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
38 #include "silcschedule.h"
42 /****s* silcutil/SilcThreadAPI/SilcThread
46 * typedef struct SilcThreadStruct *SilcThread;
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.
56 typedef void *SilcThread;
58 /****f* silcutil/SilcThreadAPI/SilcThreadStart
62 * typedef void *(*SilcThreadStart)(void *context);
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
74 typedef void *(*SilcThreadStart)(void *context);
76 /****f* silcutil/SilcThreadAPI/silc_thread_create
80 * SilcThread silc_thread_create(SilcThreadStart start_func,
81 * void *context, SilcBool waitable);
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
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.
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.
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.
106 SilcThread silc_thread_create(SilcThreadStart start_func, void *context,
109 /****f* silcutil/SilcThreadAPI/silc_thread_exit
113 * void silc_thread_exit(void *exit_value);
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.
124 void silc_thread_exit(void *exit_value);
126 /****f* silcutil/SilcThreadAPI/silc_thread_self
130 * SilcThread silc_thread_self(void);
134 * Returns a pointer to the current thread.
137 SilcThread silc_thread_self(void);
139 /****f* silcutil/SilcThreadAPI/silc_thread_wait
143 * SilcBool silc_thread_wait(SilcThread thread, void **exit_value);
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
155 SilcBool silc_thread_wait(SilcThread thread, void **exit_value);
157 /****f* silcutil/SilcThreadAPI/silc_thread_yield
161 * void silc_thread_yield(void);
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.
169 void silc_thread_yield(void);
171 /****s* silcutil/SilcThreadAPI/SilcThreadPool
175 * typedef struct SilcThreadPoolStruct *SilcThreadPool;
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;
185 typedef struct SilcThreadPoolStruct *SilcThreadPool;
187 /****f* silcutil/SilcThreadAPI/SilcThreadPoolFunc
191 * typedef void (*SilcThreadPoolFunc)(SilcSchedule schedule,
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.
202 typedef void (*SilcThreadPoolFunc)(SilcSchedule schedule, void *context);
204 /****f* silcutil/SilcThreadAPI/silc_thread_pool_alloc
208 * SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
209 * SilcUInt32 min_threads,
210 * SilcUInt32 max_threads,
211 * SilcBool start_min_threads);
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'.
224 * // Start thread pool, by default it has 0 threads.
225 * pool = silc_thread_pool_alloc(NULL, 0, 5, FALSE);
227 * // Function to execute in a thread
228 * void my_func(SilcSchedule schedule, void *context)
230 * MyContext mycontext = context;
234 * // Execute code in a thread in the pool
235 * silc_thread_pool_run(pool, TRUE, NULL, my_func, my_context, NULL, NULL);
238 SilcThreadPool silc_thread_pool_alloc(SilcStack stack,
239 SilcUInt32 min_threads,
240 SilcUInt32 max_threads,
241 SilcBool start_min_threads);
243 /****f* silcutil/SilcThreadAPI/silc_thread_pool_free
247 * void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
251 * Free the thread pool. If `wait_unfinished' is TRUE this will block
252 * and waits that all remaining active threads finish before freeing
256 void silc_thread_pool_free(SilcThreadPool tp, SilcBool wait_unfinished);
258 /****f* silcutil/SilcThreadAPI/silc_thread_pool_run
262 * SilcBool silc_thread_pool_run(SilcThreadPool tp,
263 * SilcBool queueable,
264 * SilcSchedule schedule,
265 * SilcThreadPoolFunc run,
267 * SilcTaskCallback completion,
268 * void *completion_context);
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.
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.
286 SilcBool silc_thread_pool_run(SilcThreadPool tp,
288 SilcSchedule schedule,
289 SilcThreadPoolFunc run,
291 SilcTaskCallback completion,
292 void *completion_context);
294 /****f* silcutil/SilcThreadAPI/silc_thread_pool_set_max_threads
298 * void silc_thread_pool_set_max_threads(SilcThreadPool tp,
299 * SilcUInt32 max_threads);
303 * Modify the amount of maximum threads of the pool. This call does not
304 * affect any currently active or running thread.
307 void silc_thread_pool_set_max_threads(SilcThreadPool tp,
308 SilcUInt32 max_threads);
310 /****f* silcutil/SilcThreadAPI/silc_thread_pool_get_max_threads
314 * SilcUInt32 silc_thread_pool_get_max_threads(SilcThreadPool tp);
318 * Returns the number of maximum threads to which the pool can grow.
321 SilcUInt32 silc_thread_pool_get_max_threads(SilcThreadPool tp);
323 /****f* silcutil/SilcThreadAPI/silc_thread_pool_num_free_threads
327 * SilcUInt32 silc_thread_pool_num_free_threads(SilcThreadPool tp);
331 * Returns the number of free threads in the pool currently. Free threads
332 * are threads that are not currently executing any code.
335 SilcUInt32 silc_thread_pool_num_free_threads(SilcThreadPool tp);
337 /****f* silcutil/SilcThreadAPI/silc_thread_pool_purge
341 * void silc_thread_pool_purge(SilcThreadPool tp);
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.
350 void silc_thread_pool_purge(SilcThreadPool tp);