blob: 0064c7d598b1712b1a8ee9b7b7ef440e7188b742 [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 Abdulrasool1d192372017-01-03 02:00:31 +000066// Condition Variable
Asiri Rathnayake040945b2016-09-11 21:46:40 +000067typedef pthread_cond_t __libcpp_condvar_t;
68#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000069
70// THread ID
71typedef pthread_t __libcpp_thread_id;
72
73// Thread
74typedef pthread_t __libcpp_thread_t;
75
76// Thrad Local Storage
77typedef pthread_key_t __libcpp_tls_key;
78#endif
79
80// Mutex
81_LIBCPP_THREAD_ABI_VISIBILITY
82int __libcpp_recursive_mutex_init(__libcpp_mutex_t *__m);
83
84_LIBCPP_THREAD_ABI_VISIBILITY
85int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
86
87_LIBCPP_THREAD_ABI_VISIBILITY
88int __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
89
90_LIBCPP_THREAD_ABI_VISIBILITY
91int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
92
93_LIBCPP_THREAD_ABI_VISIBILITY
94int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
95
96// Condition variable
Asiri Rathnayake040945b2016-09-11 21:46:40 +000097_LIBCPP_THREAD_ABI_VISIBILITY
98int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +000099
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000100_LIBCPP_THREAD_ABI_VISIBILITY
101int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000102
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000103_LIBCPP_THREAD_ABI_VISIBILITY
104int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000105
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000106_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000107int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
108 timespec *__ts);
109
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000110_LIBCPP_THREAD_ABI_VISIBILITY
111int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
112
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000113// Thread ID
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000114_LIBCPP_THREAD_ABI_VISIBILITY
115bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000116
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000117_LIBCPP_THREAD_ABI_VISIBILITY
118bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
119
120// Thread
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000121_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000122int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
123 void *__arg);
124
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000125_LIBCPP_THREAD_ABI_VISIBILITY
126__libcpp_thread_id __libcpp_thread_get_current_id();
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000127
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000128_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000129__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
130
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000131_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000132int __libcpp_thread_join(__libcpp_thread_t *__t);
133
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000134_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000135int __libcpp_thread_detach(__libcpp_thread_t *__t);
136
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000137_LIBCPP_THREAD_ABI_VISIBILITY
138void __libcpp_thread_yield();
139
140// Thread local storage
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000141_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000142int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *));
143
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000144_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000145void *__libcpp_tls_get(__libcpp_tls_key __key);
146
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000147_LIBCPP_THREAD_ABI_VISIBILITY
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000148void __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000149
Asiri Rathnayakee29d9ff2017-01-03 11:32:31 +0000150#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
151 defined(_LIBCPP_BUILDING_THREAD_API_EXTERNAL_PTHREAD)
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000152
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000153int __libcpp_recursive_mutex_init(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000154{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000155 pthread_mutexattr_t attr;
156 int __ec = pthread_mutexattr_init(&attr);
157 if (__ec)
158 return __ec;
159 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
160 if (__ec) {
161 pthread_mutexattr_destroy(&attr);
162 return __ec;
163 }
164 __ec = pthread_mutex_init(__m, &attr);
165 if (__ec) {
166 pthread_mutexattr_destroy(&attr);
167 return __ec;
168 }
169 __ec = pthread_mutexattr_destroy(&attr);
170 if (__ec) {
171 pthread_mutex_destroy(__m);
172 return __ec;
173 }
174 return 0;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000175}
176
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000177int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000178{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000179 return pthread_mutex_lock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000180}
181
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000182int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000183{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000184 return pthread_mutex_trylock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000185}
186
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000187int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000188{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000189 return pthread_mutex_unlock(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000190}
191
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000192int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000193{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000194 return pthread_mutex_destroy(__m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000195}
196
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000197// Condition Variable
198int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000199{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000200 return pthread_cond_signal(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000201}
202
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000203int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000204{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000205 return pthread_cond_broadcast(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000206}
207
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000208int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000209{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000210 return pthread_cond_wait(__cv, __m);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000211}
212
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000213int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
214 timespec *__ts)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000215{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000216 return pthread_cond_timedwait(__cv, __m, __ts);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000217}
218
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000219int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000220{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000221 return pthread_cond_destroy(__cv);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000222}
223
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000224// Returns non-zero if the thread ids are equal, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000225bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
226{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000227 return pthread_equal(t1, t2) != 0;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000228}
229
230// Returns non-zero if t1 < t2, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000231bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
232{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000233 return t1 < t2;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000234}
235
236// Thread
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000237int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
238 void *__arg)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000239{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000240 return pthread_create(__t, 0, __func, __arg);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000241}
242
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000243__libcpp_thread_id __libcpp_thread_get_current_id()
244{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000245 return pthread_self();
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000246}
247
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000248__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000249{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000250 return *__t;
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000251}
252
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000253int __libcpp_thread_join(__libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000254{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000255 return pthread_join(*__t, 0);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000256}
257
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000258int __libcpp_thread_detach(__libcpp_thread_t *__t)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000259{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000260 return pthread_detach(*__t);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000261}
262
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000263void __libcpp_thread_yield()
264{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000265 sched_yield();
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000266}
267
268// Thread local storage
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000269int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000270{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000271 return pthread_key_create(__key, __at_exit);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000272}
273
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000274void *__libcpp_tls_get(__libcpp_tls_key __key)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000275{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000276 return pthread_getspecific(__key);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000277}
278
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000279void __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000280{
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000281 pthread_setspecific(__key, __p);
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000282}
283
Saleem Abdulrasool1d192372017-01-03 02:00:31 +0000284#endif // _LIBCPP_HAS_THREAD_API_PTHREAD
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000285
286_LIBCPP_END_NAMESPACE_STD
287
Asiri Rathnayake4f2c83f2016-10-14 13:56:58 +0000288#endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>)
Asiri Rathnayake7250d332016-10-14 13:00:07 +0000289
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000290#endif // _LIBCPP_HAS_NO_THREADS
291
292#endif // _LIBCPP_THREADING_SUPPORT