num_max_thread. -> get_max_threads.
[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' or `completion_context' given as
199  *    argument to 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 `stack' is non-NULL all memory is
217  *    allocated from the `stack'.  If `start_min_threads' is TRUE this will
218  *    start `min_threads' many threads immediately.  Returns the thread
219  *    pool context or NULL on error.
220  *
221  * EXAMPLE
222  *
223  *    // Start thread pool, by default it has 0 threads.
224  *    pool = silc_thread_pool_alloc(NULL, 0, 5, FALSE);
225  *
226  *    // Function to execute in a thread
227  *    void my_func(SilcSchedule schedule, void *context)
228  *    {
229  *      MyContext mycontext = context;
230  *      ...
231  *    }
232  *
233  *    // Execute code in a thread in the pool
234  *    silc_thread_pool_run(pool, TRUE, NULL, my_func, my_context, NULL, NULL);
235  *
236  ***/
237 SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
238                                       SilcUInt32 min_threads,
239                                       SilcUInt32 max_threads,
240                                       SilcBool start_min_threads);
241
242 /****f* silcutil/SilcThreadAPI/silc_thread_pool_free
243  *
244  * SYNOPSIS
245  *
246  *    void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
247  *
248  * DESCRIPTION
249  *
250  *     Free the thread pool.  If `wait_unfinished' is TRUE this will block
251  *     and waits that all remaining active threads finish before freeing
252  *     the pool.
253  *
254  ***/
255 void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
256
257 /****f* silcutil/SilcThreadAPI/silc_thread_pool_run
258  *
259  * SYNOPSIS
260  *
261  *    SilcBool silc_thread_pool_run(SilcThreadPool tp,
262  *                                  SilcBool queueable,
263  *                                  SilcSchedule schedule,
264  *                                  SilcThreadPoolFunc run,
265  *                                  void *run_context,
266  *                                  SilcThreadPoolFunc completion,
267  *                                  void *completion_context);
268  *
269  * DESCRIPTION
270  *
271  *    Run the `run' function with `run_context' in one of the threads in the
272  *    thread pool.  Returns FALSE if the thread pool is being freed.  If
273  *    there are no free threads left in the pool this will queue the `run'
274  *    and call it once a thread becomes free, if `queueable' is TRUE.  If
275  *    `queueable' is FALSE and there are no free threads, this returns FALSE
276  *    and `run' is not executed.
277  *
278  *    If `completion' is non-NULL it will be called to indicate completion
279  *    of the `run' function.  If `schedule' is non-NULL the `completion'
280  *    will be called through the scheduler in the main thread.  If it is
281  *    NULL the `completion' is called directly from the thread after the
282  *    `run' has returned.
283  *
284  ***/
285 SilcBool silc_thread_pool_run(SilcThreadPool tp,
286                               SilcBool queue,
287                               SilcSchedule schedule,
288                               SilcThreadPoolFunc run,
289                               void *run_context,
290                               SilcThreadPoolFunc completion,
291                               void *completion_context);
292
293 /****f* silcutil/SilcThreadAPI/silc_thread_pool_set_max_threads
294  *
295  * SYNOPSIS
296  *
297  *    void silc_thread_pool_set_max_threads(SilcThreadPool tp,
298  *                                          SilcUInt32 max_threads);
299  *
300  * DESCRIPTION
301  *
302  *    Modify the amount of maximum threads of the pool.  This call does not
303  *    affect any currently active or running thread.
304  *
305  ***/
306 void silc_thread_pool_set_max_threads(SilcThreadPool tp,
307                                       SilcUInt32 max_threads);
308
309 /****f* silcutil/SilcThreadAPI/silc_thread_pool_get_max_threads
310  *
311  * SYNOPSIS
312  *
313  *    SilcUInt32 silc_thread_pool_get_max_threads(SilcThreadPool tp);
314  *
315  * DESCRIPTION
316  *
317  *    Returns the number of maximum threads to which the pool can grow.
318  *
319  ***/
320 SilcUInt32 silc_thread_pool_get_max_threads(SilcThreadPool tp);
321
322 /****f* silcutil/SilcThreadAPI/silc_thread_pool_num_free_threads
323  *
324  * SYNOPSIS
325  *
326  *    SilcUInt32 silc_thread_pool_num_free_threads(SilcThreadPool tp);
327  *
328  * DESCRIPTION
329  *
330  *    Returns the number of free threads in the pool currently.  Free threads
331  *    are threads that are not currently executing any code.
332  *
333  ***/
334 SilcUInt32 silc_thread_pool_num_free_threads(SilcThreadPool tp);
335
336 /****f* silcutil/SilcThreadAPI/silc_thread_pool_purge
337  *
338  * SYNOPSIS
339  *
340  *    void silc_thread_pool_purge(SilcThreadPool tp);
341  *
342  * DESCRIPTION
343  *
344  *    Stops all free and started threads.  The minumum amount of threads
345  *    specified to silc_thread_pool_alloc always remains.  Any thread that
346  *    is currently executing code is not affected by this call.
347  *
348  ***/
349 void silc_thread_pool_purge(SilcThreadPool tp);
350
351 #endif