77#include <jasper/jas_config.h> 
   82#if defined(JAS_THREADS) 
   87#if defined(JAS_THREADS_C11) 
   90#elif defined(JAS_THREADS_PTHREAD) 
   93#elif defined(JAS_THREADS_WIN32) 
   96#include <processthreadsapi.h> 
  114#if defined(JAS_THREADS) 
  115#if defined(JAS_FOR_INTERNAL_USE_ONLY) || defined(JAS_FOR_JASPER_APP_USE_ONLY) 
  121#if defined(JAS_THREADS_C11) 
  122#       define JAS_THREADS_IMPL "C11" 
  123#       define JAS_USE_SPINLOCK 
  124#elif defined(JAS_THREADS_PTHREAD) 
  125#       define JAS_THREADS_IMPL "PTHREAD" 
  126#       undef JAS_USE_SPINLOCK 
  127#elif defined(JAS_THREADS_WIN32) 
  128#       define JAS_THREADS_IMPL "WIN32" 
  129#       define JAS_USE_SPINLOCK 
  137#if defined(JAS_THREADS_C11) 
  138#       define JAS_USE_SPINLOCK 
  142#elif defined(JAS_THREADS_PTHREAD) 
  144#       undef JAS_USE_SPINLOCK 
  145#elif defined(JAS_THREADS_WIN32) 
  146#       define JAS_USE_SPINLOCK 
  153#if defined(JAS_THREADS_C11) 
  154#define JAS_SPINLOCK_INITIALIZER {ATOMIC_FLAG_INIT} 
  155#elif defined(JAS_THREADS_PTHREAD) 
  157#elif defined(JAS_THREADS_WIN32) 
  158#define JAS_SPINLOCK_INITIALIZER {0} 
  166#if defined(JAS_THREADS_C11) 
  167typedef mtx_t jas_basicmutex_t;
 
  168#elif defined(JAS_THREADS_PTHREAD) 
  169typedef pthread_mutex_t jas_basicmutex_t;
 
  170#elif defined(JAS_THREADS_WIN32) 
  171typedef CRITICAL_SECTION jas_basicmutex_t;
 
  175#if defined(JAS_THREADS_C11) 
  176#undef JAS_BASICMUTEX_INITIALIZER 
  177#elif defined(JAS_THREADS_PTHREAD) 
  178#define JAS_BASICMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 
  179#elif defined(JAS_THREADS_WIN32) 
  180#define JAS_BASICMUTEX_INITIALIZER 
  187#if defined(JAS_USE_SPINLOCK) 
  188#       define jas_mutex_t jas_spinlock_t 
  189#       define JAS_MUTEX_INITIALIZER JAS_SPINLOCK_INITIALIZER 
  190#       define jas_mutex_init jas_spinlock_init 
  191#       define jas_mutex_cleanup jas_spinlock_cleanup 
  192#       define jas_mutex_lock jas_spinlock_lock 
  193#       define jas_mutex_unlock jas_spinlock_unlock 
  195#       define jas_mutex_t jas_basicmutex_t 
  196#       define JAS_MUTEX_INITIALIZER JAS_BASICMUTEX_INITIALIZER 
  197#       define jas_mutex_init jas_basicmutex_init 
  198#       define jas_mutex_cleanup jas_basicmutex_cleanup 
  199#       define jas_mutex_lock jas_basicmutex_lock 
  200#       define jas_mutex_unlock jas_basicmutex_unlock 
  208#if defined(JAS_THREADS_C11) 
  209typedef once_flag jas_once_flag_t;
 
  210#elif defined(JAS_THREADS_PTHREAD) 
  211typedef pthread_once_t jas_once_flag_t;
 
  212#elif defined(JAS_THREADS_WIN32) 
  214        volatile LONG status;
 
  219#if defined(JAS_THREADS_C11) 
  220#       define JAS_ONCE_FLAG_INIT ONCE_FLAG_INIT 
  221#elif defined(JAS_THREADS_PTHREAD) 
  222#       define JAS_ONCE_FLAG_INIT PTHREAD_ONCE_INIT 
  223#elif defined(JAS_THREADS_WIN32) 
  224#       define JAS_ONCE_FLAG_INIT {0} 
  231#if defined(JAS_FOR_INTERNAL_USE_ONLY) || defined(JAS_FOR_JASPER_APP_USE_ONLY) 
  234#if defined(JAS_THREADS_C11) 
  235typedef thrd_t jas_thread_id_t;
 
  236#elif defined(JAS_THREADS_PTHREAD) 
  237typedef pthread_t jas_thread_id_t;
 
  238#elif defined(JAS_THREADS_WIN32) 
  239typedef HANDLE jas_thread_id_t;
 
  243#if defined(JAS_THREADS_C11) 
  244typedef thrd_t jas_thread_t;
 
  245#elif defined(JAS_THREADS_PTHREAD) 
  252#elif defined(JAS_THREADS_WIN32) 
  260static inline void jas_thread_yield(
void);
 
  269#if defined(JAS_THREADS_C11) 
  270typedef tss_t jas_tss_t;
 
  271#elif defined(JAS_THREADS_PTHREAD) 
  272typedef pthread_key_t jas_tss_t;
 
  273#elif defined(JAS_THREADS_WIN32) 
  274typedef DWORD jas_tss_t;
 
  282#if defined(JAS_USE_SPINLOCK) 
  295static inline int jas_spinlock_init(jas_spinlock_t *mtx)
 
  298#if defined(JAS_THREADS_C11) 
  299        atomic_flag_clear(&mtx->flag);
 
  301#elif defined(JAS_THREADS_PTHREAD) 
  305#elif defined(JAS_THREADS_WIN32) 
  306        InterlockedExchange(&mtx->flag, 0);
 
  322static inline int jas_spinlock_cleanup(jas_spinlock_t *mtx)
 
  325#if defined(JAS_THREADS_C11) 
  328#elif defined(JAS_THREADS_PTHREAD) 
  332#elif defined(JAS_THREADS_WIN32) 
  349static inline int jas_spinlock_lock(jas_spinlock_t *mtx)
 
  352#if defined(JAS_THREADS_C11) 
  353        while (atomic_flag_test_and_set(&mtx->flag)) {}
 
  355#elif defined(JAS_THREADS_PTHREAD) 
  359#elif defined(JAS_THREADS_WIN32) 
  360        while (InterlockedCompareExchange(&mtx->flag, 1, 0)) {}
 
  376static inline int jas_spinlock_unlock(jas_spinlock_t *mtx)
 
  379#if defined(JAS_THREADS_C11) 
  380        atomic_flag_clear(&mtx->flag);
 
  382#elif defined(JAS_THREADS_PTHREAD) 
  386#elif defined(JAS_THREADS_WIN32) 
  387        InterlockedExchange(&mtx->flag, 0);
 
  399static inline int jas_basicmutex_init(jas_basicmutex_t *mtx)
 
  402#if defined(JAS_THREADS_C11) 
  403        return mtx_init(mtx, mtx_plain) == thrd_success ? 0 : -1;
 
  404#elif defined(JAS_THREADS_PTHREAD) 
  405        return pthread_mutex_init(mtx, 0);
 
  406#elif defined(JAS_THREADS_WIN32) 
  407        InitializeCriticalSection(mtx);
 
  413static inline int jas_basicmutex_cleanup(jas_basicmutex_t *mtx)
 
  416#if defined(JAS_THREADS_C11) 
  419#elif defined(JAS_THREADS_PTHREAD) 
  420        return pthread_mutex_destroy(mtx);
 
  421#elif defined(JAS_THREADS_WIN32) 
  422        DeleteCriticalSection(mtx);
 
  428static inline int jas_basicmutex_lock(jas_basicmutex_t *mtx)
 
  431#if defined(JAS_THREADS_C11) 
  432        return mtx_lock(mtx);
 
  433#elif defined(JAS_THREADS_PTHREAD) 
  434        return pthread_mutex_lock(mtx);
 
  435#elif defined(JAS_THREADS_WIN32) 
  436        EnterCriticalSection(mtx);
 
  442static inline int jas_basicmutex_unlock(jas_basicmutex_t *mtx)
 
  445#if defined(JAS_THREADS_C11) 
  446        return mtx_unlock(mtx);
 
  447#elif defined(JAS_THREADS_PTHREAD) 
  448        return pthread_mutex_unlock(mtx);
 
  449#elif defined(JAS_THREADS_WIN32) 
  450        LeaveCriticalSection(mtx);
 
  473int jas_tss_create(jas_tss_t *tss, 
void (*destructor)(
void *))
 
  476#if defined(JAS_THREADS_C11) 
  477        return tss_create(tss, destructor) == thrd_success ? 0 : -1;
 
  478#elif defined(JAS_THREADS_PTHREAD) 
  479        return pthread_key_create(tss, destructor);
 
  480#elif defined(JAS_THREADS_WIN32) 
  485        if ((
id = TlsAlloc()) == TLS_OUT_OF_INDEXES) {
 
  504void jas_tss_delete(jas_tss_t tss)
 
  506#if defined(JAS_THREADS_C11) 
  508#elif defined(JAS_THREADS_PTHREAD) 
  509        pthread_key_delete(tss);
 
  510#elif defined(JAS_THREADS_WIN32) 
  525void *jas_tss_get(jas_tss_t tss)
 
  527#if defined(JAS_THREADS_C11) 
  529#elif defined(JAS_THREADS_PTHREAD) 
  530        return pthread_getspecific(tss);
 
  531#elif defined(JAS_THREADS_WIN32) 
  532        return TlsGetValue(tss);
 
  547int jas_tss_set(jas_tss_t tss, 
void *value)
 
  549#if defined(JAS_THREADS_C11) 
  550        return tss_set(tss, value) == thrd_success ? 0 : -1;
 
  551#elif defined(JAS_THREADS_PTHREAD) 
  552        return pthread_setspecific(tss, value);
 
  553#elif defined(JAS_THREADS_WIN32) 
  554        return TlsSetValue(tss, value) ? 0 : -1;
 
  572static inline int jas_call_once(jas_once_flag_t *flag, 
void (*func)(
void))
 
  576#if defined(JAS_THREADS_C11) 
  577        call_once(flag, func);
 
  579#elif defined(JAS_THREADS_PTHREAD) 
  580        return pthread_once(flag, func);
 
  581#elif defined(JAS_THREADS_WIN32) 
  582        if (InterlockedCompareExchange(&flag->status, 1, 0) == 0) {
 
  584                InterlockedExchange(&flag->status, 2);
 
  586                while (flag->status == 1) {
 
  600#if defined(JAS_FOR_INTERNAL_USE_ONLY) || defined(JAS_FOR_JASPER_APP_USE_ONLY) 
  602#if defined(JAS_THREADS_PTHREAD) 
  603static void *thread_func_wrapper(
void *thread_ptr)
 
  605        jas_thread_t *thread = JAS_CAST(jas_thread_t *, thread_ptr);
 
  606        int result = (thread->func)(thread->arg);
 
  607        thread->result = result;
 
  610#elif defined(JAS_THREADS_WIN32) 
  611static unsigned __stdcall thread_func_wrapper(
void *thread_ptr)
 
  613        jas_thread_t *thread = JAS_CAST(jas_thread_t *, thread_ptr);
 
  614        int result = (thread->func)(thread->arg);
 
  615        return JAS_CAST(
unsigned, result);
 
  628int jas_thread_compare(jas_thread_id_t x, jas_thread_id_t y)
 
  630#if defined(JAS_THREADS_C11) 
  631        return thrd_equal(x, y);
 
  632#elif defined(JAS_THREADS_PTHREAD) 
  633        return pthread_equal(x, y);
 
  634#elif defined(JAS_THREADS_WIN32) 
  635        return GetThreadId(x) == GetThreadId(y);
 
  648int jas_thread_create(jas_thread_t *thread, 
int (*func)(
void *), 
void *arg)
 
  652#if defined(JAS_THREADS_C11) 
  653        return thrd_create(thread, func, arg) == thrd_success ? 0 : -1;
 
  654#elif defined(JAS_THREADS_PTHREAD) 
  658        return pthread_create(&thread->id, 0, thread_func_wrapper, thread);
 
  659#elif defined(JAS_THREADS_WIN32) 
  663        if (!(handle = _beginthreadex(0, 0, thread_func_wrapper, thread, 0, 0))) {
 
  666        thread->id = JAS_CAST(jas_thread_id_t, handle);
 
  680int jas_thread_join(jas_thread_t *thread, 
int *result)
 
  683#if defined(JAS_THREADS_C11) 
  684        return thrd_join(*thread, result) == thrd_success ? 0 : -1;
 
  685#elif defined(JAS_THREADS_PTHREAD) 
  687        int ret = pthread_join(thread->id, &result_buf);
 
  689                jas_thread_t *other_thread = JAS_CAST(jas_thread_t *, result_buf);
 
  692                        assert(other_thread);
 
  693                        *result = other_thread ? other_thread->result : 0;
 
  697#elif defined(JAS_THREADS_WIN32) 
  700        if ((w = WaitForSingleObject(thread->id, INFINITE)) != WAIT_OBJECT_0) {
 
  704                if (!GetExitCodeThread(thread->id, &code)) {
 
  705                        CloseHandle(thread->id);
 
  708                *result = JAS_CAST(
int, code);
 
  710        CloseHandle(thread->id);
 
  725static inline void jas_thread_yield(
void)
 
  727#if defined(JAS_THREADS_C11) 
  729#elif defined(JAS_THREADS_PTHREAD) 
  731#elif defined(JAS_THREADS_WIN32) 
  739void jas_thread_exit(
int result)
 
  741#if defined(JAS_THREADS_C11) 
  743#elif defined(JAS_THREADS_PTHREAD) 
  746        jas_thread_t *thread = jas_thread_find(pthread_self());
 
  747        thread->result = result;
 
  748        pthread_exit(JAS_CAST(
void *, thread));
 
  758jas_thread_id_t jas_thread_current(
void)
 
  760#if defined(JAS_THREADS_C11) 
  761        return thrd_current();
 
  762#elif defined(JAS_THREADS_PTHREAD) 
  763        return pthread_self();
 
  764#elif defined(JAS_THREADS_WIN32) 
#define JAS_UNUSED(x)
Indicate that a variable may be unused (in order to avoid a compiler warning).
Definition jas_compiler.h:145