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-2014 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 #endif
80
81 /* Generic includes */
82 #include <time.h>
83
84 /* Platform specific includes */
85 #if defined(_TTHREAD_POSIX_)
86 #include <pthread.h>
87 #elif defined(_TTHREAD_WIN32_)
88 #ifndef WIN32_LEAN_AND_MEAN
89 #define WIN32_LEAN_AND_MEAN
90 #define __UNDEF_LEAN_AND_MEAN
91 #endif
92 #include <windows.h>
93 #ifdef __UNDEF_LEAN_AND_MEAN
94 #undef WIN32_LEAN_AND_MEAN
95 #undef __UNDEF_LEAN_AND_MEAN
96 #endif
97 #endif
98
99 /* Compiler-specific information */
100 #if defined(__GNUC__)
101 #define TTHREAD_NORETURN __attribute__((noreturn))
102 #else
103 #define TTHREAD_NORETURN
104 #endif
105
106 /* If TIME_UTC is missing, provide it and provide a wrapper for
107 timespec_get. */
108 #ifndef TIME_UTC
109 #define TIME_UTC 1
110 #define _TTHREAD_EMULATE_TIMESPEC_GET_
111
112 #if defined(_TTHREAD_WIN32_)
113 struct _tthread_timespec {
114 time_t tv_sec;
115 long tv_nsec;
116 };
117 #define timespec _tthread_timespec
118 #endif
119
120 int _tthread_timespec_get(struct timespec *ts, int base);
121 #define timespec_get _tthread_timespec_get
122 #endif
123
125 #define TINYCTHREAD_VERSION_MAJOR 1
126
127 #define TINYCTHREAD_VERSION_MINOR 2
128
129 #define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR)
130
150 /* FIXME: Check for a PROPER value of __STDC_VERSION__ to know if we have C11 */
151 #if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local)
152 #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
153 #define _Thread_local __thread
154 #else
155 #define _Thread_local __declspec(thread)
156 #endif
157 #endif
158
159 /* Macros */
160 #if defined(_TTHREAD_WIN32_)
161 #define TSS_DTOR_ITERATIONS (4)
162 #else
163 #define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS
164 #endif
165
166 /* Function return values */
167 #define thrd_error 0
168 #define thrd_success 1
169 #define thrd_timedout 2
170 #define thrd_busy 3
171 #define thrd_nomem 4
173 /* Mutex types */
174 #define mtx_plain 0
175 #define mtx_timed 1
176 #define mtx_recursive 2
177
178 /* Mutex */
179 #if defined(_TTHREAD_WIN32_)
180 typedef struct {
181 union {
182 CRITICAL_SECTION cs; /* Critical section handle (used for non-timed mutexes) */
183 HANDLE mut; /* Mutex handle (used for timed mutex) */
184 } mHandle; /* Mutex handle */
185 int mAlreadyLocked; /* TRUE if the mutex is already locked */
186 int mRecursive; /* TRUE if the mutex is recursive */
187 int mTimed; /* TRUE if the mutex is timed */
188 } mtx_t;
189 #else
190 typedef pthread_mutex_t mtx_t;
191 #endif
192
205 int mtx_init(mtx_t *mtx, int type);
206
210 void mtx_destroy(mtx_t *mtx);
211
220 int mtx_lock(mtx_t *mtx);
221
224 int mtx_timedlock(mtx_t *mtx, const struct timespec *ts);
225
234 int mtx_trylock(mtx_t *mtx);
235
241 int mtx_unlock(mtx_t *mtx);
242
243 /* Condition variable */
244 #if defined(_TTHREAD_WIN32_)
245 typedef struct {
246 HANDLE mEvents[2]; /* Signal and broadcast event HANDLEs. */
247 unsigned int mWaitersCount; /* Count of the number of waiters. */
248 CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */
249 } cnd_t;
250 #else
251 typedef pthread_cond_t cnd_t;
252 #endif
253
259 int cnd_init(cnd_t *cond);
260
264 void cnd_destroy(cnd_t *cond);
265
274 int cnd_signal(cnd_t *cond);
275
284 int cnd_broadcast(cnd_t *cond);
285
296 int cnd_wait(cnd_t *cond, mtx_t *mtx);
297
310 int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
311
312 /* Thread */
313 #if defined(_TTHREAD_WIN32_)
314 typedef HANDLE thrd_t;
315 #else
316 typedef pthread_t thrd_t;
317 #endif
318
327 typedef int (*thrd_start_t)(void *arg);
328
341 int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
342
346 thrd_t thrd_current(void);
347
351 int thrd_detach(thrd_t thr);
352
358 int thrd_equal(thrd_t thr0, thrd_t thr1);
359
363 void thrd_exit(int res) TTHREAD_NORETURN;
364
374 int thrd_join(thrd_t thr, int *res);
375
387 int thrd_sleep(const struct timespec *duration, struct timespec *remaining);
388
393 void thrd_yield(void);
394
395 /* Thread local storage */
396 #if defined(_TTHREAD_WIN32_)
397 typedef DWORD tss_t;
398 #else
399 typedef pthread_key_t tss_t;
400 #endif
401
405 typedef void (*tss_dtor_t)(void *val);
406
419 int tss_create(tss_t *key, tss_dtor_t dtor);
420
426 void tss_delete(tss_t key);
427
433 void *tss_get(tss_t key);
434
442 int tss_set(tss_t key, void *val);
443
444 #if defined(_TTHREAD_WIN32_)
445 typedef struct {
446 LONG volatile status;
447 CRITICAL_SECTION lock;
448 } once_flag;
449 #define ONCE_FLAG_INIT {0,}
450 #else
451 #define once_flag pthread_once_t
452 #define ONCE_FLAG_INIT PTHREAD_ONCE_INIT
453 #endif
454
460 #if defined(_TTHREAD_WIN32_)
461 void call_once(once_flag *flag, void (*func)(void));
462 #else
463 #define call_once(flag,func) pthread_once(flag,func)
464 #endif
465
466 #ifdef __cplusplus
467 }
468 #endif
469
470 #endif /* _TINYTHREAD_H_ */
471
thrd_start_t
int(* thrd_start_t)(void *arg)
Thread start function.
Definition: tinycthread.h:327
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)
NOT YET IMPLEMENTED.
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.
cnd_init
int cnd_init(cnd_t *cond)
Create a condition variable object.
thrd_exit
void thrd_exit(int res) TTHREAD_NORETURN
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.
call_once
#define call_once(flag, func)
Invoke a callback exactly once.
Definition: tinycthread.h:463
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.
tss_dtor_t
void(* tss_dtor_t)(void *val)
Destructor function for a thread-specific storage.
Definition: tinycthread.h:405
thrd_equal
int thrd_equal(thrd_t thr0, thrd_t thr1)
Compare two thread identifiers.