Added SILC Thread Queue API
[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  * The interface also provides routines for accessing the Thread-local
34  * storage (Tls) on all supported platforms.
35  *
36  ***/
37
38 #ifndef SILCTHREAD_H
39 #define SILCTHREAD_H
40
41 #include "silcschedule.h"
42
43 /* Prototypes */
44
45 /****s* silcutil/SilcThreadAPI/SilcThread
46  *
47  * NAME
48  *
49  *    typedef struct SilcThreadStruct *SilcThread;
50  *
51  * DESCRIPTION
52  *
53  *    This context is the actual SILC Thread and is returned by
54  *    the silc_thread_create functions, and given as arguments to
55  *    some of the silc_thread_* functions. This context and its
56  *    resources are released automatically when the thread exits.
57  *
58  ***/
59 typedef void *SilcThread;
60
61 /****f* silcutil/SilcThreadAPI/SilcThreadStart
62  *
63  * SYNOPSIS
64  *
65  *    typedef void *(*SilcThreadStart)(void *context);
66  *
67  * DESCRIPTION
68  *
69  *    A callback function that is called when the thread is created
70  *    by the silc_thread_create function.  This returns the return value
71  *    of the thread. If another thread is waiting this thread's
72  *    destruction with silc_thread_wait the returned value is passed
73  *    to that thread. The thread is destroyed when this function
74  *    returns.
75  *
76  ***/
77 typedef void *(*SilcThreadStart)(void *context);
78
79 /****f* silcutil/SilcThreadAPI/silc_thread_create
80  *
81  * SYNOPSIS
82  *
83  *    SilcThread silc_thread_create(SilcThreadStart start_func,
84  *                                  void *context, SilcBool waitable);
85  * DESCRIPTION
86  *
87  *    Creates a new thread. The `start_func' with `context' will be
88  *    called if the thread was created. This function returns a pointer
89  *    to the thread or NULL if the thread could not be created.  All
90  *    resources of the returned pointer is freed automatically when the
91  *    thread exits.
92  *
93  *    If the `waitable' is set to TRUE then another thread can wait
94  *    this thread's destruction with silc_thread_wait. If it is set to
95  *    FALSE the thread is not waitable.
96  *
97  * NOTES
98  *
99  *    If the `waitable' is TRUE the thread's resources are not freed
100  *    when it exits until another thread has issued silc_thread_wait.
101  *    If the `waitable' is TRUE then another thread must always issue
102  *    silc_thread_wait to avoid memory leaks.
103  *
104  *    On Symbian Cleanup Stack is created and new Active Scheduler is
105  *    installed automatically for the created thread.  The thread also
106  *    shares heap with the calling thread.
107  *
108  ***/
109 SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
110                               SilcBool waitable);
111
112 /****f* silcutil/SilcThreadAPI/silc_thread_exit
113  *
114  * SYNOPSIS
115  *
116  *    void silc_thread_exit(void *exit_value);
117  *
118  * DESCRIPTION
119  *
120  *    Exits the current thread. This can be called to explicitly exit
121  *    the thread with `exit_value'. Another way to exit (destroy) the
122  *    current thread is to return from the SilcThreadStart function
123  *    with exit value. The exit value is passed to another thread if it
124  *    is waiting it with silc_thread_wait function.
125  *
126  ***/
127 void silc_thread_exit(void *exit_value);
128
129 /****f* silcutil/SilcThreadAPI/silc_thread_self
130  *
131  * SYNOPSIS
132  *
133  *    SilcThread silc_thread_self(void);
134  *
135  * DESCRIPTION
136  *
137  *    Returns a pointer to the current thread.
138  *
139  ***/
140 SilcThread silc_thread_self(void);
141
142 /****f* silcutil/SilcThreadAPI/silc_thread_wait
143  *
144  * SYNOPSIS
145  *
146  *    SilcBool silc_thread_wait(SilcThread thread, void **exit_value);
147  *
148  * DESCRIPTION
149  *
150  *    Waits until the thread indicated by `thread' finishes. This blocks
151  *    the execution of the current thread. The thread is finished if it
152  *    calls silc_thread_exit or is destroyed naturally. When the thread
153  *    exits its exit value is saved to `exit_value' and TRUE is returned.
154  *    If the `thread' is not waitable this will return immediately with
155  *    FALSE value.
156  *
157  ***/
158 SilcBool silc_thread_wait(SilcThread thread, void **exit_value);
159
160 /****f* silcutil/SilcThreadAPI/silc_thread_yield
161  *
162  * SYNOPSIS
163  *
164  *    void silc_thread_yield(void);
165  *
166  * DESCRIPTION
167  *
168  *    Yield the processor.  The calling thread will yield the processor and
169  *    give execution time for other threads, until its turn comes up again.
170  *
171  ***/
172 void silc_thread_yield(void);
173
174 /****s* silcutil/SilcThreadAPI/SilcThreadPool
175  *
176  * NAME
177  *
178  *    typedef struct SilcThreadPoolStruct *SilcThreadPool;
179  *
180  * DESCRIPTION
181  *
182  *    This context is the actual SILC Thread Pool and is returned by
183  *    the silc_thread_pool_alloc function, and given as arguments to
184  *    some of the silc_thread_pool_* functions. This context and its
185  *    resources are freed by calling silc_thread_pool_free;
186  *
187  ***/
188 typedef struct SilcThreadPoolStruct *SilcThreadPool;
189
190 /****f* silcutil/SilcThreadAPI/SilcThreadPoolFunc
191  *
192  * SYNOPSIS
193  *
194  *    typedef void (*SilcThreadPoolFunc)(SilcSchedule schedule,
195  *                                       void *context);
196  *
197  * DESCRIPTION
198  *
199  *    A callback function of this type is given as argument to the
200  *    silc_thread_pool_run.  The `schedule' is the scheduler and the
201  *    `context' is the `run_context' given as argument to
202  *    silc_thread_pool_run.
203  *
204  ***/
205 typedef void (*SilcThreadPoolFunc)(SilcSchedule schedule, void *context);
206
207 /****f* silcutil/SilcThreadAPI/silc_thread_pool_alloc
208  *
209  * SYNOPSIS
210  *
211  *    SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
212  *                                          SilcUInt32 min_threads,
213  *                                          SilcUInt32 max_threads,
214  *                                          SilcBool start_min_threads);
215  *
216  * DESCRIPTION
217  *
218  *    Allocate thread pool with at least `min_threads' and at most
219  *    `max_threads' many threads. If `start_min_threads' is TRUE this will
220  *    start `min_threads' many threads immediately.  Returns the thread
221  *    pool context or NULL on error.  If `stack' is non-NULL memory is
222  *    allocated from `stack'.  When the thread pool is freed the memory
223  *    is returned to `stack'.
224  *
225  * EXAMPLE
226  *
227  *    // Start thread pool, by default it has 0 threads.
228  *    pool = silc_thread_pool_alloc(NULL, 0, 5, FALSE);
229  *
230  *    // Function to execute in a thread
231  *    void my_func(SilcSchedule schedule, void *context)
232  *    {
233  *      MyContext mycontext = context;
234  *      ...
235  *    }
236  *
237  *    // Execute code in a thread in the pool
238  *    silc_thread_pool_run(pool, TRUE, NULL, my_func, my_context, NULL, NULL);
239  *
240  ***/
241 SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
242                                       SilcUInt32 min_threads,
243                                       SilcUInt32 max_threads,
244                                       SilcBool start_min_threads);
245
246 /****f* silcutil/SilcThreadAPI/silc_thread_pool_free
247  *
248  * SYNOPSIS
249  *
250  *    void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
251  *
252  * DESCRIPTION
253  *
254  *     Free the thread pool.  If `wait_unfinished' is TRUE this will block
255  *     and waits that all remaining active threads finish before freeing
256  *     the pool.
257  *
258  ***/
259 void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
260
261 /****f* silcutil/SilcThreadAPI/silc_thread_pool_run
262  *
263  * SYNOPSIS
264  *
265  *    SilcBool silc_thread_pool_run(SilcThreadPool tp,
266  *                                  SilcBool queueable,
267  *                                  SilcSchedule schedule,
268  *                                  SilcThreadPoolFunc run,
269  *                                  void *run_context,
270  *                                  SilcTaskCallback completion,
271  *                                  void *completion_context);
272  *
273  * DESCRIPTION
274  *
275  *    Run the `run' function with `run_context' in one of the threads in the
276  *    thread pool.  Returns FALSE if the thread pool is being freed.  If
277  *    there are no free threads left in the pool this will queue the `run'
278  *    and call it once a thread becomes free, if `queueable' is TRUE.  If
279  *    `queueable' is FALSE and there are no free threads, this returns FALSE
280  *    and `run' is not executed.
281  *
282  *    If `completion' is non-NULL it will be called to indicate completion
283  *    of the `run' function.  If `schedule' is non-NULL the `completion'
284  *    will be called through the scheduler in the main thread.  If it is
285  *    NULL the `completion' is called directly from the thread after the
286  *    `run' has returned.
287  *
288  ***/
289 SilcBool silc_thread_pool_run(SilcThreadPool tp,
290                               SilcBool queue,
291                               SilcSchedule schedule,
292                               SilcThreadPoolFunc run,
293                               void *run_context,
294                               SilcTaskCallback completion,
295                               void *completion_context);
296
297 /****f* silcutil/SilcThreadAPI/silc_thread_pool_set_max_threads
298  *
299  * SYNOPSIS
300  *
301  *    void silc_thread_pool_set_max_threads(SilcThreadPool tp,
302  *                                          SilcUInt32 max_threads);
303  *
304  * DESCRIPTION
305  *
306  *    Modify the amount of maximum threads of the pool.  This call does not
307  *    affect any currently active or running thread.
308  *
309  ***/
310 void silc_thread_pool_set_max_threads(SilcThreadPool tp,
311                                       SilcUInt32 max_threads);
312
313 /****f* silcutil/SilcThreadAPI/silc_thread_pool_get_max_threads
314  *
315  * SYNOPSIS
316  *
317  *    SilcUInt32 silc_thread_pool_get_max_threads(SilcThreadPool tp);
318  *
319  * DESCRIPTION
320  *
321  *    Returns the number of maximum threads to which the pool can grow.
322  *
323  ***/
324 SilcUInt32 silc_thread_pool_get_max_threads(SilcThreadPool tp);
325
326 /****f* silcutil/SilcThreadAPI/silc_thread_pool_num_free_threads
327  *
328  * SYNOPSIS
329  *
330  *    SilcUInt32 silc_thread_pool_num_free_threads(SilcThreadPool tp);
331  *
332  * DESCRIPTION
333  *
334  *    Returns the number of free threads in the pool currently.  Free threads
335  *    are threads that are not currently executing any code.
336  *
337  ***/
338 SilcUInt32 silc_thread_pool_num_free_threads(SilcThreadPool tp);
339
340 /****f* silcutil/SilcThreadAPI/silc_thread_pool_purge
341  *
342  * SYNOPSIS
343  *
344  *    void silc_thread_pool_purge(SilcThreadPool tp);
345  *
346  * DESCRIPTION
347  *
348  *    Stops all free and started threads.  The minumum amount of threads
349  *    specified to silc_thread_pool_alloc always remains.  Any thread that
350  *    is currently executing code is not affected by this call.
351  *
352  ***/
353 void silc_thread_pool_purge(SilcThreadPool tp);
354
355 /****f* silcutil/SilcThreadAPI/silc_thread_tls_set
356  *
357  * SYNOPSIS
358  *
359  *    void silc_thread_tls_set(void *context);
360  *
361  * DESCRIPTION
362  *
363  *    Sets `context' into the Thread-local storage.  Any previously set
364  *    value will be replaced.  This function may be called for the main
365  *    thread also.  This function may be called also if the program does
366  *    not support threads.
367  *
368  *    To retrieve the context from the Tls, call silc_thread_tls_get.
369  *
370  ***/
371 void silc_thread_tls_set(void *context);
372
373 /****f* silcutil/SilcThreadAPI/silc_thread_tls_get
374  *
375  * SYNOPSIS
376  *
377  *    void *silc_thread_tls_get(void);
378  *
379  * DESCRIPTION
380  *
381  *    Returns context from the Thread-local storage.  If context has no been
382  *    set for the current thread NULL will be returned.
383  *
384  ***/
385 void *silc_thread_tls_get(void);
386
387 #include "silcthread_i.h"
388
389 #endif