c439b38db611f64f1f85ba643b1b3e53f953fd59
[silc.git] / lib / silcutil / silcthread.h
1 /*
2
3   silcmutex.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2001 - 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 /****h* silcutil/SILC Thread Interface
21  *
22  * DESCRIPTION
23  *
24  * Interface for platform independent thread implementation and thread pool
25  * system.  The interface provides routines for applications that need
26  * concurrent execution with the application's main thread.  The threads
27  * created with this interface executes concurrently with the calling thread.
28  *
29  * The thread pool system can be used to start many threads and execute code
30  * in the threads.  The thread pool manages the threads creation and
31  * destruction.
32  *
33  ***/
34
35 #ifndef SILCTHREAD_H
36 #define SILCTHREAD_H
37
38 #include "silcschedule.h"
39
40 /* Prototypes */
41
42 /****s* silcutil/SilcThreadAPI/SilcThread
43  *
44  * NAME
45  *
46  *    typedef struct SilcThreadStruct *SilcThread;
47  *
48  * DESCRIPTION
49  *
50  *    This context is the actual SILC Thread and is returned by
51  *    the silc_thread_create functions, and given as arguments to
52  *    some of the silc_thread_* functions. This context and its
53  *    resources are released automatically when the thread exits.
54  *
55  ***/
56 typedef void *SilcThread;
57
58 /****f* silcutil/SilcThreadAPI/SilcThreadStart
59  *
60  * SYNOPSIS
61  *
62  *    typedef void *(*SilcThreadStart)(void *context);
63  *
64  * DESCRIPTION
65  *
66  *    A callback function that is called when the thread is created
67  *    by the silc_thread_create function.  This returns the return value
68  *    of the thread. If another thread is waiting this thread's
69  *    destruction with silc_thread_wait the returned value is passed
70  *    to that thread. The thread is destroyed when this function
71  *    returns.
72  *
73  ***/
74 typedef void *(*SilcThreadStart)(void *context);
75
76 /****f* silcutil/SilcThreadAPI/silc_thread_create
77  *
78  * SYNOPSIS
79  *
80  *    SilcThread silc_thread_create(SilcThreadStart start_func,
81  *                                  void *context, SilcBool waitable);
82  * DESCRIPTION
83  *
84  *    Creates a new thread. The `start_func' with `context' will be
85  *    called if the thread was created. This function returns a pointer
86  *    to the thread or NULL if the thread could not be created.  All
87  *    resources of the returned pointer is freed automatically when the
88  *    thread exits.
89  *
90  *    If the `waitable' is set to TRUE then another thread can wait
91  *    this thread's destruction with silc_thread_wait. If it is set to
92  *    FALSE the thread is not waitable.
93  *
94  * NOTES
95  *
96  *    If the `waitable' is TRUE the thread's resources are not freed
97  *    when it exits until another thread has issued silc_thread_wait.
98  *    If the `waitable' is TRUE then another thread must always issue
99  *    silc_thread_wait to avoid memory leaks.
100  *
101  *    On Symbian Cleanup Stack is created and new Active Scheduler is
102  *    installed automatically for the created thread.  The thread also
103  *    shares heap with the calling thread.
104  *
105  ***/
106 SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
107                               SilcBool waitable);
108
109 /****f* silcutil/SilcThreadAPI/silc_thread_exit
110  *
111  * SYNOPSIS
112  *
113  *    void silc_thread_exit(void *exit_value);
114  *
115  * DESCRIPTION
116  *
117  *    Exits the current thread. This can be called to explicitly exit
118  *    the thread with `exit_value'. Another way to exit (destroy) the
119  *    current thread is to return from the SilcThreadStart function
120  *    with exit value. The exit value is passed to another thread if it
121  *    is waiting it with silc_thread_wait function.
122  *
123  ***/
124 void silc_thread_exit(void *exit_value);
125
126 /****f* silcutil/SilcThreadAPI/silc_thread_self
127  *
128  * SYNOPSIS
129  *
130  *    SilcThread silc_thread_self(void);
131  *
132  * DESCRIPTION
133  *
134  *    Returns a pointer to the current thread.
135  *
136  ***/
137 SilcThread silc_thread_self(void);
138
139 /****f* silcutil/SilcThreadAPI/silc_thread_wait
140  *
141  * SYNOPSIS
142  *
143  *    SilcBool silc_thread_wait(SilcThread thread, void **exit_value);
144  *
145  * DESCRIPTION
146  *
147  *    Waits until the thread indicated by `thread' finishes. This blocks
148  *    the execution of the current thread. The thread is finished if it
149  *    calls silc_thread_exit or is destroyed naturally. When the thread
150  *    exits its exit value is saved to `exit_value' and TRUE is returned.
151  *    If the `thread' is not waitable this will return immediately with
152  *    FALSE value.
153  *
154  ***/
155 SilcBool silc_thread_wait(SilcThread thread, void **exit_value);
156
157 /****f* silcutil/SilcThreadAPI/silc_thread_yield
158  *
159  * SYNOPSIS
160  *
161  *    void silc_thread_yield(void);
162  *
163  * DESCRIPTION
164  *
165  *    Yield the processor.  The calling thread will yield the processor and
166  *    give execution time for other threads, until its turn comes up again.
167  *
168  ***/
169 void silc_thread_yield(void);
170
171 /****s* silcutil/SilcThreadAPI/SilcThreadPool
172  *
173  * NAME
174  *
175  *    typedef struct SilcThreadPoolStruct *SilcThreadPool;
176  *
177  * DESCRIPTION
178  *
179  *    This context is the actual SILC Thread Pool and is returned by
180  *    the silc_thread_pool_alloc function, and given as arguments to
181  *    some of the silc_thread_pool_* functions. This context and its
182  *    resources are freed by calling silc_thread_pool_free;
183  *
184  ***/
185 typedef struct SilcThreadPoolStruct *SilcThreadPool;
186
187 /****f* silcutil/SilcThreadAPI/SilcThreadPoolFunc
188  *
189  * SYNOPSIS
190  *
191  *    typedef void (*SilcThreadPoolFunc)(SilcSchedule schedule,
192  *                                       void *context);
193  *
194  * DESCRIPTION
195  *
196  *    A callback function of this type is given as argument to the
197  *    silc_thread_pool_run.  The `schedule' is the scheduler and the
198  *    `context' is the `run_context' given as argument to
199  *    silc_thread_pool_run.
200  *
201  ***/
202 typedef void (*SilcThreadPoolFunc)(SilcSchedule schedule, void *context);
203
204 /****f* silcutil/SilcThreadAPI/silc_thread_pool_alloc
205  *
206  * SYNOPSIS
207  *
208  *    SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
209  *                                          SilcUInt32 min_threads,
210  *                                          SilcUInt32 max_threads,
211  *                                          SilcBool start_min_threads);
212  *
213  * DESCRIPTION
214  *
215  *    Allocate thread pool with at least `min_threads' and at most
216  *    `max_threads' many threads. If `start_min_threads' is TRUE this will
217  *    start `min_threads' many threads immediately.  Returns the thread
218  *    pool context or NULL on error.  If `stack' is non-NULL memory is
219  *    allocated from `stack'.  When the thread pool is freed the memory
220  *    is returned to `stack'.
221  *
222  * EXAMPLE
223  *
224  *    // Start thread pool, by default it has 0 threads.
225  *    pool = silc_thread_pool_alloc(NULL, 0, 5, FALSE);
226  *
227  *    // Function to execute in a thread
228  *    void my_func(SilcSchedule schedule, void *context)
229  *    {
230  *      MyContext mycontext = context;
231  *      ...
232  *    }
233  *
234  *    // Execute code in a thread in the pool
235  *    silc_thread_pool_run(pool, TRUE, NULL, my_func, my_context, NULL, NULL);
236  *
237  ***/
238 SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
239                                       SilcUInt32 min_threads,
240                                       SilcUInt32 max_threads,
241                                       SilcBool start_min_threads);
242
243 /****f* silcutil/SilcThreadAPI/silc_thread_pool_free
244  *
245  * SYNOPSIS
246  *
247  *    void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
248  *
249  * DESCRIPTION
250  *
251  *     Free the thread pool.  If `wait_unfinished' is TRUE this will block
252  *     and waits that all remaining active threads finish before freeing
253  *     the pool.
254  *
255  ***/
256 void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
257
258 /****f* silcutil/SilcThreadAPI/silc_thread_pool_run
259  *
260  * SYNOPSIS
261  *
262  *    SilcBool silc_thread_pool_run(SilcThreadPool tp,
263  *                                  SilcBool queueable,
264  *                                  SilcSchedule schedule,
265  *                                  SilcThreadPoolFunc run,
266  *                                  void *run_context,
267  *                                  SilcTaskCallback completion,
268  *                                  void *completion_context);
269  *
270  * DESCRIPTION
271  *
272  *    Run the `run' function with `run_context' in one of the threads in the
273  *    thread pool.  Returns FALSE if the thread pool is being freed.  If
274  *    there are no free threads left in the pool this will queue the `run'
275  *    and call it once a thread becomes free, if `queueable' is TRUE.  If
276  *    `queueable' is FALSE and there are no free threads, this returns FALSE
277  *    and `run' is not executed.
278  *
279  *    If `completion' is non-NULL it will be called to indicate completion
280  *    of the `run' function.  If `schedule' is non-NULL the `completion'
281  *    will be called through the scheduler in the main thread.  If it is
282  *    NULL the `completion' is called directly from the thread after the
283  *    `run' has returned.
284  *
285  ***/
286 SilcBool silc_thread_pool_run(SilcThreadPool tp,
287                               SilcBool queue,
288                               SilcSchedule schedule,
289                               SilcThreadPoolFunc run,
290                               void *run_context,
291                               SilcTaskCallback completion,
292                               void *completion_context);
293
294 /****f* silcutil/SilcThreadAPI/silc_thread_pool_set_max_threads
295  *
296  * SYNOPSIS
297  *
298  *    void silc_thread_pool_set_max_threads(SilcThreadPool tp,
299  *                                          SilcUInt32 max_threads);
300  *
301  * DESCRIPTION
302  *
303  *    Modify the amount of maximum threads of the pool.  This call does not
304  *    affect any currently active or running thread.
305  *
306  ***/
307 void silc_thread_pool_set_max_threads(SilcThreadPool tp,
308                                       SilcUInt32 max_threads);
309
310 /****f* silcutil/SilcThreadAPI/silc_thread_pool_get_max_threads
311  *
312  * SYNOPSIS
313  *
314  *    SilcUInt32 silc_thread_pool_get_max_threads(SilcThreadPool tp);
315  *
316  * DESCRIPTION
317  *
318  *    Returns the number of maximum threads to which the pool can grow.
319  *
320  ***/
321 SilcUInt32 silc_thread_pool_get_max_threads(SilcThreadPool tp);
322
323 /****f* silcutil/SilcThreadAPI/silc_thread_pool_num_free_threads
324  *
325  * SYNOPSIS
326  *
327  *    SilcUInt32 silc_thread_pool_num_free_threads(SilcThreadPool tp);
328  *
329  * DESCRIPTION
330  *
331  *    Returns the number of free threads in the pool currently.  Free threads
332  *    are threads that are not currently executing any code.
333  *
334  ***/
335 SilcUInt32 silc_thread_pool_num_free_threads(SilcThreadPool tp);
336
337 /****f* silcutil/SilcThreadAPI/silc_thread_pool_purge
338  *
339  * SYNOPSIS
340  *
341  *    void silc_thread_pool_purge(SilcThreadPool tp);
342  *
343  * DESCRIPTION
344  *
345  *    Stops all free and started threads.  The minumum amount of threads
346  *    specified to silc_thread_pool_alloc always remains.  Any thread that
347  *    is currently executing code is not affected by this call.
348  *
349  ***/
350 void silc_thread_pool_purge(SilcThreadPool tp);
351
352 #endif