]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/libcxx/include/__threading_support
OpenSSL: Vendor import of OpenSSL 3.0.13
[FreeBSD/FreeBSD.git] / contrib / llvm-project / libcxx / include / __threading_support
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef _LIBCPP___THREADING_SUPPORT
11 #define _LIBCPP___THREADING_SUPPORT
12
13 #include <__availability>
14 #include <__chrono/convert_to_timespec.h>
15 #include <__chrono/duration.h>
16 #include <__config>
17 #include <__thread/poll_with_backoff.h>
18 #include <errno.h>
19
20 #ifdef __MVS__
21 # include <__support/ibm/nanosleep.h>
22 #endif
23
24 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
25 #  pragma GCC system_header
26 #endif
27
28 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
29 # include <__external_threading>
30 #elif !defined(_LIBCPP_HAS_NO_THREADS)
31
32 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
33 // Some platforms require <bits/atomic_wide_counter.h> in order for
34 // PTHREAD_COND_INITIALIZER to be expanded. Normally that would come
35 // in via <pthread.h>, but it's a non-modular header on those platforms,
36 // so libc++'s <math.h> usually absorbs atomic_wide_counter.h into the
37 // module with <math.h> and makes atomic_wide_counter.h invisible.
38 // Include <math.h> here to work around that.
39 # include <math.h>
40
41 # include <pthread.h>
42 # include <sched.h>
43 #elif defined(_LIBCPP_HAS_THREAD_API_C11)
44 # include <threads.h>
45 #endif
46
47 #if defined(_LIBCPP_HAS_THREAD_API_WIN32)
48 #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_EXPORTED_FROM_ABI
49 #else
50 #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
51 #endif
52
53 typedef ::timespec __libcpp_timespec_t;
54 #endif // !defined(_LIBCPP_HAS_NO_THREADS)
55
56 _LIBCPP_BEGIN_NAMESPACE_STD
57
58 #if !defined(_LIBCPP_HAS_NO_THREADS)
59
60 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
61 // Mutex
62 typedef pthread_mutex_t __libcpp_mutex_t;
63 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
64
65 typedef pthread_mutex_t __libcpp_recursive_mutex_t;
66
67 // Condition Variable
68 typedef pthread_cond_t __libcpp_condvar_t;
69 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
70
71 // Execute once
72 typedef pthread_once_t __libcpp_exec_once_flag;
73 #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
74
75 // Thread id
76 #if defined(__MVS__)
77   typedef unsigned long long __libcpp_thread_id;
78 #else
79   typedef pthread_t __libcpp_thread_id;
80 #endif
81
82 // Thread
83 #define _LIBCPP_NULL_THREAD ((__libcpp_thread_t()))
84 typedef pthread_t __libcpp_thread_t;
85
86 // Thread Local Storage
87 typedef pthread_key_t __libcpp_tls_key;
88
89 #define _LIBCPP_TLS_DESTRUCTOR_CC
90 #elif defined(_LIBCPP_HAS_THREAD_API_C11)
91 // Mutex
92 typedef mtx_t __libcpp_mutex_t;
93 // mtx_t is a struct so using {} for initialization is valid.
94 #define _LIBCPP_MUTEX_INITIALIZER {}
95
96 typedef mtx_t __libcpp_recursive_mutex_t;
97
98 // Condition Variable
99 typedef cnd_t __libcpp_condvar_t;
100 // cnd_t is a struct so using {} for initialization is valid.
101 #define _LIBCPP_CONDVAR_INITIALIZER {}
102
103 // Execute once
104 typedef once_flag __libcpp_exec_once_flag;
105 #define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT
106
107 // Thread id
108 typedef thrd_t __libcpp_thread_id;
109
110 // Thread
111 #define _LIBCPP_NULL_THREAD 0U
112
113 typedef thrd_t __libcpp_thread_t;
114
115 // Thread Local Storage
116 typedef tss_t __libcpp_tls_key;
117
118 #define _LIBCPP_TLS_DESTRUCTOR_CC
119 #elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
120 // Mutex
121 typedef void* __libcpp_mutex_t;
122 #define _LIBCPP_MUTEX_INITIALIZER 0
123
124 #if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
125 typedef void* __libcpp_recursive_mutex_t[6];
126 #elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
127 typedef void* __libcpp_recursive_mutex_t[5];
128 #else
129 # error Unsupported architecture
130 #endif
131
132 // Condition Variable
133 typedef void* __libcpp_condvar_t;
134 #define _LIBCPP_CONDVAR_INITIALIZER 0
135
136 // Execute Once
137 typedef void* __libcpp_exec_once_flag;
138 #define _LIBCPP_EXEC_ONCE_INITIALIZER 0
139
140 // Thread ID
141 typedef long __libcpp_thread_id;
142
143 // Thread
144 #define _LIBCPP_NULL_THREAD 0U
145
146 typedef void* __libcpp_thread_t;
147
148 // Thread Local Storage
149 typedef long __libcpp_tls_key;
150
151 #define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
152 #endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
153
154 #if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
155 // Mutex
156 _LIBCPP_THREAD_ABI_VISIBILITY
157 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
158
159 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
160 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
161
162 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
163 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
164
165 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
166 int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
167
168 _LIBCPP_THREAD_ABI_VISIBILITY
169 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
170
171 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
172 int __libcpp_mutex_lock(__libcpp_mutex_t *__m);
173
174 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
175 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
176
177 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
178 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
179
180 _LIBCPP_THREAD_ABI_VISIBILITY
181 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
182
183 // Condition variable
184 _LIBCPP_THREAD_ABI_VISIBILITY
185 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
186
187 _LIBCPP_THREAD_ABI_VISIBILITY
188 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
189
190 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
191 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
192
193 _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
194 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
195                                __libcpp_timespec_t *__ts);
196
197 _LIBCPP_THREAD_ABI_VISIBILITY
198 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
199
200 // Execute once
201 _LIBCPP_THREAD_ABI_VISIBILITY
202 int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
203                           void (*__init_routine)());
204
205 // Thread id
206 _LIBCPP_THREAD_ABI_VISIBILITY
207 bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
208
209 _LIBCPP_THREAD_ABI_VISIBILITY
210 bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
211
212 // Thread
213 _LIBCPP_THREAD_ABI_VISIBILITY
214 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
215
216 _LIBCPP_THREAD_ABI_VISIBILITY
217 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
218                            void *__arg);
219
220 _LIBCPP_THREAD_ABI_VISIBILITY
221 __libcpp_thread_id __libcpp_thread_get_current_id();
222
223 _LIBCPP_THREAD_ABI_VISIBILITY
224 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
225
226 _LIBCPP_THREAD_ABI_VISIBILITY
227 int __libcpp_thread_join(__libcpp_thread_t *__t);
228
229 _LIBCPP_THREAD_ABI_VISIBILITY
230 int __libcpp_thread_detach(__libcpp_thread_t *__t);
231
232 _LIBCPP_THREAD_ABI_VISIBILITY
233 void __libcpp_thread_yield();
234
235 _LIBCPP_THREAD_ABI_VISIBILITY
236 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
237
238 // Thread local storage
239 _LIBCPP_THREAD_ABI_VISIBILITY
240 int __libcpp_tls_create(__libcpp_tls_key* __key,
241                         void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
242
243 _LIBCPP_THREAD_ABI_VISIBILITY
244 void *__libcpp_tls_get(__libcpp_tls_key __key);
245
246 _LIBCPP_THREAD_ABI_VISIBILITY
247 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
248
249 #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
250
251 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
252
253 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
254 {
255   pthread_mutexattr_t __attr;
256   int __ec = pthread_mutexattr_init(&__attr);
257   if (__ec)
258     return __ec;
259   __ec = pthread_mutexattr_settype(&__attr, PTHREAD_MUTEX_RECURSIVE);
260   if (__ec) {
261     pthread_mutexattr_destroy(&__attr);
262     return __ec;
263   }
264   __ec = pthread_mutex_init(__m, &__attr);
265   if (__ec) {
266     pthread_mutexattr_destroy(&__attr);
267     return __ec;
268   }
269   __ec = pthread_mutexattr_destroy(&__attr);
270   if (__ec) {
271     pthread_mutex_destroy(__m);
272     return __ec;
273   }
274   return 0;
275 }
276
277 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
278 {
279   return pthread_mutex_lock(__m);
280 }
281
282 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
283 {
284   return pthread_mutex_trylock(__m) == 0;
285 }
286
287 int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
288 {
289   return pthread_mutex_unlock(__m);
290 }
291
292 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
293 {
294   return pthread_mutex_destroy(__m);
295 }
296
297 int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
298 {
299   return pthread_mutex_lock(__m);
300 }
301
302 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
303 {
304   return pthread_mutex_trylock(__m) == 0;
305 }
306
307 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
308 {
309   return pthread_mutex_unlock(__m);
310 }
311
312 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
313 {
314   return pthread_mutex_destroy(__m);
315 }
316
317 // Condition Variable
318 int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
319 {
320   return pthread_cond_signal(__cv);
321 }
322
323 int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
324 {
325   return pthread_cond_broadcast(__cv);
326 }
327
328 int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
329 {
330   return pthread_cond_wait(__cv, __m);
331 }
332
333 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
334                                __libcpp_timespec_t *__ts)
335 {
336   return pthread_cond_timedwait(__cv, __m, __ts);
337 }
338
339 int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
340 {
341   return pthread_cond_destroy(__cv);
342 }
343
344 // Execute once
345 int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
346                           void (*__init_routine)()) {
347   return pthread_once(__flag, __init_routine);
348 }
349
350 // Thread id
351 // Returns non-zero if the thread ids are equal, otherwise 0
352 bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
353 {
354   return __t1 == __t2;
355 }
356
357 // Returns non-zero if t1 < t2, otherwise 0
358 bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
359 {
360   return __t1 < __t2;
361 }
362
363 // Thread
364 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
365   return __libcpp_thread_get_id(__t) == 0;
366 }
367
368 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
369                            void *__arg)
370 {
371   return pthread_create(__t, nullptr, __func, __arg);
372 }
373
374 __libcpp_thread_id __libcpp_thread_get_current_id()
375 {
376   const __libcpp_thread_t __current_thread = pthread_self();
377   return __libcpp_thread_get_id(&__current_thread);
378 }
379
380 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
381 {
382 #if defined(__MVS__)
383   return __t->__;
384 #else
385   return *__t;
386 #endif
387 }
388
389 int __libcpp_thread_join(__libcpp_thread_t *__t)
390 {
391   return pthread_join(*__t, nullptr);
392 }
393
394 int __libcpp_thread_detach(__libcpp_thread_t *__t)
395 {
396   return pthread_detach(*__t);
397 }
398
399 void __libcpp_thread_yield()
400 {
401   sched_yield();
402 }
403
404 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
405 {
406    __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
407    while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
408 }
409
410 // Thread local storage
411 int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
412 {
413   return pthread_key_create(__key, __at_exit);
414 }
415
416 void *__libcpp_tls_get(__libcpp_tls_key __key)
417 {
418   return pthread_getspecific(__key);
419 }
420
421 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
422 {
423     return pthread_setspecific(__key, __p);
424 }
425
426 #elif defined(_LIBCPP_HAS_THREAD_API_C11)
427
428 int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
429 {
430   return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
431 }
432
433 int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
434 {
435   return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
436 }
437
438 bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
439 {
440   return mtx_trylock(__m) == thrd_success;
441 }
442
443 int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
444 {
445   return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
446 }
447
448 int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
449 {
450   mtx_destroy(__m);
451   return 0;
452 }
453
454 int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
455 {
456   return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
457 }
458
459 bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
460 {
461   return mtx_trylock(__m) == thrd_success;
462 }
463
464 int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
465 {
466   return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
467 }
468
469 int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
470 {
471   mtx_destroy(__m);
472   return 0;
473 }
474
475 // Condition Variable
476 int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
477 {
478   return cnd_signal(__cv) == thrd_success ? 0 : EINVAL;
479 }
480
481 int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
482 {
483   return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
484 }
485
486 int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
487 {
488   return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
489 }
490
491 int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
492                                timespec *__ts)
493 {
494   int __ec = cnd_timedwait(__cv, __m, __ts);
495   return __ec == thrd_timedout ? ETIMEDOUT : __ec;
496 }
497
498 int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
499 {
500   cnd_destroy(__cv);
501   return 0;
502 }
503
504 // Execute once
505 int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
506                           void (*init_routine)(void)) {
507   ::call_once(flag, init_routine);
508   return 0;
509 }
510
511 // Thread id
512 // Returns non-zero if the thread ids are equal, otherwise 0
513 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
514 {
515   return thrd_equal(t1, t2) != 0;
516 }
517
518 // Returns non-zero if t1 < t2, otherwise 0
519 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
520 {
521   return t1 < t2;
522 }
523
524 // Thread
525 bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
526   return __libcpp_thread_get_id(__t) == 0;
527 }
528
529 int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
530                            void *__arg)
531 {
532   int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg);
533   return __ec == thrd_nomem ? ENOMEM : __ec;
534 }
535
536 __libcpp_thread_id __libcpp_thread_get_current_id()
537 {
538   return thrd_current();
539 }
540
541 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
542 {
543   return *__t;
544 }
545
546 int __libcpp_thread_join(__libcpp_thread_t *__t)
547 {
548   return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL;
549 }
550
551 int __libcpp_thread_detach(__libcpp_thread_t *__t)
552 {
553   return thrd_detach(*__t) == thrd_success ? 0 : EINVAL;
554 }
555
556 void __libcpp_thread_yield()
557 {
558   thrd_yield();
559 }
560
561 void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
562 {
563    __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
564   thrd_sleep(&__ts, nullptr);
565 }
566
567 // Thread local storage
568 int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
569 {
570   return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
571 }
572
573 void *__libcpp_tls_get(__libcpp_tls_key __key)
574 {
575   return tss_get(__key);
576 }
577
578 int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
579 {
580   return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
581 }
582
583 #endif
584
585 #endif // !_LIBCPP_HAS_NO_THREADS
586
587 _LIBCPP_END_NAMESPACE_STD
588
589 #endif // _LIBCPP___THREADING_SUPPORT