1*c7e4239fSAsiri Rathnayake// -*- C++ -*- 2*c7e4239fSAsiri Rathnayake//===----------------------------------------------------------------------===// 3*c7e4239fSAsiri Rathnayake// 4*c7e4239fSAsiri Rathnayake// The LLVM Compiler Infrastructure 5*c7e4239fSAsiri Rathnayake// 6*c7e4239fSAsiri Rathnayake// This file is dual licensed under the MIT and the University of Illinois Open 7*c7e4239fSAsiri Rathnayake// Source Licenses. See LICENSE.TXT for details. 8*c7e4239fSAsiri Rathnayake// 9*c7e4239fSAsiri Rathnayake//===----------------------------------------------------------------------===// 10*c7e4239fSAsiri Rathnayake 11*c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_THREADING_SUPPORT 12*c7e4239fSAsiri Rathnayake#define _LIBCPP_THREADING_SUPPORT 13*c7e4239fSAsiri Rathnayake 14*c7e4239fSAsiri Rathnayake#include <__config> 15*c7e4239fSAsiri Rathnayake 16*c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER 17*c7e4239fSAsiri Rathnayake#pragma GCC system_header 18*c7e4239fSAsiri Rathnayake#endif 19*c7e4239fSAsiri Rathnayake 20*c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_HAS_NO_THREADS 21*c7e4239fSAsiri Rathnayake 22*c7e4239fSAsiri Rathnayake#if defined(_LIBCPP_THREAD_API_PTHREAD) 23*c7e4239fSAsiri Rathnayake#include <pthread.h> 24*c7e4239fSAsiri Rathnayake#include <sched.h> 25*c7e4239fSAsiri Rathnayake#endif 26*c7e4239fSAsiri Rathnayake 27*c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD 28*c7e4239fSAsiri Rathnayake 29*c7e4239fSAsiri Rathnayake#if defined(_LIBCPP_THREAD_API_PTHREAD) 30*c7e4239fSAsiri Rathnayake 31*c7e4239fSAsiri Rathnayake// Mutex 32*c7e4239fSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 33*c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t; 34*c7e4239fSAsiri Rathnayake 35*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 36*c7e4239fSAsiri Rathnayakeint __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m) 37*c7e4239fSAsiri Rathnayake{ 38*c7e4239fSAsiri Rathnayake pthread_mutexattr_t attr; 39*c7e4239fSAsiri Rathnayake int __ec = pthread_mutexattr_init(&attr); 40*c7e4239fSAsiri Rathnayake if (__ec) return __ec; 41*c7e4239fSAsiri Rathnayake __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 42*c7e4239fSAsiri Rathnayake if (__ec) 43*c7e4239fSAsiri Rathnayake { 44*c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 45*c7e4239fSAsiri Rathnayake return __ec; 46*c7e4239fSAsiri Rathnayake } 47*c7e4239fSAsiri Rathnayake __ec = pthread_mutex_init(__m, &attr); 48*c7e4239fSAsiri Rathnayake if (__ec) 49*c7e4239fSAsiri Rathnayake { 50*c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 51*c7e4239fSAsiri Rathnayake return __ec; 52*c7e4239fSAsiri Rathnayake } 53*c7e4239fSAsiri Rathnayake __ec = pthread_mutexattr_destroy(&attr); 54*c7e4239fSAsiri Rathnayake if (__ec) 55*c7e4239fSAsiri Rathnayake { 56*c7e4239fSAsiri Rathnayake pthread_mutex_destroy(__m); 57*c7e4239fSAsiri Rathnayake return __ec; 58*c7e4239fSAsiri Rathnayake } 59*c7e4239fSAsiri Rathnayake return 0; 60*c7e4239fSAsiri Rathnayake} 61*c7e4239fSAsiri Rathnayake 62*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 63*c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t* __m) 64*c7e4239fSAsiri Rathnayake{ 65*c7e4239fSAsiri Rathnayake return pthread_mutex_lock(__m); 66*c7e4239fSAsiri Rathnayake} 67*c7e4239fSAsiri Rathnayake 68*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 69*c7e4239fSAsiri Rathnayakeint __libcpp_mutex_trylock(__libcpp_mutex_t* __m) 70*c7e4239fSAsiri Rathnayake{ 71*c7e4239fSAsiri Rathnayake return pthread_mutex_trylock(__m); 72*c7e4239fSAsiri Rathnayake} 73*c7e4239fSAsiri Rathnayake 74*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 75*c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t* __m) 76*c7e4239fSAsiri Rathnayake{ 77*c7e4239fSAsiri Rathnayake return pthread_mutex_unlock(__m); 78*c7e4239fSAsiri Rathnayake} 79*c7e4239fSAsiri Rathnayake 80*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 81*c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t* __m) 82*c7e4239fSAsiri Rathnayake{ 83*c7e4239fSAsiri Rathnayake return pthread_mutex_destroy(__m); 84*c7e4239fSAsiri Rathnayake} 85*c7e4239fSAsiri Rathnayake 86*c7e4239fSAsiri Rathnayake// Condition variable 87*c7e4239fSAsiri Rathnayake#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER 88*c7e4239fSAsiri Rathnayaketypedef pthread_cond_t __libcpp_condvar_t; 89*c7e4239fSAsiri Rathnayake 90*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 91*c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv) 92*c7e4239fSAsiri Rathnayake{ 93*c7e4239fSAsiri Rathnayake return pthread_cond_signal(__cv); 94*c7e4239fSAsiri Rathnayake} 95*c7e4239fSAsiri Rathnayake 96*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 97*c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv) 98*c7e4239fSAsiri Rathnayake{ 99*c7e4239fSAsiri Rathnayake return pthread_cond_broadcast(__cv); 100*c7e4239fSAsiri Rathnayake} 101*c7e4239fSAsiri Rathnayake 102*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 103*c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m) 104*c7e4239fSAsiri Rathnayake{ 105*c7e4239fSAsiri Rathnayake return pthread_cond_wait(__cv, __m); 106*c7e4239fSAsiri Rathnayake} 107*c7e4239fSAsiri Rathnayake 108*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 109*c7e4239fSAsiri Rathnayakeint __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts) 110*c7e4239fSAsiri Rathnayake{ 111*c7e4239fSAsiri Rathnayake return pthread_cond_timedwait(__cv, __m, __ts); 112*c7e4239fSAsiri Rathnayake} 113*c7e4239fSAsiri Rathnayake 114*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 115*c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv) 116*c7e4239fSAsiri Rathnayake{ 117*c7e4239fSAsiri Rathnayake return pthread_cond_destroy(__cv); 118*c7e4239fSAsiri Rathnayake} 119*c7e4239fSAsiri Rathnayake 120*c7e4239fSAsiri Rathnayake// Thread id 121*c7e4239fSAsiri Rathnayaketypedef pthread_t __libcpp_thread_id; 122*c7e4239fSAsiri Rathnayake 123*c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0 124*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 125*c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 126*c7e4239fSAsiri Rathnayake{ 127*c7e4239fSAsiri Rathnayake return pthread_equal(t1, t2) != 0; 128*c7e4239fSAsiri Rathnayake} 129*c7e4239fSAsiri Rathnayake 130*c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0 131*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 132*c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 133*c7e4239fSAsiri Rathnayake{ 134*c7e4239fSAsiri Rathnayake return t1 < t2; 135*c7e4239fSAsiri Rathnayake} 136*c7e4239fSAsiri Rathnayake 137*c7e4239fSAsiri Rathnayake// Thread 138*c7e4239fSAsiri Rathnayaketypedef pthread_t __libcpp_thread_t; 139*c7e4239fSAsiri Rathnayake 140*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 141*c7e4239fSAsiri Rathnayakeint __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg) 142*c7e4239fSAsiri Rathnayake{ 143*c7e4239fSAsiri Rathnayake return pthread_create(__t, 0, __func, __arg); 144*c7e4239fSAsiri Rathnayake} 145*c7e4239fSAsiri Rathnayake 146*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 147*c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id() 148*c7e4239fSAsiri Rathnayake{ 149*c7e4239fSAsiri Rathnayake return pthread_self(); 150*c7e4239fSAsiri Rathnayake} 151*c7e4239fSAsiri Rathnayake 152*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 153*c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t) 154*c7e4239fSAsiri Rathnayake{ 155*c7e4239fSAsiri Rathnayake return *__t; 156*c7e4239fSAsiri Rathnayake} 157*c7e4239fSAsiri Rathnayake 158*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 159*c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t* __t) 160*c7e4239fSAsiri Rathnayake{ 161*c7e4239fSAsiri Rathnayake return pthread_join(*__t, 0); 162*c7e4239fSAsiri Rathnayake} 163*c7e4239fSAsiri Rathnayake 164*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 165*c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t* __t) 166*c7e4239fSAsiri Rathnayake{ 167*c7e4239fSAsiri Rathnayake return pthread_detach(*__t); 168*c7e4239fSAsiri Rathnayake} 169*c7e4239fSAsiri Rathnayake 170*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 171*c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield() 172*c7e4239fSAsiri Rathnayake{ 173*c7e4239fSAsiri Rathnayake sched_yield(); 174*c7e4239fSAsiri Rathnayake} 175*c7e4239fSAsiri Rathnayake 176*c7e4239fSAsiri Rathnayake// Thread local storage 177*c7e4239fSAsiri Rathnayaketypedef pthread_key_t __libcpp_tl_key; 178*c7e4239fSAsiri Rathnayake 179*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 180*c7e4239fSAsiri Rathnayakeint __libcpp_tl_create(__libcpp_tl_key* __key, void (*__at_exit)(void*)) 181*c7e4239fSAsiri Rathnayake{ 182*c7e4239fSAsiri Rathnayake return pthread_key_create(__key, __at_exit); 183*c7e4239fSAsiri Rathnayake} 184*c7e4239fSAsiri Rathnayake 185*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 186*c7e4239fSAsiri Rathnayakevoid* __libcpp_tl_get(__libcpp_tl_key __key) 187*c7e4239fSAsiri Rathnayake{ 188*c7e4239fSAsiri Rathnayake return pthread_getspecific(__key); 189*c7e4239fSAsiri Rathnayake} 190*c7e4239fSAsiri Rathnayake 191*c7e4239fSAsiri Rathnayakeinline _LIBCPP_ALWAYS_INLINE 192*c7e4239fSAsiri Rathnayakevoid __libcpp_tl_set(__libcpp_tl_key __key, void* __p) 193*c7e4239fSAsiri Rathnayake{ 194*c7e4239fSAsiri Rathnayake pthread_setspecific(__key, __p); 195*c7e4239fSAsiri Rathnayake} 196*c7e4239fSAsiri Rathnayake 197*c7e4239fSAsiri Rathnayake#else // !_LIBCPP_THREAD_API_PTHREAD 198*c7e4239fSAsiri Rathnayake #error "No thread API selected." 199*c7e4239fSAsiri Rathnayake#endif 200*c7e4239fSAsiri Rathnayake 201*c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD 202*c7e4239fSAsiri Rathnayake 203*c7e4239fSAsiri Rathnayake#endif // _LIBCPP_HAS_NO_THREADS 204*c7e4239fSAsiri Rathnayake 205*c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT 206