5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2001 - 2007 Pekka Riikonen
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.
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.
20 /****h* silcutil/SILC Thread Interface
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.
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
33 * The interface also provides routines for accessing the Thread-local
34 * storage (Tls) on all supported platforms.
41 #include "silcschedule.h"
45 /****s* silcutil/SilcThreadAPI/SilcThread
49 * typedef struct SilcThreadStruct *SilcThread;
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.
59 typedef void *SilcThread;
61 /****f* silcutil/SilcThreadAPI/SilcThreadStart
65 * typedef void *(*SilcThreadStart)(void *context);
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
77 typedef void *(*SilcThreadStart)(void *context);
79 /****f* silcutil/SilcThreadAPI/silc_thread_create
83 * SilcThread silc_thread_create(SilcThreadStart start_func,
84 * void *context, SilcBool waitable);
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
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.
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.
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.
109 SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
112 /****f* silcutil/SilcThreadAPI/silc_thread_exit
116 * void silc_thread_exit(void *exit_value);
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.
127 void silc_thread_exit(void *exit_value);
129 /****f* silcutil/SilcThreadAPI/silc_thread_self
133 * SilcThread silc_thread_self(void);
137 * Returns a pointer to the current thread.
140 SilcThread silc_thread_self(void);
142 /****f* silcutil/SilcThreadAPI/silc_thread_wait
146 * SilcBool silc_thread_wait(SilcThread thread, void **exit_value);
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
158 SilcBool silc_thread_wait(SilcThread thread, void **exit_value);
160 /****f* silcutil/SilcThreadAPI/silc_thread_yield
164 * void silc_thread_yield(void);
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.
172 void silc_thread_yield(void);
174 /****s* silcutil/SilcThreadAPI/SilcThreadPool
178 * typedef struct SilcThreadPoolStruct *SilcThreadPool;
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;
188 typedef struct SilcThreadPoolStruct *SilcThreadPool;
190 /****f* silcutil/SilcThreadAPI/SilcThreadPoolFunc
194 * typedef void (*SilcThreadPoolFunc)(SilcSchedule schedule,
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.
205 typedef void (*SilcThreadPoolFunc)(SilcSchedule schedule, void *context);
207 /****f* silcutil/SilcThreadAPI/silc_thread_pool_alloc
211 * SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
212 * SilcUInt32 min_threads,
213 * SilcUInt32 max_threads,
214 * SilcBool start_min_threads);
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'.
227 * // Start thread pool, by default it has 0 threads.
228 * pool = silc_thread_pool_alloc(NULL, 0, 5, FALSE);
230 * // Function to execute in a thread
231 * void my_func(SilcSchedule schedule, void *context)
233 * MyContext mycontext = context;
237 * // Execute code in a thread in the pool
238 * silc_thread_pool_run(pool, TRUE, NULL, my_func, my_context, NULL, NULL);
241 SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
242 SilcUInt32 min_threads,
243 SilcUInt32 max_threads,
244 SilcBool start_min_threads);
246 /****f* silcutil/SilcThreadAPI/silc_thread_pool_free
250 * void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
254 * Free the thread pool. If `wait_unfinished' is TRUE this will block
255 * and waits that all remaining active threads finish before freeing
259 void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
261 /****f* silcutil/SilcThreadAPI/silc_thread_pool_run
265 * SilcBool silc_thread_pool_run(SilcThreadPool tp,
266 * SilcBool queueable,
267 * SilcSchedule schedule,
268 * SilcThreadPoolFunc run,
270 * SilcTaskCallback completion,
271 * void *completion_context);
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.
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.
289 SilcBool silc_thread_pool_run(SilcThreadPool tp,
291 SilcSchedule schedule,
292 SilcThreadPoolFunc run,
294 SilcTaskCallback completion,
295 void *completion_context);
297 /****f* silcutil/SilcThreadAPI/silc_thread_pool_set_max_threads
301 * void silc_thread_pool_set_max_threads(SilcThreadPool tp,
302 * SilcUInt32 max_threads);
306 * Modify the amount of maximum threads of the pool. This call does not
307 * affect any currently active or running thread.
310 void silc_thread_pool_set_max_threads(SilcThreadPool tp,
311 SilcUInt32 max_threads);
313 /****f* silcutil/SilcThreadAPI/silc_thread_pool_get_max_threads
317 * SilcUInt32 silc_thread_pool_get_max_threads(SilcThreadPool tp);
321 * Returns the number of maximum threads to which the pool can grow.
324 SilcUInt32 silc_thread_pool_get_max_threads(SilcThreadPool tp);
326 /****f* silcutil/SilcThreadAPI/silc_thread_pool_num_free_threads
330 * SilcUInt32 silc_thread_pool_num_free_threads(SilcThreadPool tp);
334 * Returns the number of free threads in the pool currently. Free threads
335 * are threads that are not currently executing any code.
338 SilcUInt32 silc_thread_pool_num_free_threads(SilcThreadPool tp);
340 /****f* silcutil/SilcThreadAPI/silc_thread_pool_purge
344 * void silc_thread_pool_purge(SilcThreadPool tp);
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.
353 void silc_thread_pool_purge(SilcThreadPool tp);
355 /****f* silcutil/SilcThreadAPI/silc_thread_tls_set
359 * void silc_thread_tls_set(void *context);
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.
368 * To retrieve the context from the Tls, call silc_thread_tls_get.
371 void silc_thread_tls_set(void *context);
373 /****f* silcutil/SilcThreadAPI/silc_thread_tls_get
377 * void *silc_thread_tls_get(void);
381 * Returns context from the Thread-local storage. If context has no been
382 * set for the current thread NULL will be returned.
385 void *silc_thread_tls_get(void);
387 #include "silcthread_i.h"