/* Threads This file is part of the Public Domain C Library (PDCLib). Permission is granted to use, modify, and / or redistribute at will. */ #ifndef _PDCLIB_THREADS_H #define _PDCLIB_THREADS_H _PDCLIB_THREADS_H #include "_PDCLIB/int.h" #include "_PDCLIB/threadconfig.h" #include #ifdef __cplusplus extern "C" { #endif #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 #ifdef _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 #ifdef _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 #ifdef _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 #ifdef _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 #ifdef _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 */ #ifdef _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 #ifdef __cplusplus } #endif #endif