TinyCThread 1.1

- Main Page
- Files

- File List
- Globals

tinycthread.h
Go to the documentation of this file.
1 /* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*-
2 Copyright (c) 2012 Marcus Geelnard
3 Copyright (c) 2013-2016 Evan Nemerson
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20
21 3. This notice may not be removed or altered from any source
22 distribution.
23 */
24
25 #ifndef _TINYCTHREAD_H_
26 #define _TINYCTHREAD_H_
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
55 /* Which platform are we on? */
56 #if !defined(_TTHREAD_PLATFORM_DEFINED_)
57 #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
58 #define _TTHREAD_WIN32_
59 #else
60 #define _TTHREAD_POSIX_
61 #endif
62 #define _TTHREAD_PLATFORM_DEFINED_
63 #endif
64
65 /* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */
66 #if defined(_TTHREAD_POSIX_)
67 #undef _FEATURES_H
68 #if !defined(_GNU_SOURCE)
69 #define _GNU_SOURCE
70 #endif
71 #if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L)
72 #undef _POSIX_C_SOURCE
73 #define _POSIX_C_SOURCE 199309L
74 #endif
75 #if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500)
76 #undef _XOPEN_SOURCE
77 #define _XOPEN_SOURCE 500
78 #endif
79 #define _XPG6
80 #endif
81
82 /* Generic includes */
83 #include <time.h>
84
85 /* Platform specific includes */
86 #if defined(_TTHREAD_POSIX_)
87 #include <pthread.h>
88 #elif defined(_TTHREAD_WIN32_)
89 #ifndef WIN32_LEAN_AND_MEAN
90 #define WIN32_LEAN_AND_MEAN
91 #define __UNDEF_LEAN_AND_MEAN
92 #endif
93 #include <windows.h>
94 #ifdef __UNDEF_LEAN_AND_MEAN
95 #undef WIN32_LEAN_AND_MEAN
96 #undef __UNDEF_LEAN_AND_MEAN
97 #endif
98 #endif
99
100 /* Compiler-specific information */
101 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
102 #define TTHREAD_NORETURN _Noreturn
103 #elif defined(__GNUC__)
104 #define TTHREAD_NORETURN __attribute__((__noreturn__))
105 #else
106 #define TTHREAD_NORETURN
107 #endif
108
109 /* If TIME_UTC is missing, provide it and provide a wrapper for
110 timespec_get. */
111 #ifndef TIME_UTC
112 #define TIME_UTC 1
113 #define _TTHREAD_EMULATE_TIMESPEC_GET_
114
115 #if defined(_TTHREAD_WIN32_)
116 struct _tthread_timespec {
117 time_t tv_sec;
118 long tv_nsec;
119 };
120 #define timespec _tthread_timespec
121 #endif
122
123 int _tthread_timespec_get(struct timespec *ts, int base);
124 #define timespec_get _tthread_timespec_get
125 #endif
126
128 #define TINYCTHREAD_VERSION_MAJOR 1
129
130 #define TINYCTHREAD_VERSION_MINOR 2
131
132 #define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR)
133
153 #if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local)
154 #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
155 #define _Thread_local __thread
156 #else
157 #define _Thread_local __declspec(thread)
158 #endif
159 #elif defined(__GNUC__) && defined(__GNUC_MINOR__) && (((__GNUC__ << 8) | __GNUC_MINOR__) < ((4 << 8) | 9))
160 #define _Thread_local __thread
161 #endif
162
163 /* Macros */
164 #if defined(_TTHREAD_WIN32_)
165 #define TSS_DTOR_ITERATIONS (4)
166 #else
167 #define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS
168 #endif
169
170 /* Function return values */
171 #define thrd_error 0
172 #define thrd_success 1
173 #define thrd_timedout 2
174 #define thrd_busy 3
175 #define thrd_nomem 4
177 /* Mutex types */
178 #define mtx_plain 0
179 #define mtx_timed 1
180 #define mtx_recursive 2
181
182 /* Mutex */
183 #if defined(_TTHREAD_WIN32_)
184 typedef struct {
185 union {
186 CRITICAL_SECTION cs; /* Critical section handle (used for non-timed mutexes) */
187 HANDLE mut; /* Mutex handle (used for timed mutex) */
188 } mHandle; /* Mutex handle */
189 int mAlreadyLocked; /* TRUE if the mutex is already locked */
190 int mRecursive; /* TRUE if the mutex is recursive */
191 int mTimed; /* TRUE if the mutex is timed */
192 } mtx_t;
193 #else
194 typedef pthread_mutex_t mtx_t;
195 #endif
196
207 int mtx_init(mtx_t *mtx, int type);
208
212 void mtx_destroy(mtx_t *mtx);
213
222 int mtx_lock(mtx_t *mtx);
223
233 int mtx_timedlock(mtx_t *mtx, const struct timespec *ts);
234
243 int mtx_trylock(mtx_t *mtx);
244
250 int mtx_unlock(mtx_t *mtx);
251
252 /* Condition variable */
253 #if defined(_TTHREAD_WIN32_)
254 typedef struct {
255 HANDLE mEvents[2]; /* Signal and broadcast event HANDLEs. */
256 unsigned int mWaitersCount; /* Count of the number of waiters. */
257 CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
258 } cnd_t;
259 #else
260 typedef pthread_cond_t cnd_t;
261 #endif
262
268 int cnd_init(cnd_t *cond);
269
273 void cnd_destroy(cnd_t *cond);
274
283 int cnd_signal(cnd_t *cond);
284
293 int cnd_broadcast(cnd_t *cond);
294
305 int cnd_wait(cnd_t *cond, mtx_t *mtx);
306
319 int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
320
321 /* Thread */
322 #if defined(_TTHREAD_WIN32_)
323 typedef HANDLE thrd_t;
324 #else
325 typedef pthread_t thrd_t;
326 #endif
327
336 typedef int (*thrd_start_t)(void *arg);
337
350 int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
351
355 thrd_t thrd_current(void);
356
360 int thrd_detach(thrd_t thr);
361
367 int thrd_equal(thrd_t thr0, thrd_t thr1);
368
372 TTHREAD_NORETURN void thrd_exit(int res);
373
383 int thrd_join(thrd_t thr, int *res);
384
396 int thrd_sleep(const struct timespec *duration, struct timespec *remaining);
397
402 void thrd_yield(void);
403
404 /* Thread local storage */
405 #if defined(_TTHREAD_WIN32_)
406 typedef DWORD tss_t;
407 #else
408 typedef pthread_key_t tss_t;
409 #endif
410
414 typedef void (*tss_dtor_t)(void *val);
415
428 int tss_create(tss_t *key, tss_dtor_t dtor);
429
435 void tss_delete(tss_t key);
436
442 void *tss_get(tss_t key);
443
451 int tss_set(tss_t key, void *val);
452
453 #if defined(_TTHREAD_WIN32_)
454 typedef struct {
455 LONG volatile status;
456 CRITICAL_SECTION lock;
457 } once_flag;
458 #define ONCE_FLAG_INIT {0,}
459 #else
460 #define once_flag pthread_once_t
461 #define ONCE_FLAG_INIT PTHREAD_ONCE_INIT
462 #endif
463
469 #if defined(_TTHREAD_WIN32_)
470 void call_once(once_flag *flag, void (*func)(void));
471 #else
472 #define call_once(flag,func) pthread_once(flag,func)
473 #endif
474
475 #ifdef __cplusplus
476 }
477 #endif
478
479 #endif /* _TINYTHREAD_H_ */
mtx_trylock
int mtx_trylock(mtx_t *mtx)
Try to lock the given mutex.
thrd_current
thrd_t thrd_current(void)
Identify the calling thread.
mtx_timedlock
int mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
Lock the given mutex, or block until a specific point in time.
mtx_unlock
int mtx_unlock(mtx_t *mtx)
Unlock the given mutex.
tss_set
int tss_set(tss_t key, void *val)
Set the value for a thread-specific storage.
thrd_create
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
Create a new thread.
thrd_yield
void thrd_yield(void)
Yield execution to another thread.
mtx_init
int mtx_init(mtx_t *mtx, int type)
Create a mutex object.
thrd_start_t
int(* thrd_start_t)(void *arg)
Thread start function.
Definition: tinycthread.h:336
cnd_init
int cnd_init(cnd_t *cond)
Create a condition variable object.
thrd_exit
TTHREAD_NORETURN void thrd_exit(int res)
Terminate execution of the calling thread.
cnd_broadcast
int cnd_broadcast(cnd_t *cond)
Broadcast a condition variable.
mtx_destroy
void mtx_destroy(mtx_t *mtx)
Release any resources used by the given mutex.
thrd_sleep
int thrd_sleep(const struct timespec *duration, struct timespec *remaining)
Put the calling thread to sleep.
tss_get
void * tss_get(tss_t key)
Get the value for a thread-specific storage.
tss_dtor_t
void(* tss_dtor_t)(void *val)
Destructor function for a thread-specific storage.
Definition: tinycthread.h:414
call_once
#define call_once(flag, func)
Invoke a callback exactly once.
Definition: tinycthread.h:472
cnd_wait
int cnd_wait(cnd_t *cond, mtx_t *mtx)
Wait for a condition variable to become signaled.
cnd_signal
int cnd_signal(cnd_t *cond)
Signal a condition variable.
tss_create
int tss_create(tss_t *key, tss_dtor_t dtor)
Create a thread-specific storage.
mtx_lock
int mtx_lock(mtx_t *mtx)
Lock the given mutex.
cnd_timedwait
int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
Wait for a condition variable to become signaled.
thrd_join
int thrd_join(thrd_t thr, int *res)
Wait for a thread to terminate.
tss_delete
void tss_delete(tss_t key)
Delete a thread-specific storage.
thrd_detach
int thrd_detach(thrd_t thr)
Dispose of any resources allocated to the thread when that thread exits.
cnd_destroy
void cnd_destroy(cnd_t *cond)
Release any resources used by the given condition variable.
thrd_equal
int thrd_equal(thrd_t thr0, thrd_t thr1)
Compare two thread identifiers.