blob: f4d41f7a10512aad13346b868bb3c1e5f29cdeb4 [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) && \
31 __libcpp_has_include(<__external_threading>)
32#include <__external_threading>
33#else
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000034
35#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000036#include <pthread.h>
37#include <sched.h>
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000038#endif
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000039
Asiri Rathnayake040945b2016-09-11 21:46:40 +000040#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
41#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
42#else
43#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
44#endif
45
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000046_LIBCPP_BEGIN_NAMESPACE_STD
47
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000048#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000049// Mutex
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000050typedef pthread_mutex_t __libcpp_mutex_t;
Asiri Rathnayake040945b2016-09-11 21:46:40 +000051#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000052
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000053// Condition Variable
Asiri Rathnayake040945b2016-09-11 21:46:40 +000054typedef pthread_cond_t __libcpp_condvar_t;
55#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000056
57// THread ID
58typedef pthread_t __libcpp_thread_id;
59
60// Thread
61typedef pthread_t __libcpp_thread_t;
62
63// Thrad Local Storage
64typedef pthread_key_t __libcpp_tls_key;
65#endif
66
67// Mutex
68_LIBCPP_THREAD_ABI_VISIBILITY
69int __libcpp_recursive_mutex_init(__libcpp_mutex_t *__m);
70
71_LIBCPP_THREAD_ABI_VISIBILITY
72int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
73
74_LIBCPP_THREAD_ABI_VISIBILITY
75int __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
76
77_LIBCPP_THREAD_ABI_VISIBILITY
78int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
79
80_LIBCPP_THREAD_ABI_VISIBILITY
81int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
82
83// Condition variable
Asiri Rathnayake040945b2016-09-11 21:46:40 +000084_LIBCPP_THREAD_ABI_VISIBILITY
85int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000086
Asiri Rathnayake040945b2016-09-11 21:46:40 +000087_LIBCPP_THREAD_ABI_VISIBILITY
88int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000089
Asiri Rathnayake040945b2016-09-11 21:46:40 +000090_LIBCPP_THREAD_ABI_VISIBILITY
91int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000092
Asiri Rathnayake040945b2016-09-11 21:46:40 +000093_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000094int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
95 timespec *__ts);
96
Asiri Rathnayake040945b2016-09-11 21:46:40 +000097_LIBCPP_THREAD_ABI_VISIBILITY
98int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
99
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000100// Thread ID
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000101_LIBCPP_THREAD_ABI_VISIBILITY
102bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000103
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000104_LIBCPP_THREAD_ABI_VISIBILITY
105bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
106
107// Thread
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000108_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000109int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
110 void *__arg);
111
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000112_LIBCPP_THREAD_ABI_VISIBILITY
113__libcpp_thread_id __libcpp_thread_get_current_id();
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000114
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000115_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000116__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
117
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000118_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000119int __libcpp_thread_join(__libcpp_thread_t *__t);
120
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000121_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000122int __libcpp_thread_detach(__libcpp_thread_t *__t);
123
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000124_LIBCPP_THREAD_ABI_VISIBILITY
125void __libcpp_thread_yield();
126
127// Thread local storage
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000128_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000129int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *));
130
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000131_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000132void *__libcpp_tls_get(__libcpp_tls_key __key);
133
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000134_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000135void __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000136
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000137#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000138
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000139int __libcpp_recursive_mutex_init(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000140{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000141 pthread_mutexattr_t attr;
142 int __ec = pthread_mutexattr_init(&attr);
143 if (__ec)
144 return __ec;
145 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
146 if (__ec) {
147 pthread_mutexattr_destroy(&attr);
148 return __ec;
149 }
150 __ec = pthread_mutex_init(__m, &attr);
151 if (__ec) {
152 pthread_mutexattr_destroy(&attr);
153 return __ec;
154 }
155 __ec = pthread_mutexattr_destroy(&attr);
156 if (__ec) {
157 pthread_mutex_destroy(__m);
158 return __ec;
159 }
160 return 0;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000161}
162
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000163int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000164{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000165 return pthread_mutex_lock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000166}
167
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000168int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000169{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000170 return pthread_mutex_trylock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000171}
172
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000173int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000174{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000175 return pthread_mutex_unlock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000176}
177
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000178int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000179{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000180 return pthread_mutex_destroy(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000181}
182
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000183// Condition Variable
184int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000185{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000186 return pthread_cond_signal(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000187}
188
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000189int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000190{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000191 return pthread_cond_broadcast(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000192}
193
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000194int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000195{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000196 return pthread_cond_wait(__cv, __m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000197}
198
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000199int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
200 timespec *__ts)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000201{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000202 return pthread_cond_timedwait(__cv, __m, __ts);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000203}
204
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000205int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000206{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000207 return pthread_cond_destroy(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000208}
209
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000210// Returns non-zero if the thread ids are equal, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000211bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
212{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000213 return pthread_equal(t1, t2) != 0;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000214}
215
216// Returns non-zero if t1 < t2, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000217bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
218{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000219 return t1 < t2;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000220}
221
222// Thread
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000223int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
224 void *__arg)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000225{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000226 return pthread_create(__t, 0, __func, __arg);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000227}
228
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000229__libcpp_thread_id __libcpp_thread_get_current_id()
230{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000231 return pthread_self();
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000232}
233
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000234__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000235{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000236 return *__t;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000237}
238
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000239int __libcpp_thread_join(__libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000240{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000241 return pthread_join(*__t, 0);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000242}
243
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000244int __libcpp_thread_detach(__libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000245{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000246 return pthread_detach(*__t);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000247}
248
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000249void __libcpp_thread_yield()
250{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000251 sched_yield();
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000252}
253
254// Thread local storage
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000255int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000256{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000257 return pthread_key_create(__key, __at_exit);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000258}
259
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000260void *__libcpp_tls_get(__libcpp_tls_key __key)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000261{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000262 return pthread_getspecific(__key);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000263}
264
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000265void __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000266{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000267 pthread_setspecific(__key, __p);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000268}
269
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000270#endif // _LIBCPP_HAS_THREAD_API_PTHREAD
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000271
272_LIBCPP_END_NAMESPACE_STD
273
Asiri Rathnayake4f2c83f2016-10-14 13:56:58 +0000274#endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>)
Asiri Rathnayake7250d332016-10-14 13:00:07 +0000275
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000276#endif // _LIBCPP_HAS_NO_THREADS
277
278#endif // _LIBCPP_THREADING_SUPPORT