KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
threads.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 threads.h
4 Copyright (C) 2014 Lawrence Sebald
5*/
6
7/** \file threads.h
8 \brief C11 Threading API.
9 \ingroup threading_c11
10
11 This file contains the definitions needed for using C11 threads. The C11
12 standard defines a number of threading-related primitives, which we wrap
13 neatly around KOS' built-in threading support here.
14
15 If you compile your code with a strict standard set (you use a -std= flag
16 with GCC that doesn't start with gnu), you must use -std=c11 to use this
17 functionality. If you don't pass a -std= flag to GCC, then you're probably
18 fine.
19
20 \author Lawrence Sebald
21*/
22
23#ifndef __THREADS_H
24#define __THREADS_H
25
26#if !defined(__STRICT_ANSI__) || (__STDC_VERSION__ >= 201112L)
27
28#include <sys/cdefs.h>
29#include <time.h>
30
31/* Bring in all the threading-related stuff we'll need. */
32#include <kos/thread.h>
33#include <kos/once.h>
34#include <kos/mutex.h>
35#include <kos/cond.h>
36#include <kos/tls.h>
37
38__BEGIN_DECLS
39
40/** \defgroup threading_c11 C11
41 \brief C11 Threading APIs
42 \ingroup threading
43
44 @{
45*/
46
47/** \name Return values
48 \brief C11 Thread function return values
49
50 Most of the C11 thread-related functions that return a result code return
51 one of these.
52
53 @{
54*/
55#define thrd_success 0 /**< \brief Success */
56#define thrd_error -1 /**< \brief Uncategorized error */
57#define thrd_timedout -2 /**< \brief Time out error */
58#define thrd_busy -3 /**< \brief Resource busy */
59#define thrd_nomem -4 /**< \brief Out of memory */
60/** @} */
61
62/** \brief Object type backing call_once.
63
64 This object type holds a flag that is used by the call_once function to call
65 a function one time. It should always be initialized with the ONCE_FLAG_INIT
66 macro.
67
68 \headerfile threads.h
69*/
71
72/** \brief Macro to initialize a once_flag object. */
73#define ONCE_FLAG_INIT KTHREAD_ONCE_INIT
74
75/** \brief Call a function one time, no matter how many threads try.
76
77 This function uses the once_flag object passed in to ensure that a given
78 function is called exactly once, regardless of how many threads attempt to
79 call through the once_flag.
80
81 \param flag The once_flag to run against.
82 \param func The function to call.
83*/
84extern void call_once(once_flag *flag, void (*func)(void));
85
86/** \brief C11 mutual exclusion lock type.
87
88 This type holds an identifier for a mutual exclusion (mutex) lock to be used
89 with C11 threading support.
90
91 \headerfile threads.h
92*/
93typedef mutex_t mtx_t;
94
95/** \name Mutex types
96 \brief C11 mutual exclusion lock types
97
98 These are the possible types of mutex locks that C11 allows for. Note that
99 mtx_plain or mtx_recursive can be ORed with mtx_timed as well.
100
101 @{
102*/
103#define mtx_plain (1 << 0) /**< \brief Plain mutex */
104#define mtx_recursive (1 << 1) /**< \brief Recursive mutex */
105#define mtx_timed (1 << 2) /**< \brief Mutex supporting the
106 mtx_timedlock function. */
107/** @} */
108
109/** \brief Deinitialize a mutex lock.
110
111 This function deinitializes a mutex lock that was previously created with
112 mtx_init().
113
114 \param mtx The mutex to deinitialize.
115*/
116extern void mtx_destroy(mtx_t *mtx);
117
118/** \brief Initialize a mutex lock.
119
120 This function initializes a mutex lock of the given type for later use to
121 protect critical sections of code.
122
123 \param mtx The mutex to initialize.
124 \param type The type of mutex desired
125 \retval thrd_success On success.
126 \retval thrd_error If the request could not be honored.
127*/
128extern int mtx_init(mtx_t *mtx, int type);
129
130/** \brief Lock a mutex lock.
131
132 This function locks the specified mutex, preventing any other threads from
133 obtaining the same lock.
134
135 This function will block until the lock can be obtained.
136
137 \param mtx The mutex to lock.
138 \retval thrd_success On success.
139 \retval thrd_error If the request could not be honored.
140
141 \note Calling this function in an interrupt will result in an error being
142 returned.
143*/
144extern int mtx_lock(mtx_t *mtx);
145
146/** \brief Lock a mutex lock with a timeout.
147
148 This function locks the specified mutex, assuming that the lock can be
149 obtained in the time period specified.
150
151 This function will block until the lock can be obtained or the timeout
152 expires.
153
154 \param mtx The mutex to lock.
155 \param ts The amount of time to wait before timing out.
156 \retval thrd_success On success.
157 \retval thrd_error If the request could not be honored for some other
158 reason than a timeout.
159 \retval thrd_timedout If the timeout specified passes without obtaining
160 the lock.
161
162 \note Calling this function in an interrupt will result in an error being
163 returned.
164 \note Although timeouts are specified in seconds and nanoseconds, the
165 timeout will be rounded up to the nearest millisecond.
166*/
168 const struct timespec *__RESTRICT ts);
169
170/** \brief Attempt to acquire a mutex lock.
171
172 This function attempts to acquire the specified mutex and will not block if
173 it cannot be obtained.
174
175 \param mtx The mutex to lock.
176 \retval thrd_success On success.
177 \retval thrd_busy If the lock is already locked by a thread.
178 \retval thrd_error If the request could not be honored for some other
179 reason.
180
181 \note This function is safe to call in an interrupt.
182 \note Always check the return value to ensure that the lock was obtained.
183*/
184extern int mtx_trylock(mtx_t *mtx);
185
186/** \brief Unlock a previously acquired lock.
187
188 This function releases the specified mutex lock, allowing other threads to
189 acquire it.
190
191 \param mtx The mutex to unlock.
192 \retval thrd_success On success.
193 \retval thrd_error If the request cannot be honored.
194
195 \note Unlocking a mutex that was not previously locked by the calling
196 thread results in undefined behavior.
197*/
198extern int mtx_unlock(mtx_t *mtx);
199
200/** \brief C11 condition variable type.
201
202 This type holds an identifier for a condition variable object that is to be
203 used with C11 threading support.
204
205 \headerfile threads.h
206*/
208
209/** \brief Broadcast to all threads locked on a condition variable.
210
211 This function wakes all threads that are blocked on the condition variable
212 cond at the time of the call. If no threads are currently blocked on cond,
213 this call does nothing.
214
215 \param cond The condition variable to signal.
216 \retval thrd_success On success.
217 \retval thrd_error If the request cannot be honored.
218*/
219extern int cnd_broadcast(cnd_t *cond);
220
221/** \brief Deinitialize a condition variable.
222
223 This function cleans up all resources associated with the given condition
224 variable. You must ensure that no threads are currently blocked on the
225 condition variable before calling this function.
226
227 \param cond The condition variable to deinitialize.
228
229 \note Deinitializing a condition variable that is currently being waited
230 on by threads results in undefined behavior.
231*/
232extern void cnd_destroy(cnd_t *cond);
233
234/** \brief Initialize a condition variable.
235
236 This function initializes the specified condition variable for use.
237
238 \param cond The condition variable to signal.
239 \retval thrd_success On success.
240 \retval thrd_nomem If memory cannot be allocated for the new condition
241 variable.
242 \retval thrd_error If the request cannot be honored for some other
243 reason.
244*/
245extern int cnd_init(cnd_t *cond);
246
247/** \brief Signal one thread locked on a condition variable.
248
249 This function wakes one thread that is blocked on the condition variable
250 cond at the time of the call. If no threads are currently blocked on cond,
251 this call does nothing.
252
253 \param cond The condition variable to signal.
254 \retval thrd_success On success.
255 \retval thrd_error If the request cannot be honored.
256*/
257extern int cnd_signal(cnd_t *cond);
258
259/** \brief Wait on a condition variable (with a timeout).
260
261 This function puts the calling thread to sleep until either the condition
262 variable is signaled or the timeout specified expires, whichever happens
263 first. The specified mutex must be held by the calling thread when calling
264 this function and will be held by the thread again when it is unblocked.
265
266 \param cond The condition variable to wait on.
267 \param mtx The mutex associated with the condition variable.
268 \param ts The time to wait before timing out.
269 \retval thrd_success On success.
270 \retval thrd_timedout If the timeout was reached before the condition
271 variable was signaled.
272 \retval thrd_error If the request cannot be honored for some other
273 reason.
274
275 \note Calling this function in an interrupt will result in an error being
276 returned.
277 \note Although timeouts are specified in seconds and nanoseconds, the
278 timeout will be rounded up to the nearest millisecond.
279*/
281 const struct timespec *__RESTRICT ts);
282
283/** \brief Wait on a condition variable.
284
285 This function puts the calling thread to sleep until the condition variable
286 is signaled. The specified mutex must be held by the calling thread when
287 calling this function and will be held by the thread again when it is
288 unblocked.
289
290 \param cond The condition variable to wait on.
291 \param mtx The mutex associated with the condition variable.
292 \retval thrd_success On success.
293 \retval thrd_error If the request cannot be honored.
294
295 \note Calling this function in an interrupt will result in an error being
296 returned.
297*/
298extern int cnd_wait(cnd_t *cond, mtx_t *mtx);
299
300/** \brief C11 thread identifier type.
301
302 This type holds an identifier for a C11 thread.
303
304 \headerfile threads.h
305*/
307
308/** \brief C11 thread start function type.
309
310 This is a function pointer type representing a function used to begin a
311 thread. The thread exits when the function returns or calls thrd_exit().
312
313 \headerfile threads.h
314*/
315typedef int (*thrd_start_t)(void *);
316
317/** \brief Create and start a new thread.
318
319 This function creates a new thread, calling the function specified. The
320 thread is immediately added to the runnable queue of the scheduler and can
321 start at any moment after that. The thread ends when either the function
322 specified returns or when the thread calls thrd_exit().
323
324 \param thr Storage for the thread identifier.
325 \param func The function to call in the new thread.
326 \param arg Argument to pass to the function called.
327 \retval thrd_success On success.
328 \retval thrd_nomem If memory cannot be allocated to satisfy the
329 request.
330 \retval thrd_error If the request cannot be honored for some other
331 reason.
332
333 \note All threads created are joinable threads by default. That means that
334 in order to free all resources at thread termination, the thread
335 must be joined with the thrd_join() function or detached at some
336 point with thrd_detach().
337*/
338extern int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
339
340/** \brief Return the identifier of the currently running thread.
341
342 \return The current thread's ID.
343*/
344extern thrd_t thrd_current(void);
345
346/** \brief Detach a running thread.
347
348 This function detaches a thread, which informs the kernel that any resources
349 associated with the thread should be freed immediately when it terminates.
350
351 \param thr The thread to detach.
352 \retval thrd_success On success.
353 \retval thrd_error If the request cannot be honored.
354
355 \note Detaching an already detached thread has no effect.
356 \note Detaching a thread that has been joined with another thread results
357 in undefined behavior.
358*/
359extern int thrd_detach(thrd_t thr);
360
361/** \brief Compare two threads for equality.
362
363 This function checks the two two thread identifiers passed in to see if they
364 refer to the same thread.
365
366 \param thr0 The first thread to compare.
367 \param thr1 The second thread to compare.
368 \return 0 if the threads are not equal, nonzero if the
369 threads are equal.
370*/
371extern int thrd_equal(thrd_t thr0, thrd_t thr1);
372
373/** \brief Terminate the current thread immediately.
374
375 This function terminates the calling thread immediately, setting the return
376 value of the thread to the value specified.
377
378 \param res The return value of the thread.
379 \note This function will not return.
380*/
381_Noreturn extern void thrd_exit(int res);
382
383/** \brief Join a running thread.
384
385 This function joins the current thread with the specified thread, blocking
386 until that thread has terminated.
387
388 \param thr The thread to join with.
389 \param res Pointer to storage for the result code of the other
390 thread. Set to NULL if you don't care about the
391 result value.
392 \retval thrd_success On success.
393 \retval thrd_error If the request cannot be honored.
394
395 \note Joining with a previously detached thread results in undefined
396 behavior.
397 \note Joining with a thread that has already been joined to another thread
398 results in undefined behavior.
399 \note Calling this function in an interrupt will result in an error being
400 returned.
401*/
402extern int thrd_join(thrd_t thr, int *res);
403
404/** \brief Put the currently running thread to sleep.
405
406 This function puts the currently running thread to sleep for the specified
407 duration of time, returning any left over time (if interrupted by a signal,
408 for instance) in the second parameter.
409
410 \param duration The amount of time to sleep.
411 \param remaining Any remaining time from the duration that the thread
412 did not sleep for.
413 \return 0 if the requested time elapsed, a negative value
414 otherwise.
415
416 \note Although the duration is expressed in seconds and nanoseconds, all
417 sleeping is done in millisecond increments. The value specified will
418 be rounded up if it is not an even number of milliseconds.
419 \note KOS does not support signals, so remaining will only ever have a
420 value after the function if there is some sort of error.
421 \note Calling this function in an interrupt will result in an error being
422 returned.
423*/
424extern int thrd_sleep(const struct timespec *duration,
425 struct timespec *remaining);
426
427/** \brief Yield the current thread's timeslice.
428
429 This function immediately pauses the current thread's execution and switches
430 to another thread in the ready queue (if there are any threads ready to
431 execute).
432
433 \note Calling this function in an interrupt will not have any effect.
434*/
435extern void thrd_yield(void);
436
437/** \brief Maximum number of iterations over TSS destructors.
438
439 This macro defines the maximum number of iterations that will be performed
440 over the destructors for thread-specific storage objects when a thread
441 terminates.
442*/
443#define TSS_DTOR_ITERATIONS 1
444
445/** \brief C11 thread-specific storage type.
446
447 This type holds a thread-specific storage identifier, which allows a value
448 to be associated with it for each and every thread running.
449
450 \headerfile threads.h
451*/
453
454/** \brief C11 thread-specific storage destructor type.
455
456 This is a function pointer type which describes a destructor for a
457 thread-specific storage object.
458
459 \headerfile threads.h
460*/
461typedef void (*tss_dtor_t)(void *);
462
463/** \brief Create a thread-specific storage pointer.
464
465 This function creates a thread-specific storage pointer and associates the
466 destructor function supplied with it. After creating the pointer, each
467 thread may associate a piece of data with the key.
468
469 \param key The key to initialize.
470 \param dtor The destructor to associate with the key.
471 \retval thrd_success On success.
472 \retval thrd_error On failure.
473*/
474extern int tss_create(tss_t *key, tss_dtor_t dtor);
475
476/** \brief Free resources associated with a thread-specific storage key.
477
478 This function releases any resources used by the thread-specific storage
479 key specified. Note that this DOES NOT call any destructors.
480
481 \param key The key to deinitialize.
482*/
483extern void tss_delete(tss_t key);
484
485/** \brief Retrieve the value associated with a thread-specific storage key.
486
487 This function retrieves the value associated with the specified
488 thread-specific storage key and returns it to the caller. If no value has
489 been set in the current thread, NULL is returned.
490
491 \param key The key to look up the value associated with.
492 \return The value associated with the key.
493*/
494extern void *tss_get(tss_t key);
495
496/** \brief Set the value associated with a thread-specific storage key.
497
498 This function sets the value to be associated with the specified
499 thread-specific storage key, overwriting any previous keys. Note that this
500 DOES NOT call any destructors.
501
502 \param key The key to set the value for.
503 \param val The value to set.
504 \retval thrd_success On success.
505 \retval thrd_error If the request cannot be honored.
506*/
507extern int tss_set(tss_t key, void *val);
508
509/** @} */
510
511__END_DECLS
512
513#endif /* !defined(__STRICT_ANSI__) || (__STDC_VERSION__ >= 201112L) */
514
515#endif /* !__THREADS_H */
Condition variables.
#define __RESTRICT
Definition cdefs.h:176
kthread_once_t once_flag
Object type backing call_once.
Definition threads.h:70
condvar_t cnd_t
C11 condition variable type.
Definition threads.h:207
int cnd_init(cnd_t *cond)
Initialize a condition variable.
int(* thrd_start_t)(void *)
C11 thread start function type.
Definition threads.h:315
int thrd_equal(thrd_t thr0, thrd_t thr1)
Compare two threads for equality.
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
Create and start a new thread.
int tss_create(tss_t *key, tss_dtor_t dtor)
Create a thread-specific storage pointer.
_Noreturn void thrd_exit(int res)
Terminate the current thread immediately.
mutex_t mtx_t
C11 mutual exclusion lock type.
Definition threads.h:93
void * tss_get(tss_t key)
Retrieve the value associated with a thread-specific storage key.
int mtx_timedlock(mtx_t *__RESTRICT mtx, const struct timespec *__RESTRICT ts)
Lock a mutex lock with a timeout.
int tss_set(tss_t key, void *val)
Set the value associated with a thread-specific storage key.
int cnd_broadcast(cnd_t *cond)
Broadcast to all threads locked on a condition variable.
int thrd_sleep(const struct timespec *duration, struct timespec *remaining)
Put the currently running thread to sleep.
int mtx_init(mtx_t *mtx, int type)
Initialize a mutex lock.
int mtx_lock(mtx_t *mtx)
Lock a mutex lock.
kthread_t * thrd_t
C11 thread identifier type.
Definition threads.h:306
int thrd_join(thrd_t thr, int *res)
Join a running thread.
void cnd_destroy(cnd_t *cond)
Deinitialize a condition variable.
kthread_key_t tss_t
C11 thread-specific storage type.
Definition threads.h:452
thrd_t thrd_current(void)
Return the identifier of the currently running thread.
void call_once(once_flag *flag, void(*func)(void))
Call a function one time, no matter how many threads try.
int cnd_wait(cnd_t *cond, mtx_t *mtx)
Wait on a condition variable.
int mtx_trylock(mtx_t *mtx)
Attempt to acquire a mutex lock.
void thrd_yield(void)
Yield the current thread's timeslice.
int thrd_detach(thrd_t thr)
Detach a running thread.
int cnd_timedwait(cnd_t *__RESTRICT cond, mtx_t *__RESTRICT mtx, const struct timespec *__RESTRICT ts)
Wait on a condition variable (with a timeout).
int mtx_unlock(mtx_t *mtx)
Unlock a previously acquired lock.
void mtx_destroy(mtx_t *mtx)
Deinitialize a mutex lock.
void tss_delete(tss_t key)
Free resources associated with a thread-specific storage key.
int cnd_signal(cnd_t *cond)
Signal one thread locked on a condition variable.
void(* tss_dtor_t)(void *)
C11 thread-specific storage destructor type.
Definition threads.h:461
Mutual exclusion locks.
Dynamic package initialization.
volatile int kthread_once_t
Object type backing kthread_once.
Definition once.h:35
Condition variable.
Definition cond.h:62
Structure describing one running thread.
Definition thread.h:169
Mutual exclusion lock type.
Definition mutex.h:68
Threading support.
KOS-implementation of select C11 and POSIX extensions.
Thread-local storage support.
int kthread_key_t
Thread-local storage key type.
Definition tls.h:28