#ifndef _PDCLIB_THREADS_H #define _PDCLIB_THREADS_H #include <_PDCLIB_int.h> #include <_PDCLIB_threadconfig.h> #include _PDCLIB_BEGIN_EXTERN_C #define thread_local _Thread_local typedef _PDCLIB_once_flag once_flag; enum { mtx_plain = 0, mtx_recursive = (1 << 0), mtx_timed = (1 << 1), _PDCLIB_mtx_valid_mask = mtx_recursive | mtx_timed }; enum { thrd_success = 0, thrd_timeout = 1, thrd_busy = 2, thrd_error = 3, thrd_nomem = 4, }; #define ONCE_FLAG_INIT _PDCLIB_ONCE_FLAG_INIT #if defined(_PDCLIB_ONCE_FLAG_IS_DONE) static inline void call_once(once_flag *flag, void (*func)(void)) { if(!_PDCLIB_ONCE_FLAG_IS_DONE(flag)) { _PDCLIB_call_once(flag, func); } } #else void call_once(once_flag *flag, void (*func)(void)); #endif #if defined(_PDCLIB_MTX_T) typedef _PDCLIB_MTX_T mtx_t; void mtx_destroy(mtx_t *mtx) _PDCLIB_nothrow; int mtx_init(mtx_t *mtx, int type) _PDCLIB_nothrow; int mtx_lock(mtx_t *mtx) _PDCLIB_nothrow; int mtx_timedlock(mtx_t *_PDCLIB_restrict mtx, const struct timespec *_PDCLIB_restrict ts) _PDCLIB_nothrow; int mtx_trylock(mtx_t *mtx) _PDCLIB_nothrow; int mtx_unlock(mtx_t *mtx) _PDCLIB_nothrow; #endif #if defined(_PDCLIB_CND_T) typedef _PDCLIB_CND_T cnd_t; int cnd_broadcast(cnd_t *cond) _PDCLIB_nothrow; void cnd_destroy(cnd_t *cond) _PDCLIB_nothrow; int cnd_init(cnd_t *cond) _PDCLIB_nothrow; int cnd_signal(cnd_t *cond) _PDCLIB_nothrow; int cnd_timedwait(cnd_t *_PDCLIB_restrict cond, mtx_t *_PDCLIB_restrict mtx, const struct timespec *_PDCLIB_restrict ts) _PDCLIB_nothrow; int cnd_wait(cnd_t *cond, mtx_t *mtx) _PDCLIB_nothrow; #endif #if defined(_PDCLIB_THRD_T) #define _PDCLIB_THRD_HAVE_MISC typedef _PDCLIB_THRD_T thrd_t; typedef int (*thrd_start_t)(void*); int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) _PDCLIB_nothrow; thrd_t thrd_current(void) _PDCLIB_nothrow; int thrd_detach(thrd_t thr) _PDCLIB_nothrow; int thrd_equal(thrd_t thr0, thrd_t thr1) _PDCLIB_nothrow; /* Not nothrow: systems may use exceptions at thread exit */ _PDCLIB_noreturn void thrd_exit(int res); /* Not nothrow: systems may potentially propogate exceptions out of thrd_join?*/ int thrd_join(thrd_t thr, int *res); #endif #if defined(_PDCLIB_THRD_HAVE_MISC) int thrd_sleep(const struct timespec *duration, struct timespec *remaining) _PDCLIB_nothrow; void thrd_yield(void) _PDCLIB_nothrow; #endif /* The behaviour of tss_t is woefully underspecified in the C11 standard. In * particular, it never specifies where/when/if destructors are called. * * In lieu of any clarification, we assume the behaviour of POSIX pthread_key_t */ #if defined(_PDCLIB_TSS_T) #define TSS_DTOR_ITERATIONS _PDCLIB_TSS_DTOR_ITERATIONS typedef _PDCLIB_TSS_T tss_t; typedef void (*tss_dtor_t)(void*); int tss_create(tss_t *key, tss_dtor_t dtor) _PDCLIB_nothrow; void tss_delete(tss_t key) _PDCLIB_nothrow; void *tss_get(tss_t key) _PDCLIB_nothrow; int tss_set(tss_t key, void *val) _PDCLIB_nothrow; #endif _PDCLIB_END_EXTERN_C #endif