]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/__threading_support
Merge lldb trunk r366426, resolve conflicts, and update FREEBSD-Xlist.
[FreeBSD/FreeBSD.git] / contrib / libc++ / include / __threading_support
1 // -*- 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 #include <chrono>
16 #include <iosfwd>
17 #include <errno.h>
18
19 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
20 #pragma GCC system_header
21 #endif
22
23 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
24 # include <__external_threading>
25 #elif !defined(_LIBCPP_HAS_NO_THREADS)
26
27 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
28 # include <pthread.h>
29 # include <sched.h>
30 #endif
31
32 _LIBCPP_PUSH_MACROS
33 #include <__undef_macros>
34
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
39 #else
40 #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
41 #endif
42
43 #if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
44 #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
45 #else
46 #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
47 #endif
48
49 _LIBCPP_BEGIN_NAMESPACE_STD
50
51 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
52 // Mutex
53 typedef pthread_mutex_t __libcpp_mutex_t;
54 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
55
56 typedef pthread_mutex_t __libcpp_recursive_mutex_t;
57
58 // Condition Variable
59 typedef pthread_cond_t __libcpp_condvar_t;
60 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
61
62 // Execute once
63 typedef pthread_once_t __libcpp_exec_once_flag;
64 #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
65
66 // Thread id
67 typedef pthread_t __libcpp_thread_id;
68
69 // Thread
70 #define _LIBCPP_NULL_THREAD 0U
71
72 typedef pthread_t __libcpp_thread_t;
73
74 // Thread Local Storage
75 typedef pthread_key_t __libcpp_tls_key;
76
77 #define _LIBCPP_TLS_DESTRUCTOR_CC
78 #else
79 // Mutex
80 typedef void* __libcpp_mutex_t;
81 #define _LIBCPP_MUTEX_INITIALIZER 0
82
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];
87 #else
88 # error Unsupported architecture
89 #endif
90
91 // Condition Variable
92 typedef void* __libcpp_condvar_t;
93 #define _LIBCPP_CONDVAR_INITIALIZER 0
94
95 // Execute Once
96 typedef void* __libcpp_exec_once_flag;
97 #define _LIBCPP_EXEC_ONCE_INITIALIZER 0
98
99 // Thread ID
100 typedef long __libcpp_thread_id;
101
102 // Thread
103 #define _LIBCPP_NULL_THREAD 0U
104
105 typedef void* __libcpp_thread_t;
106
107 // Thread Local Storage
108 typedef long __libcpp_tls_key;
109
110 #define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
111 #endif
112
113 // Mutex
114 _LIBCPP_THREAD_ABI_VISIBILITY
115 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
116
117 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
118 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
119
120 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
121 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
122
123 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
124 int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
125
126 _LIBCPP_THREAD_ABI_VISIBILITY
127 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
128
129 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
130 int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
131
132 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
133 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
134
135 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
136 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
137
138 _LIBCPP_THREAD_ABI_VISIBILITY
139 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
140
141 // Condition variable
142 _LIBCPP_THREAD_ABI_VISIBILITY
143 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
144
145 _LIBCPP_THREAD_ABI_VISIBILITY
146 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
147
148 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
149 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
150
151 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
152 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
153                                timespec *__ts);
154
155 _LIBCPP_THREAD_ABI_VISIBILITY
156 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
157
158 // Execute once
159 _LIBCPP_THREAD_ABI_VISIBILITY
160 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
161                           void (*init_routine)(void));
162
163 // Thread id
164 _LIBCPP_THREAD_ABI_VISIBILITY
165 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
166
167 _LIBCPP_THREAD_ABI_VISIBILITY
168 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
169
170 // Thread
171 _LIBCPP_THREAD_ABI_VISIBILITY
172 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
173
174 _LIBCPP_THREAD_ABI_VISIBILITY
175 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
176                            void *__arg);
177
178 _LIBCPP_THREAD_ABI_VISIBILITY
179 __libcpp_thread_id __libcpp_thread_get_current_id();
180
181 _LIBCPP_THREAD_ABI_VISIBILITY
182 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
183
184 _LIBCPP_THREAD_ABI_VISIBILITY
185 int __libcpp_thread_join(__libcpp_thread_t *__t);
186
187 _LIBCPP_THREAD_ABI_VISIBILITY
188 int __libcpp_thread_detach(__libcpp_thread_t *__t);
189
190 _LIBCPP_THREAD_ABI_VISIBILITY
191 void __libcpp_thread_yield();
192
193 _LIBCPP_THREAD_ABI_VISIBILITY
194 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
195
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*));
200
201 _LIBCPP_THREAD_ABI_VISIBILITY
202 void *__libcpp_tls_get(__libcpp_tls_key __key);
203
204 _LIBCPP_THREAD_ABI_VISIBILITY
205 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
206
207 #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
208      defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \
209     defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
210
211 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
212 {
213   pthread_mutexattr_t attr;
214   int __ec = pthread_mutexattr_init(&attr);
215   if (__ec)
216     return __ec;
217   __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
218   if (__ec) {
219     pthread_mutexattr_destroy(&attr);
220     return __ec;
221   }
222   __ec = pthread_mutex_init(__m, &attr);
223   if (__ec) {
224     pthread_mutexattr_destroy(&attr);
225     return __ec;
226   }
227   __ec = pthread_mutexattr_destroy(&attr);
228   if (__ec) {
229     pthread_mutex_destroy(__m);
230     return __ec;
231   }
232   return 0;
233 }
234
235 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
236 {
237   return pthread_mutex_lock(__m);
238 }
239
240 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
241 {
242   return pthread_mutex_trylock(__m) == 0;
243 }
244
245 int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
246 {
247   return pthread_mutex_unlock(__m);
248 }
249
250 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
251 {
252   return pthread_mutex_destroy(__m);
253 }
254
255 int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
256 {
257   return pthread_mutex_lock(__m);
258 }
259
260 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
261 {
262   return pthread_mutex_trylock(__m) == 0;
263 }
264
265 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
266 {
267   return pthread_mutex_unlock(__m);
268 }
269
270 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
271 {
272   return pthread_mutex_destroy(__m);
273 }
274
275 // Condition Variable
276 int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
277 {
278   return pthread_cond_signal(__cv);
279 }
280
281 int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
282 {
283   return pthread_cond_broadcast(__cv);
284 }
285
286 int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
287 {
288   return pthread_cond_wait(__cv, __m);
289 }
290
291 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
292                                timespec *__ts)
293 {
294   return pthread_cond_timedwait(__cv, __m, __ts);
295 }
296
297 int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
298 {
299   return pthread_cond_destroy(__cv);
300 }
301
302 // Execute once
303 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
304                           void (*init_routine)(void)) {
305   return pthread_once(flag, init_routine);
306 }
307
308 // Thread id
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)
311 {
312   return pthread_equal(t1, t2) != 0;
313 }
314
315 // Returns non-zero if t1 < t2, otherwise 0
316 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
317 {
318   return t1 < t2;
319 }
320
321 // Thread
322 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
323   return *__t == 0;
324 }
325
326 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
327                            void *__arg)
328 {
329   return pthread_create(__t, 0, __func, __arg);
330 }
331
332 __libcpp_thread_id __libcpp_thread_get_current_id()
333 {
334   return pthread_self();
335 }
336
337 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
338 {
339   return *__t;
340 }
341
342 int __libcpp_thread_join(__libcpp_thread_t *__t)
343 {
344   return pthread_join(*__t, 0);
345 }
346
347 int __libcpp_thread_detach(__libcpp_thread_t *__t)
348 {
349   return pthread_detach(*__t);
350 }
351
352 void __libcpp_thread_yield()
353 {
354   sched_yield();
355 }
356
357 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
358 {
359    using namespace chrono;
360    seconds __s = duration_cast<seconds>(__ns);
361    timespec __ts;
362    typedef decltype(__ts.tv_sec) ts_sec;
363    _LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits<ts_sec>::max();
364
365    if (__s.count() < __ts_sec_max)
366    {
367      __ts.tv_sec = static_cast<ts_sec>(__s.count());
368      __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
369    }
370    else
371    {
372      __ts.tv_sec = __ts_sec_max;
373      __ts.tv_nsec = 999999999; // (10^9 - 1)
374    }
375
376    while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
377 }
378
379 // Thread local storage
380 int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
381 {
382   return pthread_key_create(__key, __at_exit);
383 }
384
385 void *__libcpp_tls_get(__libcpp_tls_key __key)
386 {
387   return pthread_getspecific(__key);
388 }
389
390 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
391 {
392     return pthread_setspecific(__key, __p);
393 }
394
395 #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
396
397 class _LIBCPP_TYPE_VIS thread;
398 class _LIBCPP_TYPE_VIS __thread_id;
399
400 namespace this_thread
401 {
402
403 _LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
404
405 }  // this_thread
406
407 template<> struct hash<__thread_id>;
408
409 class _LIBCPP_TEMPLATE_VIS __thread_id
410 {
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_;
415
416 public:
417     _LIBCPP_INLINE_VISIBILITY
418     __thread_id() _NOEXCEPT : __id_(0) {}
419
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_);
426         }
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_);
436         }
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
442         {return   __y < __x ;}
443     friend _LIBCPP_INLINE_VISIBILITY
444         bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
445         {return !(__x < __y);}
446
447     _LIBCPP_INLINE_VISIBILITY
448     void __reset() { __id_ = 0; }
449     
450     template<class _CharT, class _Traits>
451     friend
452     _LIBCPP_INLINE_VISIBILITY
453     basic_ostream<_CharT, _Traits>&
454     operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
455
456 private:
457     _LIBCPP_INLINE_VISIBILITY
458     __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
459
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>;
463 };
464
465 namespace this_thread
466 {
467
468 inline _LIBCPP_INLINE_VISIBILITY
469 __thread_id
470 get_id() _NOEXCEPT
471 {
472     return __libcpp_thread_get_current_id();
473 }
474
475 }  // this_thread
476
477 _LIBCPP_END_NAMESPACE_STD
478
479 _LIBCPP_POP_MACROS
480
481 #endif // !_LIBCPP_HAS_NO_THREADS
482
483 #endif // _LIBCPP_THREADING_SUPPORT