]> pd.if.org Git - pdclib/blob - includes/threads.h
* Change the style of inclusion of the internal/ headers. Modern preprocessors
[pdclib] / includes / threads.h
1 #ifndef _PDCLIB_THREADS_H\r
2 #define _PDCLIB_THREADS_H\r
3 #include <_PDCLIB_threadconfig.h>\r
4 #include <time.h>\r
5 _PDCLIB_BEGIN_EXTERN_C\r
6 \r
7 #define thread_local _Thread_local\r
8 \r
9 typedef _PDCLIB_once_flag once_flag;\r
10 \r
11 enum {\r
12         mtx_plain               = 0,\r
13         mtx_recursive   = (1 << 0),\r
14         mtx_timed               = (1 << 1),\r
15 \r
16         _PDCLIB_mtx_valid_mask = mtx_recursive | mtx_timed\r
17 };\r
18 \r
19 enum {\r
20         thrd_success    = 0,\r
21         thrd_timeout    = 1,\r
22         thrd_busy               = 2,\r
23         thrd_error              = 3,\r
24         thrd_nomem              = 4,\r
25 };\r
26 \r
27 #define ONCE_FLAG_INIT _PDCLIB_ONCE_FLAG_INIT\r
28 #if defined(_PDCLIB_ONCE_FLAG_DONE)\r
29 static inline void call_once(once_flag *flag, void (*func)(void))\r
30 {\r
31         if(*flag != _PDCLIB_ONCE_FLAG_DONE) {\r
32                 _PDCLIB_call_once(flag, func);\r
33         }\r
34 }\r
35 #else\r
36 void call_once(once_flag *flag, void (*func)(void))\r
37 #endif\r
38 \r
39 #if defined(_PDCLIB_MTX_T)\r
40 typedef _PDCLIB_MTX_T   mtx_t;\r
41 void mtx_destroy(mtx_t *mtx);\r
42 int mtx_init(mtx_t *mtx, int type);\r
43 int mtx_lock(mtx_t *mtx);\r
44 int mtx_timedlock(mtx_t *_PDCLIB_restrict mtx, const struct timespec *_PDCLIB_restrict ts);\r
45 int mtx_trylock(mtx_t *mtx);\r
46 int mtx_unlock(mtx_t *mtx);\r
47 #endif\r
48 \r
49 #if defined(_PDCLIB_CND_T)\r
50 typedef _PDCLIB_CND_T   cnd_t;\r
51 int cnd_broadcast(cnd_t *cond);\r
52 void cnd_destroy(cnd_t *cond);\r
53 int cnd_init(cnd_t *cond);\r
54 int cnd_signal(cnd_t *cond);\r
55 int cnd_timedwait(cnd_t *_PDCLIB_restrict cond,\r
56         mtx_t *_PDCLIB_restrict mtx,\r
57         const struct timespec *_PDCLIB_restrict ts);\r
58 int cnd_wait(cnd_t *cond, mtx_t *mtx);\r
59 #endif\r
60 \r
61 #if defined(_PDCLIB_THRD_T)\r
62 #define _PDCLIB_THRD_HAVE_MISC\r
63 typedef _PDCLIB_THRD_T  thrd_t;\r
64 typedef int (*)(void*)  thrd_start_t;\r
65 \r
66 int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);\r
67 thrd_t thrd_current(void);\r
68 int thrd_detach(thrd_t thr);\r
69 int thrd_equal(thrd_t thr0, thrd_t thr1);\r
70 _PDCLIB_noreturn void thrd_exit(int res);\r
71 int thrd_join(thrd_t thr, int *res);\r
72 #endif\r
73 \r
74 #if defined(_PDCLIB_THRD_HAVE_MISC)\r
75 int thrd_sleep(const struct timespec *duration, struct timespec *remaining);\r
76 void thrd_yield(void);\r
77 #endif\r
78 \r
79 /* The behaviour of tss_t is woefully underspecified in the C11 standard. In \r
80  * particular, it never specifies where/when/<b>if</b> destructors are called.\r
81  *\r
82  * In lieu of any clarification, we assume the behaviour of POSIX pthread_key_t\r
83  */\r
84 \r
85 #if defined(_PDCLIB_TSS_T)\r
86 #define TSS_DTOR_ITERATIONS _PDCLIB_TSS_DTOR_ITERATIONS\r
87 \r
88 typedef _PDCLIB_TSS_T   tss_t;\r
89 typedef void (*tss_dtor_t)(void*);\r
90 \r
91 int tss_create(tss_t *key, tss_dtor_t dtor);\r
92 void tss_delete(tss_t key);\r
93 void *tss_get(tss_t key);\r
94 int tss_set(tss_t key, void *val);\r
95 #endif\r
96 \r
97 _PDCLIB_END_EXTERN_C\r
98 #endif\r