blob: b36a52ec9cce86364fadf78c754ae58fe906f205 [file] [log] [blame]
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +00001// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_THREADING_SUPPORT
12#define _LIBCPP_THREADING_SUPPORT
13
14#include <__config>
15
16#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
17#pragma GCC system_header
18#endif
19
20#ifndef _LIBCPP_HAS_NO_THREADS
21
Asiri Rathnayake040945b2016-09-11 21:46:40 +000022#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && (!defined(__has_include) || __has_include(<__external_threading>))
23#include <__external_threading>
24#else
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000025#include <pthread.h>
26#include <sched.h>
27#endif
28
Asiri Rathnayake040945b2016-09-11 21:46:40 +000029#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
30#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
31#else
32#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
33#endif
34
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000035_LIBCPP_BEGIN_NAMESPACE_STD
36
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000037// Mutex
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000038typedef pthread_mutex_t __libcpp_mutex_t;
Asiri Rathnayake040945b2016-09-11 21:46:40 +000039#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000040
Asiri Rathnayake040945b2016-09-11 21:46:40 +000041_LIBCPP_THREAD_ABI_VISIBILITY
42int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m);
43_LIBCPP_THREAD_ABI_VISIBILITY
44int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
45_LIBCPP_THREAD_ABI_VISIBILITY
46int __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
47_LIBCPP_THREAD_ABI_VISIBILITY
48int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
49_LIBCPP_THREAD_ABI_VISIBILITY
50int __libcpp_mutex_destroy(__libcpp_mutex_t* __m);
51
52// Condition variable
53typedef pthread_cond_t __libcpp_condvar_t;
54#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
55_LIBCPP_THREAD_ABI_VISIBILITY
56int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
57_LIBCPP_THREAD_ABI_VISIBILITY
58int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
59_LIBCPP_THREAD_ABI_VISIBILITY
60int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
61_LIBCPP_THREAD_ABI_VISIBILITY
62int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts);
63_LIBCPP_THREAD_ABI_VISIBILITY
64int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
65
66// Thread id
67typedef pthread_t __libcpp_thread_id;
68_LIBCPP_THREAD_ABI_VISIBILITY
69bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
70_LIBCPP_THREAD_ABI_VISIBILITY
71bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
72
73// Thread
74typedef pthread_t __libcpp_thread_t;
75_LIBCPP_THREAD_ABI_VISIBILITY
76int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg);
77_LIBCPP_THREAD_ABI_VISIBILITY
78__libcpp_thread_id __libcpp_thread_get_current_id();
79_LIBCPP_THREAD_ABI_VISIBILITY
80__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t);
81_LIBCPP_THREAD_ABI_VISIBILITY
82int __libcpp_thread_join(__libcpp_thread_t* __t);
83_LIBCPP_THREAD_ABI_VISIBILITY
84int __libcpp_thread_detach(__libcpp_thread_t* __t);
85_LIBCPP_THREAD_ABI_VISIBILITY
86void __libcpp_thread_yield();
87
88// Thread local storage
89typedef pthread_key_t __libcpp_tls_key;
90_LIBCPP_THREAD_ABI_VISIBILITY
91int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*));
92_LIBCPP_THREAD_ABI_VISIBILITY
93void* __libcpp_tls_get(__libcpp_tls_key __key);
94_LIBCPP_THREAD_ABI_VISIBILITY
95void __libcpp_tls_set(__libcpp_tls_key __key, void* __p);
96
97#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || defined(_LIBCPP_BUILDING_EXTERNAL_THREADS)
98
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000099int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
100{
101 pthread_mutexattr_t attr;
102 int __ec = pthread_mutexattr_init(&attr);
103 if (__ec) return __ec;
104 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
105 if (__ec)
106 {
107 pthread_mutexattr_destroy(&attr);
108 return __ec;
109 }
110 __ec = pthread_mutex_init(__m, &attr);
111 if (__ec)
112 {
113 pthread_mutexattr_destroy(&attr);
114 return __ec;
115 }
116 __ec = pthread_mutexattr_destroy(&attr);
117 if (__ec)
118 {
119 pthread_mutex_destroy(__m);
120 return __ec;
121 }
122 return 0;
123}
124
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000125int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
126{
127 return pthread_mutex_lock(__m);
128}
129
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000130int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
131{
132 return pthread_mutex_trylock(__m);
133}
134
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000135int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
136{
137 return pthread_mutex_unlock(__m);
138}
139
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000140int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
141{
142 return pthread_mutex_destroy(__m);
143}
144
145// Condition variable
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000146int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
147{
148 return pthread_cond_signal(__cv);
149}
150
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000151int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
152{
153 return pthread_cond_broadcast(__cv);
154}
155
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000156int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
157{
158 return pthread_cond_wait(__cv, __m);
159}
160
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000161int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
162{
163 return pthread_cond_timedwait(__cv, __m, __ts);
164}
165
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000166int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
167{
168 return pthread_cond_destroy(__cv);
169}
170
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000171// Returns non-zero if the thread ids are equal, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000172bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
173{
174 return pthread_equal(t1, t2) != 0;
175}
176
177// Returns non-zero if t1 < t2, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000178bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
179{
180 return t1 < t2;
181}
182
183// Thread
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000184int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
185{
186 return pthread_create(__t, 0, __func, __arg);
187}
188
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000189__libcpp_thread_id __libcpp_thread_get_current_id()
190{
191 return pthread_self();
192}
193
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000194__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
195{
196 return *__t;
197}
198
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000199int __libcpp_thread_join(__libcpp_thread_t* __t)
200{
201 return pthread_join(*__t, 0);
202}
203
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000204int __libcpp_thread_detach(__libcpp_thread_t* __t)
205{
206 return pthread_detach(*__t);
207}
208
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000209void __libcpp_thread_yield()
210{
211 sched_yield();
212}
213
214// Thread local storage
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000215int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*))
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000216{
217 return pthread_key_create(__key, __at_exit);
218}
219
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000220void* __libcpp_tls_get(__libcpp_tls_key __key)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000221{
222 return pthread_getspecific(__key);
223}
224
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000225void __libcpp_tls_set(__libcpp_tls_key __key, void* __p)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000226{
227 pthread_setspecific(__key, __p);
228}
229
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000230#endif // _LIBCPP_HAS_THREAD_API_PTHREAD || _LIBCPP_BUILDING_EXTERNAL_THREADS
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000231
232_LIBCPP_END_NAMESPACE_STD
233
234#endif // _LIBCPP_HAS_NO_THREADS
235
236#endif // _LIBCPP_THREADING_SUPPORT