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