blob: b4383b92c287f16214b097a8529cc0db7bdd6f7a [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 Rathnayake4f2c83f2016-10-14 13:56:58 +000022#ifndef __libcpp_has_include
23 #ifndef __has_include
24 #define __libcpp_has_include(x) 0
25 #else
26 #define __libcpp_has_include(x) __has_include(x)
27 #endif
Asiri Rathnayakef6600b72016-09-13 09:32:32 +000028#endif
29
Asiri Rathnayake4f2c83f2016-10-14 13:56:58 +000030#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \
Asiri Rathnayakee29d9ff2017-01-03 11:32:31 +000031 !__libcpp_has_include(<__external_threading>)
32// If the <__external_threading> header is absent, build libc++ against a
33// pthread-oriented thread api but leave out its implementation. This setup
34// allows building+testing of an externally-threaded library variant (on any
35// platform that supports pthreads). Here, an 'externally-threaded' library
36// variant is one where the implementation of the libc++ thread api is provided
37// as a separate library.
38#define _LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD
39#endif
40
41#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \
Asiri Rathnayake4f2c83f2016-10-14 13:56:58 +000042 __libcpp_has_include(<__external_threading>)
43#include <__external_threading>
44#else
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000045
Asiri Rathnayakee29d9ff2017-01-03 11:32:31 +000046#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
47 defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000048#include <pthread.h>
49#include <sched.h>
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000050#endif
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000051
Asiri Rathnayake040945b2016-09-11 21:46:40 +000052#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
53#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
54#else
55#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
56#endif
57
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000058_LIBCPP_BEGIN_NAMESPACE_STD
59
Asiri Rathnayakee29d9ff2017-01-03 11:32:31 +000060#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
61 defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000062// Mutex
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000063typedef pthread_mutex_t __libcpp_mutex_t;
Asiri Rathnayake040945b2016-09-11 21:46:40 +000064#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000065
Saleem Abdulrasool3451a652017-01-05 17:54:45 +000066typedef pthread_mutex_t __libcpp_recursive_mutex_t;
67
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000068// Condition Variable
Asiri Rathnayake040945b2016-09-11 21:46:40 +000069typedef pthread_cond_t __libcpp_condvar_t;
70#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000071
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +000072// Execute once
73typedef pthread_once_t __libcpp_exec_once_flag;
74#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
75
76// Thread id
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000077typedef pthread_t __libcpp_thread_id;
78
79// Thread
80typedef pthread_t __libcpp_thread_t;
81
82// Thrad Local Storage
83typedef pthread_key_t __libcpp_tls_key;
84#endif
85
86// Mutex
87_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool3451a652017-01-05 17:54:45 +000088int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
89
90_LIBCPP_THREAD_ABI_VISIBILITY
91int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
92
93_LIBCPP_THREAD_ABI_VISIBILITY
94int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
95
96_LIBCPP_THREAD_ABI_VISIBILITY
97int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
98
99_LIBCPP_THREAD_ABI_VISIBILITY
100int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000101
102_LIBCPP_THREAD_ABI_VISIBILITY
103int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
104
105_LIBCPP_THREAD_ABI_VISIBILITY
106int __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
107
108_LIBCPP_THREAD_ABI_VISIBILITY
109int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
110
111_LIBCPP_THREAD_ABI_VISIBILITY
112int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
113
114// Condition variable
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000115_LIBCPP_THREAD_ABI_VISIBILITY
116int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000117
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000118_LIBCPP_THREAD_ABI_VISIBILITY
119int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000120
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000121_LIBCPP_THREAD_ABI_VISIBILITY
122int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000123
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000124_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000125int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
126 timespec *__ts);
127
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000128_LIBCPP_THREAD_ABI_VISIBILITY
129int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
130
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +0000131// Execute once
132_LIBCPP_THREAD_ABI_VISIBILITY
133int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
134 void (*init_routine)(void));
135
136// Thread id
137#if defined(__APPLE__) && !defined(__arm__)
138_LIBCPP_THREAD_ABI_VISIBILITY
139mach_port_t __libcpp_thread_get_port();
140#endif
141
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000142_LIBCPP_THREAD_ABI_VISIBILITY
143bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000144
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000145_LIBCPP_THREAD_ABI_VISIBILITY
146bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
147
148// Thread
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000149_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000150int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
151 void *__arg);
152
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000153_LIBCPP_THREAD_ABI_VISIBILITY
154__libcpp_thread_id __libcpp_thread_get_current_id();
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000155
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000156_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000157__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
158
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000159_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000160int __libcpp_thread_join(__libcpp_thread_t *__t);
161
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000162_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000163int __libcpp_thread_detach(__libcpp_thread_t *__t);
164
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000165_LIBCPP_THREAD_ABI_VISIBILITY
166void __libcpp_thread_yield();
167
168// Thread local storage
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000169_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000170int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *));
171
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000172_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000173void *__libcpp_tls_get(__libcpp_tls_key __key);
174
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000175_LIBCPP_THREAD_ABI_VISIBILITY
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +0000176int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000177
Asiri Rathnayakee29d9ff2017-01-03 11:32:31 +0000178#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
179 defined(_LIBCPP_BUILDING_THREAD_API_EXTERNAL_PTHREAD)
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000180
Saleem Abdulrasool3451a652017-01-05 17:54:45 +0000181int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000182{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000183 pthread_mutexattr_t attr;
184 int __ec = pthread_mutexattr_init(&attr);
185 if (__ec)
186 return __ec;
187 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
188 if (__ec) {
189 pthread_mutexattr_destroy(&attr);
190 return __ec;
191 }
192 __ec = pthread_mutex_init(__m, &attr);
193 if (__ec) {
194 pthread_mutexattr_destroy(&attr);
195 return __ec;
196 }
197 __ec = pthread_mutexattr_destroy(&attr);
198 if (__ec) {
199 pthread_mutex_destroy(__m);
200 return __ec;
201 }
202 return 0;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000203}
204
Saleem Abdulrasool3451a652017-01-05 17:54:45 +0000205int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
206{
207 return pthread_mutex_lock(__m);
208}
209
210int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
211{
212 return pthread_mutex_trylock(__m);
213}
214
215int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
216{
217 return pthread_mutex_unlock(__m);
218}
219
220int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
221{
222 return pthread_mutex_destroy(__m);
223}
224
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000225int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000226{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000227 return pthread_mutex_lock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000228}
229
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000230int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000231{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000232 return pthread_mutex_trylock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000233}
234
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000235int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000236{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000237 return pthread_mutex_unlock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000238}
239
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000240int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000241{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000242 return pthread_mutex_destroy(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000243}
244
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000245// Condition Variable
246int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000247{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000248 return pthread_cond_signal(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000249}
250
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000251int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000252{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000253 return pthread_cond_broadcast(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000254}
255
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000256int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000257{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000258 return pthread_cond_wait(__cv, __m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000259}
260
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000261int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
262 timespec *__ts)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000263{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000264 return pthread_cond_timedwait(__cv, __m, __ts);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000265}
266
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000267int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000268{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000269 return pthread_cond_destroy(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000270}
271
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +0000272// Execute once
273int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
274 void (*init_routine)(void)) {
275 return pthread_once(flag, init_routine);
276}
277
278// Thread id
279#if defined(__APPLE__) && !defined(__arm__)
280mach_port_t __libcpp_thread_get_port() {
281 return pthread_mach_thread_np(pthread_self());
282}
283#endif
284
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000285// Returns non-zero if the thread ids are equal, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000286bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
287{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000288 return pthread_equal(t1, t2) != 0;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000289}
290
291// Returns non-zero if t1 < t2, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000292bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
293{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000294 return t1 < t2;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000295}
296
297// Thread
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000298int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
299 void *__arg)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000300{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000301 return pthread_create(__t, 0, __func, __arg);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000302}
303
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000304__libcpp_thread_id __libcpp_thread_get_current_id()
305{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000306 return pthread_self();
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000307}
308
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000309__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000310{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000311 return *__t;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000312}
313
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000314int __libcpp_thread_join(__libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000315{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000316 return pthread_join(*__t, 0);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000317}
318
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000319int __libcpp_thread_detach(__libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000320{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000321 return pthread_detach(*__t);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000322}
323
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000324void __libcpp_thread_yield()
325{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000326 sched_yield();
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000327}
328
329// Thread local storage
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000330int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000331{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000332 return pthread_key_create(__key, __at_exit);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000333}
334
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000335void *__libcpp_tls_get(__libcpp_tls_key __key)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000336{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000337 return pthread_getspecific(__key);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000338}
339
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +0000340int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000341{
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +0000342 return pthread_setspecific(__key, __p);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000343}
344
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000345#endif // _LIBCPP_HAS_THREAD_API_PTHREAD
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000346
347_LIBCPP_END_NAMESPACE_STD
348
Asiri Rathnayake4f2c83f2016-10-14 13:56:58 +0000349#endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>)
Asiri Rathnayake7250d332016-10-14 13:00:07 +0000350
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000351#endif // _LIBCPP_HAS_NO_THREADS
352
353#endif // _LIBCPP_THREADING_SUPPORT