2 //===----------------------------------------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_THREADING_SUPPORT
12 #define _LIBCPP_THREADING_SUPPORT
16 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
17 #pragma GCC system_header
20 #ifndef _LIBCPP_HAS_NO_THREADS
22 #ifndef __libcpp_has_include
24 #define __libcpp_has_include(x) 0
26 #define __libcpp_has_include(x) __has_include(x)
30 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \
31 !__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
41 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \
42 __libcpp_has_include(<__external_threading>)
43 #include <__external_threading>
46 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
47 defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
52 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
53 #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
55 #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
58 _LIBCPP_BEGIN_NAMESPACE_STD
60 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
61 defined(_LIBCPP_HAS_THREAD_API_EXTERNAL_PTHREAD)
63 typedef pthread_mutex_t __libcpp_mutex_t;
64 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
66 typedef pthread_mutex_t __libcpp_recursive_mutex_t;
69 typedef pthread_cond_t __libcpp_condvar_t;
70 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
73 typedef pthread_once_t __libcpp_exec_once_flag;
74 #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
77 typedef pthread_t __libcpp_thread_id;
80 typedef pthread_t __libcpp_thread_t;
82 // Thrad Local Storage
83 typedef pthread_key_t __libcpp_tls_key;
87 _LIBCPP_THREAD_ABI_VISIBILITY
88 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
90 _LIBCPP_THREAD_ABI_VISIBILITY
91 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
93 _LIBCPP_THREAD_ABI_VISIBILITY
94 int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
96 _LIBCPP_THREAD_ABI_VISIBILITY
97 int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
99 _LIBCPP_THREAD_ABI_VISIBILITY
100 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
102 _LIBCPP_THREAD_ABI_VISIBILITY
103 int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
105 _LIBCPP_THREAD_ABI_VISIBILITY
106 int __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
108 _LIBCPP_THREAD_ABI_VISIBILITY
109 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
111 _LIBCPP_THREAD_ABI_VISIBILITY
112 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
114 // Condition variable
115 _LIBCPP_THREAD_ABI_VISIBILITY
116 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
118 _LIBCPP_THREAD_ABI_VISIBILITY
119 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
121 _LIBCPP_THREAD_ABI_VISIBILITY
122 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
124 _LIBCPP_THREAD_ABI_VISIBILITY
125 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
128 _LIBCPP_THREAD_ABI_VISIBILITY
129 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
132 _LIBCPP_THREAD_ABI_VISIBILITY
133 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
134 void (*init_routine)(void));
137 #if defined(__APPLE__) && !defined(__arm__)
138 _LIBCPP_THREAD_ABI_VISIBILITY
139 mach_port_t __libcpp_thread_get_port();
142 _LIBCPP_THREAD_ABI_VISIBILITY
143 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
145 _LIBCPP_THREAD_ABI_VISIBILITY
146 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
149 _LIBCPP_THREAD_ABI_VISIBILITY
150 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
153 _LIBCPP_THREAD_ABI_VISIBILITY
154 __libcpp_thread_id __libcpp_thread_get_current_id();
156 _LIBCPP_THREAD_ABI_VISIBILITY
157 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
159 _LIBCPP_THREAD_ABI_VISIBILITY
160 int __libcpp_thread_join(__libcpp_thread_t *__t);
162 _LIBCPP_THREAD_ABI_VISIBILITY
163 int __libcpp_thread_detach(__libcpp_thread_t *__t);
165 _LIBCPP_THREAD_ABI_VISIBILITY
166 void __libcpp_thread_yield();
168 // Thread local storage
169 _LIBCPP_THREAD_ABI_VISIBILITY
170 int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *));
172 _LIBCPP_THREAD_ABI_VISIBILITY
173 void *__libcpp_tls_get(__libcpp_tls_key __key);
175 _LIBCPP_THREAD_ABI_VISIBILITY
176 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
178 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || \
179 defined(_LIBCPP_BUILDING_THREAD_API_EXTERNAL_PTHREAD)
181 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
183 pthread_mutexattr_t attr;
184 int __ec = pthread_mutexattr_init(&attr);
187 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
189 pthread_mutexattr_destroy(&attr);
192 __ec = pthread_mutex_init(__m, &attr);
194 pthread_mutexattr_destroy(&attr);
197 __ec = pthread_mutexattr_destroy(&attr);
199 pthread_mutex_destroy(__m);
205 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
207 return pthread_mutex_lock(__m);
210 int __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
212 return pthread_mutex_trylock(__m);
215 int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
217 return pthread_mutex_unlock(__m);
220 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
222 return pthread_mutex_destroy(__m);
225 int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
227 return pthread_mutex_lock(__m);
230 int __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
232 return pthread_mutex_trylock(__m);
235 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
237 return pthread_mutex_unlock(__m);
240 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
242 return pthread_mutex_destroy(__m);
245 // Condition Variable
246 int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
248 return pthread_cond_signal(__cv);
251 int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
253 return pthread_cond_broadcast(__cv);
256 int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
258 return pthread_cond_wait(__cv, __m);
261 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
264 return pthread_cond_timedwait(__cv, __m, __ts);
267 int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
269 return pthread_cond_destroy(__cv);
273 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
274 void (*init_routine)(void)) {
275 return pthread_once(flag, init_routine);
279 #if defined(__APPLE__) && !defined(__arm__)
280 mach_port_t __libcpp_thread_get_port() {
281 return pthread_mach_thread_np(pthread_self());
285 // Returns non-zero if the thread ids are equal, otherwise 0
286 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
288 return pthread_equal(t1, t2) != 0;
291 // Returns non-zero if t1 < t2, otherwise 0
292 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
298 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
301 return pthread_create(__t, 0, __func, __arg);
304 __libcpp_thread_id __libcpp_thread_get_current_id()
306 return pthread_self();
309 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
314 int __libcpp_thread_join(__libcpp_thread_t *__t)
316 return pthread_join(*__t, 0);
319 int __libcpp_thread_detach(__libcpp_thread_t *__t)
321 return pthread_detach(*__t);
324 void __libcpp_thread_yield()
329 // Thread local storage
330 int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
332 return pthread_key_create(__key, __at_exit);
335 void *__libcpp_tls_get(__libcpp_tls_key __key)
337 return pthread_getspecific(__key);
340 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
342 return pthread_setspecific(__key, __p);
345 #endif // _LIBCPP_HAS_THREAD_API_PTHREAD
347 _LIBCPP_END_NAMESPACE_STD
349 #endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>)
351 #endif // _LIBCPP_HAS_NO_THREADS
353 #endif // _LIBCPP_THREADING_SUPPORT