1*61046927SAndroid Build Coastguard Worker /* 2*61046927SAndroid Build Coastguard Worker * C11 <threads.h> emulation library 3*61046927SAndroid Build Coastguard Worker * 4*61046927SAndroid Build Coastguard Worker * (C) Copyright yohhoy 2012. 5*61046927SAndroid Build Coastguard Worker * Copyright 2022 Yonggang Luo 6*61046927SAndroid Build Coastguard Worker * Distributed under the Boost Software License, Version 1.0. 7*61046927SAndroid Build Coastguard Worker * 8*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person or organization 9*61046927SAndroid Build Coastguard Worker * obtaining a copy of the software and accompanying documentation covered by 10*61046927SAndroid Build Coastguard Worker * this license (the "Software") to use, reproduce, display, distribute, 11*61046927SAndroid Build Coastguard Worker * execute, and transmit the Software, and to prepare [[derivative work]]s of the 12*61046927SAndroid Build Coastguard Worker * Software, and to permit third-parties to whom the Software is furnished to 13*61046927SAndroid Build Coastguard Worker * do so, all subject to the following: 14*61046927SAndroid Build Coastguard Worker * 15*61046927SAndroid Build Coastguard Worker * The copyright notices in the Software and this entire statement, including 16*61046927SAndroid Build Coastguard Worker * the above license grant, this restriction and the following disclaimer, 17*61046927SAndroid Build Coastguard Worker * must be included in all copies of the Software, in whole or in part, and 18*61046927SAndroid Build Coastguard Worker * all derivative works of the Software, unless such copies or derivative 19*61046927SAndroid Build Coastguard Worker * works are solely in the form of machine-executable object code generated by 20*61046927SAndroid Build Coastguard Worker * a source language processor. 21*61046927SAndroid Build Coastguard Worker * 22*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 25*61046927SAndroid Build Coastguard Worker * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 26*61046927SAndroid Build Coastguard Worker * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 27*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28*61046927SAndroid Build Coastguard Worker * DEALINGS IN THE SOFTWARE. 29*61046927SAndroid Build Coastguard Worker */ 30*61046927SAndroid Build Coastguard Worker 31*61046927SAndroid Build Coastguard Worker #ifndef C11_THREADS_H_INCLUDED_ 32*61046927SAndroid Build Coastguard Worker #define C11_THREADS_H_INCLUDED_ 33*61046927SAndroid Build Coastguard Worker 34*61046927SAndroid Build Coastguard Worker #include "c11/time.h" 35*61046927SAndroid Build Coastguard Worker 36*61046927SAndroid Build Coastguard Worker #include <errno.h> 37*61046927SAndroid Build Coastguard Worker #include <limits.h> 38*61046927SAndroid Build Coastguard Worker #include <stdlib.h> 39*61046927SAndroid Build Coastguard Worker 40*61046927SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(HAVE_PTHREAD) 41*61046927SAndroid Build Coastguard Worker # include <io.h> /* close */ 42*61046927SAndroid Build Coastguard Worker # include <process.h> /* _exit */ 43*61046927SAndroid Build Coastguard Worker #elif defined(HAVE_PTHREAD) 44*61046927SAndroid Build Coastguard Worker # include <pthread.h> 45*61046927SAndroid Build Coastguard Worker # include <unistd.h> /* close, _exit */ 46*61046927SAndroid Build Coastguard Worker #else 47*61046927SAndroid Build Coastguard Worker # error Not supported on this platform. 48*61046927SAndroid Build Coastguard Worker #endif 49*61046927SAndroid Build Coastguard Worker 50*61046927SAndroid Build Coastguard Worker #if defined(HAVE_THRD_CREATE) 51*61046927SAndroid Build Coastguard Worker #include <threads.h> 52*61046927SAndroid Build Coastguard Worker #else 53*61046927SAndroid Build Coastguard Worker 54*61046927SAndroid Build Coastguard Worker /*---------------------------- macros ---------------------------*/ 55*61046927SAndroid Build Coastguard Worker 56*61046927SAndroid Build Coastguard Worker #ifndef _Thread_local 57*61046927SAndroid Build Coastguard Worker # if defined(__cplusplus) 58*61046927SAndroid Build Coastguard Worker /* C++11 doesn't need `_Thread_local` keyword or macro */ 59*61046927SAndroid Build Coastguard Worker # elif !defined(__STDC_NO_THREADS__) 60*61046927SAndroid Build Coastguard Worker /* threads are optional in C11, _Thread_local present in this condition */ 61*61046927SAndroid Build Coastguard Worker # elif defined(_MSC_VER) 62*61046927SAndroid Build Coastguard Worker # define _Thread_local __declspec(thread) 63*61046927SAndroid Build Coastguard Worker # elif defined(__GNUC__) 64*61046927SAndroid Build Coastguard Worker # define _Thread_local __thread 65*61046927SAndroid Build Coastguard Worker # else 66*61046927SAndroid Build Coastguard Worker /* Leave _Thread_local undefined so that use of _Thread_local would not promote 67*61046927SAndroid Build Coastguard Worker * to a non-thread-local global variable 68*61046927SAndroid Build Coastguard Worker */ 69*61046927SAndroid Build Coastguard Worker # endif 70*61046927SAndroid Build Coastguard Worker #endif 71*61046927SAndroid Build Coastguard Worker 72*61046927SAndroid Build Coastguard Worker #if !defined(__cplusplus) 73*61046927SAndroid Build Coastguard Worker /* 74*61046927SAndroid Build Coastguard Worker * C11 thread_local() macro 75*61046927SAndroid Build Coastguard Worker * C++11 and above already have thread_local keyword 76*61046927SAndroid Build Coastguard Worker */ 77*61046927SAndroid Build Coastguard Worker # ifndef thread_local 78*61046927SAndroid Build Coastguard Worker # define thread_local _Thread_local 79*61046927SAndroid Build Coastguard Worker # endif 80*61046927SAndroid Build Coastguard Worker #endif 81*61046927SAndroid Build Coastguard Worker 82*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus 83*61046927SAndroid Build Coastguard Worker extern "C" { 84*61046927SAndroid Build Coastguard Worker #endif 85*61046927SAndroid Build Coastguard Worker 86*61046927SAndroid Build Coastguard Worker /*---------------------------- types ----------------------------*/ 87*61046927SAndroid Build Coastguard Worker typedef void (*tss_dtor_t)(void *); 88*61046927SAndroid Build Coastguard Worker typedef int (*thrd_start_t)(void *); 89*61046927SAndroid Build Coastguard Worker 90*61046927SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(HAVE_PTHREAD) 91*61046927SAndroid Build Coastguard Worker typedef struct 92*61046927SAndroid Build Coastguard Worker { 93*61046927SAndroid Build Coastguard Worker void *Ptr; 94*61046927SAndroid Build Coastguard Worker } cnd_t; 95*61046927SAndroid Build Coastguard Worker /* Define thrd_t as struct type intentionally for avoid use of thrd_t as pointer type */ 96*61046927SAndroid Build Coastguard Worker typedef struct 97*61046927SAndroid Build Coastguard Worker { 98*61046927SAndroid Build Coastguard Worker void *handle; 99*61046927SAndroid Build Coastguard Worker } thrd_t; 100*61046927SAndroid Build Coastguard Worker typedef unsigned long tss_t; 101*61046927SAndroid Build Coastguard Worker typedef struct 102*61046927SAndroid Build Coastguard Worker { 103*61046927SAndroid Build Coastguard Worker void *DebugInfo; 104*61046927SAndroid Build Coastguard Worker long LockCount; 105*61046927SAndroid Build Coastguard Worker long RecursionCount; 106*61046927SAndroid Build Coastguard Worker void *OwningThread; 107*61046927SAndroid Build Coastguard Worker void *LockSemaphore; 108*61046927SAndroid Build Coastguard Worker uintptr_t SpinCount; 109*61046927SAndroid Build Coastguard Worker } mtx_t; /* Mock of CRITICAL_SECTION */ 110*61046927SAndroid Build Coastguard Worker typedef struct 111*61046927SAndroid Build Coastguard Worker { 112*61046927SAndroid Build Coastguard Worker volatile uintptr_t status; 113*61046927SAndroid Build Coastguard Worker } once_flag; 114*61046927SAndroid Build Coastguard Worker # define ONCE_FLAG_INIT {0} 115*61046927SAndroid Build Coastguard Worker # define TSS_DTOR_ITERATIONS 1 116*61046927SAndroid Build Coastguard Worker #elif defined(HAVE_PTHREAD) 117*61046927SAndroid Build Coastguard Worker typedef pthread_cond_t cnd_t; 118*61046927SAndroid Build Coastguard Worker typedef pthread_t thrd_t; 119*61046927SAndroid Build Coastguard Worker typedef pthread_key_t tss_t; 120*61046927SAndroid Build Coastguard Worker typedef pthread_mutex_t mtx_t; 121*61046927SAndroid Build Coastguard Worker typedef pthread_once_t once_flag; 122*61046927SAndroid Build Coastguard Worker # define ONCE_FLAG_INIT PTHREAD_ONCE_INIT 123*61046927SAndroid Build Coastguard Worker # ifdef PTHREAD_DESTRUCTOR_ITERATIONS 124*61046927SAndroid Build Coastguard Worker # define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS 125*61046927SAndroid Build Coastguard Worker # else 126*61046927SAndroid Build Coastguard Worker # define TSS_DTOR_ITERATIONS 1 // assume TSS dtor MAY be called at least once. 127*61046927SAndroid Build Coastguard Worker # endif 128*61046927SAndroid Build Coastguard Worker #else 129*61046927SAndroid Build Coastguard Worker # error Not supported on this platform. 130*61046927SAndroid Build Coastguard Worker #endif 131*61046927SAndroid Build Coastguard Worker 132*61046927SAndroid Build Coastguard Worker /*-------------------- enumeration constants --------------------*/ 133*61046927SAndroid Build Coastguard Worker enum 134*61046927SAndroid Build Coastguard Worker { 135*61046927SAndroid Build Coastguard Worker mtx_plain = 0x1, 136*61046927SAndroid Build Coastguard Worker mtx_recursive = 0x2, 137*61046927SAndroid Build Coastguard Worker mtx_timed = 0x4, 138*61046927SAndroid Build Coastguard Worker }; 139*61046927SAndroid Build Coastguard Worker 140*61046927SAndroid Build Coastguard Worker enum 141*61046927SAndroid Build Coastguard Worker { 142*61046927SAndroid Build Coastguard Worker thrd_success = 0, // succeeded 143*61046927SAndroid Build Coastguard Worker thrd_timedout, // timed out 144*61046927SAndroid Build Coastguard Worker thrd_error, // failed 145*61046927SAndroid Build Coastguard Worker thrd_busy, // resource busy 146*61046927SAndroid Build Coastguard Worker thrd_nomem // out of memory 147*61046927SAndroid Build Coastguard Worker }; 148*61046927SAndroid Build Coastguard Worker 149*61046927SAndroid Build Coastguard Worker /*-------------------------- functions --------------------------*/ 150*61046927SAndroid Build Coastguard Worker 151*61046927SAndroid Build Coastguard Worker void call_once(once_flag *, void (*)(void)); 152*61046927SAndroid Build Coastguard Worker int cnd_broadcast(cnd_t *); 153*61046927SAndroid Build Coastguard Worker void cnd_destroy(cnd_t *); 154*61046927SAndroid Build Coastguard Worker int cnd_init(cnd_t *); 155*61046927SAndroid Build Coastguard Worker int cnd_signal(cnd_t *); 156*61046927SAndroid Build Coastguard Worker int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict __mtx, 157*61046927SAndroid Build Coastguard Worker const struct timespec *__restrict); 158*61046927SAndroid Build Coastguard Worker int cnd_wait(cnd_t *, mtx_t *__mtx); 159*61046927SAndroid Build Coastguard Worker void mtx_destroy(mtx_t *__mtx); 160*61046927SAndroid Build Coastguard Worker int mtx_init(mtx_t *__mtx, int); 161*61046927SAndroid Build Coastguard Worker int mtx_lock(mtx_t *__mtx); 162*61046927SAndroid Build Coastguard Worker int mtx_timedlock(mtx_t *__restrict __mtx, 163*61046927SAndroid Build Coastguard Worker const struct timespec *__restrict); 164*61046927SAndroid Build Coastguard Worker int mtx_trylock(mtx_t *__mtx); 165*61046927SAndroid Build Coastguard Worker int mtx_unlock(mtx_t *__mtx); 166*61046927SAndroid Build Coastguard Worker int thrd_create(thrd_t *, thrd_start_t, void *); 167*61046927SAndroid Build Coastguard Worker thrd_t thrd_current(void); 168*61046927SAndroid Build Coastguard Worker int thrd_detach(thrd_t); 169*61046927SAndroid Build Coastguard Worker int thrd_equal(thrd_t, thrd_t); 170*61046927SAndroid Build Coastguard Worker #if defined(__cplusplus) 171*61046927SAndroid Build Coastguard Worker [[ noreturn ]] 172*61046927SAndroid Build Coastguard Worker #else 173*61046927SAndroid Build Coastguard Worker _Noreturn 174*61046927SAndroid Build Coastguard Worker #endif 175*61046927SAndroid Build Coastguard Worker void thrd_exit(int); 176*61046927SAndroid Build Coastguard Worker int thrd_join(thrd_t, int *); 177*61046927SAndroid Build Coastguard Worker int thrd_sleep(const struct timespec *, struct timespec *); 178*61046927SAndroid Build Coastguard Worker void thrd_yield(void); 179*61046927SAndroid Build Coastguard Worker int tss_create(tss_t *, tss_dtor_t); 180*61046927SAndroid Build Coastguard Worker void tss_delete(tss_t); 181*61046927SAndroid Build Coastguard Worker void *tss_get(tss_t); 182*61046927SAndroid Build Coastguard Worker int tss_set(tss_t, void *); 183*61046927SAndroid Build Coastguard Worker 184*61046927SAndroid Build Coastguard Worker #ifdef __cplusplus 185*61046927SAndroid Build Coastguard Worker } 186*61046927SAndroid Build Coastguard Worker #endif 187*61046927SAndroid Build Coastguard Worker 188*61046927SAndroid Build Coastguard Worker #endif /* HAVE_THRD_CREATE */ 189*61046927SAndroid Build Coastguard Worker 190*61046927SAndroid Build Coastguard Worker #endif /* C11_THREADS_H_INCLUDED_ */ 191