blob: 2a0705a96f06cbadbbf271261c7dc259362c5ff1 [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
Asiri Rathnayake040945b2016-09-11 21:46:40 +000020#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
Eric Fiselier66134e82017-01-06 20:05:40 +000021# include <__external_threading>
22#elif !defined(_LIBCPP_HAS_NO_THREADS)
23
24#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
25# include <pthread.h>
26# include <sched.h>
27#endif
28
29#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
30 defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)
Asiri Rathnayake040945b2016-09-11 21:46:40 +000031#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
32#else
33#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
34#endif
35
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000036_LIBCPP_BEGIN_NAMESPACE_STD
37
Eric Fiselier66134e82017-01-06 20:05:40 +000038#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000039// Mutex
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000040typedef pthread_mutex_t __libcpp_mutex_t;
Asiri Rathnayake040945b2016-09-11 21:46:40 +000041#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000042
Saleem Abdulrasool3451a652017-01-05 17:54:45 +000043typedef pthread_mutex_t __libcpp_recursive_mutex_t;
44
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000045// Condition Variable
Asiri Rathnayake040945b2016-09-11 21:46:40 +000046typedef pthread_cond_t __libcpp_condvar_t;
47#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000048
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +000049// Execute once
50typedef pthread_once_t __libcpp_exec_once_flag;
51#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
52
53// Thread id
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000054typedef pthread_t __libcpp_thread_id;
55
56// Thread
57typedef pthread_t __libcpp_thread_t;
58
59// Thrad Local Storage
60typedef pthread_key_t __libcpp_tls_key;
61#endif
62
63// Mutex
64_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool3451a652017-01-05 17:54:45 +000065int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
66
67_LIBCPP_THREAD_ABI_VISIBILITY
68int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
69
70_LIBCPP_THREAD_ABI_VISIBILITY
71int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
72
73_LIBCPP_THREAD_ABI_VISIBILITY
74int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
75
76_LIBCPP_THREAD_ABI_VISIBILITY
77int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000078
79_LIBCPP_THREAD_ABI_VISIBILITY
80int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
81
82_LIBCPP_THREAD_ABI_VISIBILITY
83int __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
84
85_LIBCPP_THREAD_ABI_VISIBILITY
86int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
87
88_LIBCPP_THREAD_ABI_VISIBILITY
89int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
90
91// Condition variable
Asiri Rathnayake040945b2016-09-11 21:46:40 +000092_LIBCPP_THREAD_ABI_VISIBILITY
93int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000094
Asiri Rathnayake040945b2016-09-11 21:46:40 +000095_LIBCPP_THREAD_ABI_VISIBILITY
96int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000097
Asiri Rathnayake040945b2016-09-11 21:46:40 +000098_LIBCPP_THREAD_ABI_VISIBILITY
99int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000100
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000101_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000102int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
103 timespec *__ts);
104
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000105_LIBCPP_THREAD_ABI_VISIBILITY
106int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
107
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +0000108// Execute once
109_LIBCPP_THREAD_ABI_VISIBILITY
110int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
111 void (*init_routine)(void));
112
113// Thread id
114#if defined(__APPLE__) && !defined(__arm__)
115_LIBCPP_THREAD_ABI_VISIBILITY
116mach_port_t __libcpp_thread_get_port();
117#endif
118
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000119_LIBCPP_THREAD_ABI_VISIBILITY
120bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000121
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000122_LIBCPP_THREAD_ABI_VISIBILITY
123bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
124
125// Thread
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000126_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000127int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
128 void *__arg);
129
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000130_LIBCPP_THREAD_ABI_VISIBILITY
131__libcpp_thread_id __libcpp_thread_get_current_id();
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000132
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000133_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000134__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
135
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000136_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000137int __libcpp_thread_join(__libcpp_thread_t *__t);
138
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000139_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000140int __libcpp_thread_detach(__libcpp_thread_t *__t);
141
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000142_LIBCPP_THREAD_ABI_VISIBILITY
143void __libcpp_thread_yield();
144
145// Thread local storage
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000146_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000147int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *));
148
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000149_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000150void *__libcpp_tls_get(__libcpp_tls_key __key);
151
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000152_LIBCPP_THREAD_ABI_VISIBILITY
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +0000153int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000154
Eric Fiselier66134e82017-01-06 20:05:40 +0000155#if !defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
156 defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)
157
158#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000159
Saleem Abdulrasool3451a652017-01-05 17:54:45 +0000160int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000161{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000162 pthread_mutexattr_t attr;
163 int __ec = pthread_mutexattr_init(&attr);
164 if (__ec)
165 return __ec;
166 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
167 if (__ec) {
168 pthread_mutexattr_destroy(&attr);
169 return __ec;
170 }
171 __ec = pthread_mutex_init(__m, &attr);
172 if (__ec) {
173 pthread_mutexattr_destroy(&attr);
174 return __ec;
175 }
176 __ec = pthread_mutexattr_destroy(&attr);
177 if (__ec) {
178 pthread_mutex_destroy(__m);
179 return __ec;
180 }
181 return 0;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000182}
183
Saleem Abdulrasool3451a652017-01-05 17:54:45 +0000184int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
185{
186 return pthread_mutex_lock(__m);
187}
188
189int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
190{
191 return pthread_mutex_trylock(__m);
192}
193
194int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
195{
196 return pthread_mutex_unlock(__m);
197}
198
199int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
200{
201 return pthread_mutex_destroy(__m);
202}
203
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000204int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000205{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000206 return pthread_mutex_lock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000207}
208
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000209int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000210{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000211 return pthread_mutex_trylock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000212}
213
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000214int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000215{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000216 return pthread_mutex_unlock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000217}
218
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000219int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000220{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000221 return pthread_mutex_destroy(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000222}
223
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000224// Condition Variable
225int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000226{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000227 return pthread_cond_signal(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000228}
229
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000230int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000231{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000232 return pthread_cond_broadcast(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000233}
234
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000235int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000236{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000237 return pthread_cond_wait(__cv, __m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000238}
239
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000240int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
241 timespec *__ts)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000242{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000243 return pthread_cond_timedwait(__cv, __m, __ts);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000244}
245
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000246int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000247{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000248 return pthread_cond_destroy(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000249}
250
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +0000251// Execute once
252int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
253 void (*init_routine)(void)) {
254 return pthread_once(flag, init_routine);
255}
256
257// Thread id
258#if defined(__APPLE__) && !defined(__arm__)
259mach_port_t __libcpp_thread_get_port() {
260 return pthread_mach_thread_np(pthread_self());
261}
262#endif
263
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000264// Returns non-zero if the thread ids are equal, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000265bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
266{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000267 return pthread_equal(t1, t2) != 0;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000268}
269
270// Returns non-zero if t1 < t2, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000271bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
272{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000273 return t1 < t2;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000274}
275
276// Thread
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000277int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
278 void *__arg)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000279{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000280 return pthread_create(__t, 0, __func, __arg);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000281}
282
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000283__libcpp_thread_id __libcpp_thread_get_current_id()
284{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000285 return pthread_self();
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000286}
287
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000288__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000289{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000290 return *__t;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000291}
292
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000293int __libcpp_thread_join(__libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000294{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000295 return pthread_join(*__t, 0);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000296}
297
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000298int __libcpp_thread_detach(__libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000299{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000300 return pthread_detach(*__t);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000301}
302
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000303void __libcpp_thread_yield()
304{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000305 sched_yield();
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000306}
307
308// Thread local storage
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000309int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000310{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000311 return pthread_key_create(__key, __at_exit);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000312}
313
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000314void *__libcpp_tls_get(__libcpp_tls_key __key)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000315{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000316 return pthread_getspecific(__key);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000317}
318
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +0000319int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000320{
Asiri Rathnayakee262e7b2017-01-03 12:59:50 +0000321 return pthread_setspecific(__key, __p);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000322}
323
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000324#endif // _LIBCPP_HAS_THREAD_API_PTHREAD
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000325
Eric Fiselier66134e82017-01-06 20:05:40 +0000326#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
327
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000328_LIBCPP_END_NAMESPACE_STD
329
Eric Fiselier66134e82017-01-06 20:05:40 +0000330#endif // !_LIBCPP_HAS_NO_THREADS
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000331
332#endif // _LIBCPP_THREADING_SUPPORT