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
19 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
20 #pragma GCC system_header
23 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
24 # include <__external_threading>
25 #elif !defined(_LIBCPP_HAS_NO_THREADS)
27 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
33 #include <__undef_macros>
35 #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
36 defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
37 defined(_LIBCPP_HAS_THREAD_API_WIN32)
38 #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
40 #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
43 #if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
44 #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
46 #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
49 _LIBCPP_BEGIN_NAMESPACE_STD
51 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
53 typedef pthread_mutex_t __libcpp_mutex_t;
54 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
56 typedef pthread_mutex_t __libcpp_recursive_mutex_t;
59 typedef pthread_cond_t __libcpp_condvar_t;
60 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
63 typedef pthread_once_t __libcpp_exec_once_flag;
64 #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
67 typedef pthread_t __libcpp_thread_id;
70 #define _LIBCPP_NULL_THREAD 0U
72 typedef pthread_t __libcpp_thread_t;
74 // Thread Local Storage
75 typedef pthread_key_t __libcpp_tls_key;
77 #define _LIBCPP_TLS_DESTRUCTOR_CC
80 typedef void* __libcpp_mutex_t;
81 #define _LIBCPP_MUTEX_INITIALIZER 0
83 #if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
84 typedef void* __libcpp_recursive_mutex_t[6];
85 #elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
86 typedef void* __libcpp_recursive_mutex_t[5];
88 # error Unsupported architecture
92 typedef void* __libcpp_condvar_t;
93 #define _LIBCPP_CONDVAR_INITIALIZER 0
96 typedef void* __libcpp_exec_once_flag;
97 #define _LIBCPP_EXEC_ONCE_INITIALIZER 0
100 typedef long __libcpp_thread_id;
103 #define _LIBCPP_NULL_THREAD 0U
105 typedef void* __libcpp_thread_t;
107 // Thread Local Storage
108 typedef long __libcpp_tls_key;
110 #define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
114 _LIBCPP_THREAD_ABI_VISIBILITY
115 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
117 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
118 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
120 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
121 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
123 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
124 int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
126 _LIBCPP_THREAD_ABI_VISIBILITY
127 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
129 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
130 int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
132 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
133 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
135 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
136 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
138 _LIBCPP_THREAD_ABI_VISIBILITY
139 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
141 // Condition variable
142 _LIBCPP_THREAD_ABI_VISIBILITY
143 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
145 _LIBCPP_THREAD_ABI_VISIBILITY
146 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
148 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
149 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
151 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
152 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
155 _LIBCPP_THREAD_ABI_VISIBILITY
156 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
159 _LIBCPP_THREAD_ABI_VISIBILITY
160 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
161 void (*init_routine)(void));
164 _LIBCPP_THREAD_ABI_VISIBILITY
165 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
167 _LIBCPP_THREAD_ABI_VISIBILITY
168 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
171 _LIBCPP_THREAD_ABI_VISIBILITY
172 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
174 _LIBCPP_THREAD_ABI_VISIBILITY
175 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
178 _LIBCPP_THREAD_ABI_VISIBILITY
179 __libcpp_thread_id __libcpp_thread_get_current_id();
181 _LIBCPP_THREAD_ABI_VISIBILITY
182 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
184 _LIBCPP_THREAD_ABI_VISIBILITY
185 int __libcpp_thread_join(__libcpp_thread_t *__t);
187 _LIBCPP_THREAD_ABI_VISIBILITY
188 int __libcpp_thread_detach(__libcpp_thread_t *__t);
190 _LIBCPP_THREAD_ABI_VISIBILITY
191 void __libcpp_thread_yield();
193 _LIBCPP_THREAD_ABI_VISIBILITY
194 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
196 // Thread local storage
197 _LIBCPP_THREAD_ABI_VISIBILITY
198 int __libcpp_tls_create(__libcpp_tls_key* __key,
199 void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
201 _LIBCPP_THREAD_ABI_VISIBILITY
202 void *__libcpp_tls_get(__libcpp_tls_key __key);
204 _LIBCPP_THREAD_ABI_VISIBILITY
205 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
207 #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
208 defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \
209 defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
211 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
213 pthread_mutexattr_t attr;
214 int __ec = pthread_mutexattr_init(&attr);
217 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
219 pthread_mutexattr_destroy(&attr);
222 __ec = pthread_mutex_init(__m, &attr);
224 pthread_mutexattr_destroy(&attr);
227 __ec = pthread_mutexattr_destroy(&attr);
229 pthread_mutex_destroy(__m);
235 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
237 return pthread_mutex_lock(__m);
240 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
242 return pthread_mutex_trylock(__m) == 0;
245 int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
247 return pthread_mutex_unlock(__m);
250 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
252 return pthread_mutex_destroy(__m);
255 int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
257 return pthread_mutex_lock(__m);
260 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
262 return pthread_mutex_trylock(__m) == 0;
265 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
267 return pthread_mutex_unlock(__m);
270 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
272 return pthread_mutex_destroy(__m);
275 // Condition Variable
276 int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
278 return pthread_cond_signal(__cv);
281 int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
283 return pthread_cond_broadcast(__cv);
286 int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
288 return pthread_cond_wait(__cv, __m);
291 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
294 return pthread_cond_timedwait(__cv, __m, __ts);
297 int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
299 return pthread_cond_destroy(__cv);
303 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
304 void (*init_routine)(void)) {
305 return pthread_once(flag, init_routine);
309 // Returns non-zero if the thread ids are equal, otherwise 0
310 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
312 return pthread_equal(t1, t2) != 0;
315 // Returns non-zero if t1 < t2, otherwise 0
316 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
322 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
326 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
329 return pthread_create(__t, 0, __func, __arg);
332 __libcpp_thread_id __libcpp_thread_get_current_id()
334 return pthread_self();
337 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
342 int __libcpp_thread_join(__libcpp_thread_t *__t)
344 return pthread_join(*__t, 0);
347 int __libcpp_thread_detach(__libcpp_thread_t *__t)
349 return pthread_detach(*__t);
352 void __libcpp_thread_yield()
357 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
359 using namespace chrono;
360 seconds __s = duration_cast<seconds>(__ns);
362 typedef decltype(__ts.tv_sec) ts_sec;
363 _LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits<ts_sec>::max();
365 if (__s.count() < __ts_sec_max)
367 __ts.tv_sec = static_cast<ts_sec>(__s.count());
368 __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
372 __ts.tv_sec = __ts_sec_max;
373 __ts.tv_nsec = 999999999; // (10^9 - 1)
376 while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
379 // Thread local storage
380 int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
382 return pthread_key_create(__key, __at_exit);
385 void *__libcpp_tls_get(__libcpp_tls_key __key)
387 return pthread_getspecific(__key);
390 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
392 return pthread_setspecific(__key, __p);
395 #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
397 class _LIBCPP_TYPE_VIS thread;
398 class _LIBCPP_TYPE_VIS __thread_id;
400 namespace this_thread
403 _LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
407 template<> struct hash<__thread_id>;
409 class _LIBCPP_TEMPLATE_VIS __thread_id
411 // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
412 // NULL is the no-thread value on Darwin. Someone needs to check
413 // on other platforms. We assume 0 works everywhere for now.
414 __libcpp_thread_id __id_;
417 _LIBCPP_INLINE_VISIBILITY
418 __thread_id() _NOEXCEPT : __id_(0) {}
420 friend _LIBCPP_INLINE_VISIBILITY
421 bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
422 { // don't pass id==0 to underlying routines
423 if (__x.__id_ == 0) return __y.__id_ == 0;
424 if (__y.__id_ == 0) return false;
425 return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
427 friend _LIBCPP_INLINE_VISIBILITY
428 bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT
429 {return !(__x == __y);}
430 friend _LIBCPP_INLINE_VISIBILITY
431 bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT
432 { // id==0 is always less than any other thread_id
433 if (__x.__id_ == 0) return __y.__id_ != 0;
434 if (__y.__id_ == 0) return false;
435 return __libcpp_thread_id_less(__x.__id_, __y.__id_);
437 friend _LIBCPP_INLINE_VISIBILITY
438 bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT
439 {return !(__y < __x);}
440 friend _LIBCPP_INLINE_VISIBILITY
441 bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT
443 friend _LIBCPP_INLINE_VISIBILITY
444 bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
445 {return !(__x < __y);}
447 _LIBCPP_INLINE_VISIBILITY
448 void __reset() { __id_ = 0; }
450 template<class _CharT, class _Traits>
452 _LIBCPP_INLINE_VISIBILITY
453 basic_ostream<_CharT, _Traits>&
454 operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
457 _LIBCPP_INLINE_VISIBILITY
458 __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
460 friend __thread_id this_thread::get_id() _NOEXCEPT;
461 friend class _LIBCPP_TYPE_VIS thread;
462 friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
465 namespace this_thread
468 inline _LIBCPP_INLINE_VISIBILITY
472 return __libcpp_thread_get_current_id();
477 _LIBCPP_END_NAMESPACE_STD
481 #endif // !_LIBCPP_HAS_NO_THREADS
483 #endif // _LIBCPP_THREADING_SUPPORT