146035553Spatrick// -*- C++ -*-
246035553Spatrick//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
10*4bdff4beSrobert#ifndef _LIBCPP___THREADING_SUPPORT
11*4bdff4beSrobert#define _LIBCPP___THREADING_SUPPORT
1246035553Spatrick
1376d0caaeSpatrick#include <__availability>
14*4bdff4beSrobert#include <__chrono/convert_to_timespec.h>
15*4bdff4beSrobert#include <__chrono/duration.h>
16*4bdff4beSrobert#include <__compare/ordering.h>
1746035553Spatrick#include <__config>
18*4bdff4beSrobert#include <__fwd/hash.h>
19*4bdff4beSrobert#include <__thread/poll_with_backoff.h>
2046035553Spatrick#include <errno.h>
2176d0caaeSpatrick#include <iosfwd>
2276d0caaeSpatrick#include <limits>
2376d0caaeSpatrick
2476d0caaeSpatrick#ifdef __MVS__
2576d0caaeSpatrick# include <__support/ibm/nanosleep.h>
2676d0caaeSpatrick#endif
2746035553Spatrick
2846035553Spatrick#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
2946035553Spatrick#  pragma GCC system_header
3046035553Spatrick#endif
3146035553Spatrick
3246035553Spatrick#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
3346035553Spatrick# include <__external_threading>
3446035553Spatrick#elif !defined(_LIBCPP_HAS_NO_THREADS)
3546035553Spatrick
3646035553Spatrick#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
3746035553Spatrick# include <pthread.h>
3846035553Spatrick# include <sched.h>
3946035553Spatrick#elif defined(_LIBCPP_HAS_THREAD_API_C11)
4046035553Spatrick# include <threads.h>
4146035553Spatrick#endif
4246035553Spatrick
4346035553Spatrick#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
4446035553Spatrick    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
4546035553Spatrick    defined(_LIBCPP_HAS_THREAD_API_WIN32)
4646035553Spatrick#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
4746035553Spatrick#else
4846035553Spatrick#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
4946035553Spatrick#endif
5046035553Spatrick
5146035553Spatrick#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
5246035553Spatrick#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
5346035553Spatrick#else
5446035553Spatrick#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
5546035553Spatrick#endif
5646035553Spatrick
5746035553Spatricktypedef ::timespec __libcpp_timespec_t;
5846035553Spatrick#endif // !defined(_LIBCPP_HAS_NO_THREADS)
5946035553Spatrick
6046035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
6146035553Spatrick
6246035553Spatrick#if !defined(_LIBCPP_HAS_NO_THREADS)
6346035553Spatrick
6446035553Spatrick#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
6546035553Spatrick// Mutex
6646035553Spatricktypedef pthread_mutex_t __libcpp_mutex_t;
6746035553Spatrick#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
6846035553Spatrick
6946035553Spatricktypedef pthread_mutex_t __libcpp_recursive_mutex_t;
7046035553Spatrick
7146035553Spatrick// Condition Variable
7246035553Spatricktypedef pthread_cond_t __libcpp_condvar_t;
7346035553Spatrick#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
7446035553Spatrick
7546035553Spatrick// Execute once
7646035553Spatricktypedef pthread_once_t __libcpp_exec_once_flag;
7746035553Spatrick#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
7846035553Spatrick
7946035553Spatrick// Thread id
8076d0caaeSpatrick#if defined(__MVS__)
8176d0caaeSpatrick  typedef unsigned long long __libcpp_thread_id;
8276d0caaeSpatrick#else
8346035553Spatrick  typedef pthread_t __libcpp_thread_id;
8476d0caaeSpatrick#endif
8546035553Spatrick
8646035553Spatrick// Thread
8776d0caaeSpatrick#define _LIBCPP_NULL_THREAD ((__libcpp_thread_t()))
8846035553Spatricktypedef pthread_t __libcpp_thread_t;
8946035553Spatrick
9046035553Spatrick// Thread Local Storage
9146035553Spatricktypedef pthread_key_t __libcpp_tls_key;
9246035553Spatrick
9346035553Spatrick#define _LIBCPP_TLS_DESTRUCTOR_CC
9446035553Spatrick#elif defined(_LIBCPP_HAS_THREAD_API_C11)
9546035553Spatrick// Mutex
9646035553Spatricktypedef mtx_t __libcpp_mutex_t;
9746035553Spatrick// mtx_t is a struct so using {} for initialization is valid.
9846035553Spatrick#define _LIBCPP_MUTEX_INITIALIZER {}
9946035553Spatrick
10046035553Spatricktypedef mtx_t __libcpp_recursive_mutex_t;
10146035553Spatrick
10246035553Spatrick// Condition Variable
10346035553Spatricktypedef cnd_t __libcpp_condvar_t;
10446035553Spatrick// cnd_t is a struct so using {} for initialization is valid.
10546035553Spatrick#define _LIBCPP_CONDVAR_INITIALIZER {}
10646035553Spatrick
10746035553Spatrick// Execute once
10846035553Spatricktypedef once_flag __libcpp_exec_once_flag;
10946035553Spatrick#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT
11046035553Spatrick
11146035553Spatrick// Thread id
11246035553Spatricktypedef thrd_t __libcpp_thread_id;
11346035553Spatrick
11446035553Spatrick// Thread
11546035553Spatrick#define _LIBCPP_NULL_THREAD 0U
11646035553Spatrick
11746035553Spatricktypedef thrd_t __libcpp_thread_t;
11846035553Spatrick
11946035553Spatrick// Thread Local Storage
12046035553Spatricktypedef tss_t __libcpp_tls_key;
12146035553Spatrick
12246035553Spatrick#define _LIBCPP_TLS_DESTRUCTOR_CC
12346035553Spatrick#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
12446035553Spatrick// Mutex
12546035553Spatricktypedef void* __libcpp_mutex_t;
12646035553Spatrick#define _LIBCPP_MUTEX_INITIALIZER 0
12746035553Spatrick
12846035553Spatrick#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
12946035553Spatricktypedef void* __libcpp_recursive_mutex_t[6];
13046035553Spatrick#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
13146035553Spatricktypedef void* __libcpp_recursive_mutex_t[5];
13246035553Spatrick#else
13346035553Spatrick# error Unsupported architecture
13446035553Spatrick#endif
13546035553Spatrick
13646035553Spatrick// Condition Variable
13746035553Spatricktypedef void* __libcpp_condvar_t;
13846035553Spatrick#define _LIBCPP_CONDVAR_INITIALIZER 0
13946035553Spatrick
14046035553Spatrick// Execute Once
14146035553Spatricktypedef void* __libcpp_exec_once_flag;
14246035553Spatrick#define _LIBCPP_EXEC_ONCE_INITIALIZER 0
14346035553Spatrick
14446035553Spatrick// Thread ID
14546035553Spatricktypedef long __libcpp_thread_id;
14646035553Spatrick
14746035553Spatrick// Thread
14846035553Spatrick#define _LIBCPP_NULL_THREAD 0U
14946035553Spatrick
15046035553Spatricktypedef void* __libcpp_thread_t;
15146035553Spatrick
15246035553Spatrick// Thread Local Storage
15346035553Spatricktypedef long __libcpp_tls_key;
15446035553Spatrick
15546035553Spatrick#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
15646035553Spatrick#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
15746035553Spatrick
15846035553Spatrick#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
15946035553Spatrick// Mutex
16046035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
16146035553Spatrickint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
16246035553Spatrick
16346035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
16446035553Spatrickint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
16546035553Spatrick
16646035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
16746035553Spatrickbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
16846035553Spatrick
16946035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
17046035553Spatrickint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
17146035553Spatrick
17246035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
17346035553Spatrickint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
17446035553Spatrick
17546035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
17646035553Spatrickint __libcpp_mutex_lock(__libcpp_mutex_t *__m);
17746035553Spatrick
17846035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
17946035553Spatrickbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
18046035553Spatrick
18146035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
18246035553Spatrickint __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
18346035553Spatrick
18446035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
18546035553Spatrickint __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
18646035553Spatrick
18746035553Spatrick// Condition variable
18846035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
18946035553Spatrickint __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
19046035553Spatrick
19146035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
19246035553Spatrickint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
19346035553Spatrick
19446035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
19546035553Spatrickint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
19646035553Spatrick
19746035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
19846035553Spatrickint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
19946035553Spatrick                               __libcpp_timespec_t *__ts);
20046035553Spatrick
20146035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
20246035553Spatrickint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
20346035553Spatrick
20446035553Spatrick// Execute once
20546035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
206*4bdff4beSrobertint __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
207*4bdff4beSrobert                          void (*__init_routine)());
20846035553Spatrick
20946035553Spatrick// Thread id
21046035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
211*4bdff4beSrobertbool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
21246035553Spatrick
21346035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
214*4bdff4beSrobertbool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
21546035553Spatrick
21646035553Spatrick// Thread
21746035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
21846035553Spatrickbool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
21946035553Spatrick
22046035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
22146035553Spatrickint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
22246035553Spatrick                           void *__arg);
22346035553Spatrick
22446035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
22546035553Spatrick__libcpp_thread_id __libcpp_thread_get_current_id();
22646035553Spatrick
22746035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
22846035553Spatrick__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
22946035553Spatrick
23046035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
23146035553Spatrickint __libcpp_thread_join(__libcpp_thread_t *__t);
23246035553Spatrick
23346035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
23446035553Spatrickint __libcpp_thread_detach(__libcpp_thread_t *__t);
23546035553Spatrick
23646035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
23746035553Spatrickvoid __libcpp_thread_yield();
23846035553Spatrick
23946035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
24046035553Spatrickvoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
24146035553Spatrick
24246035553Spatrick// Thread local storage
24346035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
24446035553Spatrickint __libcpp_tls_create(__libcpp_tls_key* __key,
24546035553Spatrick                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
24646035553Spatrick
24746035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
24846035553Spatrickvoid *__libcpp_tls_get(__libcpp_tls_key __key);
24946035553Spatrick
25046035553Spatrick_LIBCPP_THREAD_ABI_VISIBILITY
25146035553Spatrickint __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
25246035553Spatrick
25346035553Spatrick#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
25446035553Spatrick
25546035553Spatrick#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
25646035553Spatrick     defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
25746035553Spatrick
25846035553Spatrick#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
25946035553Spatrick
26046035553Spatrickint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
26146035553Spatrick{
26246035553Spatrick  pthread_mutexattr_t attr;
26346035553Spatrick  int __ec = pthread_mutexattr_init(&attr);
26446035553Spatrick  if (__ec)
26546035553Spatrick    return __ec;
26646035553Spatrick  __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
26746035553Spatrick  if (__ec) {
26846035553Spatrick    pthread_mutexattr_destroy(&attr);
26946035553Spatrick    return __ec;
27046035553Spatrick  }
27146035553Spatrick  __ec = pthread_mutex_init(__m, &attr);
27246035553Spatrick  if (__ec) {
27346035553Spatrick    pthread_mutexattr_destroy(&attr);
27446035553Spatrick    return __ec;
27546035553Spatrick  }
27646035553Spatrick  __ec = pthread_mutexattr_destroy(&attr);
27746035553Spatrick  if (__ec) {
27846035553Spatrick    pthread_mutex_destroy(__m);
27946035553Spatrick    return __ec;
28046035553Spatrick  }
28146035553Spatrick  return 0;
28246035553Spatrick}
28346035553Spatrick
28446035553Spatrickint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
28546035553Spatrick{
28646035553Spatrick  return pthread_mutex_lock(__m);
28746035553Spatrick}
28846035553Spatrick
28946035553Spatrickbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
29046035553Spatrick{
29146035553Spatrick  return pthread_mutex_trylock(__m) == 0;
29246035553Spatrick}
29346035553Spatrick
29476d0caaeSpatrickint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
29546035553Spatrick{
29646035553Spatrick  return pthread_mutex_unlock(__m);
29746035553Spatrick}
29846035553Spatrick
29946035553Spatrickint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
30046035553Spatrick{
30146035553Spatrick  return pthread_mutex_destroy(__m);
30246035553Spatrick}
30346035553Spatrick
30446035553Spatrickint __libcpp_mutex_lock(__libcpp_mutex_t *__m)
30546035553Spatrick{
30646035553Spatrick  return pthread_mutex_lock(__m);
30746035553Spatrick}
30846035553Spatrick
30946035553Spatrickbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
31046035553Spatrick{
31146035553Spatrick  return pthread_mutex_trylock(__m) == 0;
31246035553Spatrick}
31346035553Spatrick
31446035553Spatrickint __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
31546035553Spatrick{
31646035553Spatrick  return pthread_mutex_unlock(__m);
31746035553Spatrick}
31846035553Spatrick
31946035553Spatrickint __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
32046035553Spatrick{
32146035553Spatrick  return pthread_mutex_destroy(__m);
32246035553Spatrick}
32346035553Spatrick
32446035553Spatrick// Condition Variable
32546035553Spatrickint __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
32646035553Spatrick{
32746035553Spatrick  return pthread_cond_signal(__cv);
32846035553Spatrick}
32946035553Spatrick
33046035553Spatrickint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
33146035553Spatrick{
33246035553Spatrick  return pthread_cond_broadcast(__cv);
33346035553Spatrick}
33446035553Spatrick
33546035553Spatrickint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
33646035553Spatrick{
33746035553Spatrick  return pthread_cond_wait(__cv, __m);
33846035553Spatrick}
33946035553Spatrick
34046035553Spatrickint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
34146035553Spatrick                               __libcpp_timespec_t *__ts)
34246035553Spatrick{
34346035553Spatrick  return pthread_cond_timedwait(__cv, __m, __ts);
34446035553Spatrick}
34546035553Spatrick
34646035553Spatrickint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
34746035553Spatrick{
34846035553Spatrick  return pthread_cond_destroy(__cv);
34946035553Spatrick}
35046035553Spatrick
35146035553Spatrick// Execute once
352*4bdff4beSrobertint __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
353*4bdff4beSrobert                          void (*__init_routine)()) {
354*4bdff4beSrobert  return pthread_once(__flag, __init_routine);
35546035553Spatrick}
35646035553Spatrick
35746035553Spatrick// Thread id
35846035553Spatrick// Returns non-zero if the thread ids are equal, otherwise 0
359*4bdff4beSrobertbool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
36046035553Spatrick{
361*4bdff4beSrobert  return __t1 == __t2;
36246035553Spatrick}
36346035553Spatrick
36446035553Spatrick// Returns non-zero if t1 < t2, otherwise 0
365*4bdff4beSrobertbool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
36646035553Spatrick{
367*4bdff4beSrobert  return __t1 < __t2;
36846035553Spatrick}
36946035553Spatrick
37046035553Spatrick// Thread
37146035553Spatrickbool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
37276d0caaeSpatrick  return __libcpp_thread_get_id(__t) == 0;
37346035553Spatrick}
37446035553Spatrick
37546035553Spatrickint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
37646035553Spatrick                           void *__arg)
37746035553Spatrick{
37876d0caaeSpatrick  return pthread_create(__t, nullptr, __func, __arg);
37946035553Spatrick}
38046035553Spatrick
38146035553Spatrick__libcpp_thread_id __libcpp_thread_get_current_id()
38246035553Spatrick{
38376d0caaeSpatrick  const __libcpp_thread_t thread = pthread_self();
38476d0caaeSpatrick  return __libcpp_thread_get_id(&thread);
38546035553Spatrick}
38646035553Spatrick
38746035553Spatrick__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
38846035553Spatrick{
38976d0caaeSpatrick#if defined(__MVS__)
39076d0caaeSpatrick  return __t->__;
39176d0caaeSpatrick#else
39246035553Spatrick  return *__t;
39376d0caaeSpatrick#endif
39446035553Spatrick}
39546035553Spatrick
39646035553Spatrickint __libcpp_thread_join(__libcpp_thread_t *__t)
39746035553Spatrick{
39876d0caaeSpatrick  return pthread_join(*__t, nullptr);
39946035553Spatrick}
40046035553Spatrick
40146035553Spatrickint __libcpp_thread_detach(__libcpp_thread_t *__t)
40246035553Spatrick{
40346035553Spatrick  return pthread_detach(*__t);
40446035553Spatrick}
40546035553Spatrick
40646035553Spatrickvoid __libcpp_thread_yield()
40746035553Spatrick{
40846035553Spatrick  sched_yield();
40946035553Spatrick}
41046035553Spatrick
41146035553Spatrickvoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
41246035553Spatrick{
413*4bdff4beSrobert   __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
41446035553Spatrick   while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
41546035553Spatrick}
41646035553Spatrick
41746035553Spatrick// Thread local storage
41846035553Spatrickint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
41946035553Spatrick{
42046035553Spatrick  return pthread_key_create(__key, __at_exit);
42146035553Spatrick}
42246035553Spatrick
42346035553Spatrickvoid *__libcpp_tls_get(__libcpp_tls_key __key)
42446035553Spatrick{
42546035553Spatrick  return pthread_getspecific(__key);
42646035553Spatrick}
42746035553Spatrick
42846035553Spatrickint __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
42946035553Spatrick{
43046035553Spatrick    return pthread_setspecific(__key, __p);
43146035553Spatrick}
43246035553Spatrick
43346035553Spatrick#elif defined(_LIBCPP_HAS_THREAD_API_C11)
43446035553Spatrick
43546035553Spatrickint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
43646035553Spatrick{
43746035553Spatrick  return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
43846035553Spatrick}
43946035553Spatrick
44046035553Spatrickint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
44146035553Spatrick{
44246035553Spatrick  return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
44346035553Spatrick}
44446035553Spatrick
44546035553Spatrickbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
44646035553Spatrick{
44746035553Spatrick  return mtx_trylock(__m) == thrd_success;
44846035553Spatrick}
44946035553Spatrick
45076d0caaeSpatrickint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
45146035553Spatrick{
45246035553Spatrick  return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
45346035553Spatrick}
45446035553Spatrick
45546035553Spatrickint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
45646035553Spatrick{
45746035553Spatrick  mtx_destroy(__m);
45846035553Spatrick  return 0;
45946035553Spatrick}
46046035553Spatrick
46146035553Spatrickint __libcpp_mutex_lock(__libcpp_mutex_t *__m)
46246035553Spatrick{
46346035553Spatrick  return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
46446035553Spatrick}
46546035553Spatrick
46646035553Spatrickbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
46746035553Spatrick{
46846035553Spatrick  return mtx_trylock(__m) == thrd_success;
46946035553Spatrick}
47046035553Spatrick
47146035553Spatrickint __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
47246035553Spatrick{
47346035553Spatrick  return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
47446035553Spatrick}
47546035553Spatrick
47646035553Spatrickint __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
47746035553Spatrick{
47846035553Spatrick  mtx_destroy(__m);
47946035553Spatrick  return 0;
48046035553Spatrick}
48146035553Spatrick
48246035553Spatrick// Condition Variable
48346035553Spatrickint __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
48446035553Spatrick{
48546035553Spatrick  return cnd_signal(__cv) == thrd_success ? 0 : EINVAL;
48646035553Spatrick}
48746035553Spatrick
48846035553Spatrickint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
48946035553Spatrick{
49046035553Spatrick  return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
49146035553Spatrick}
49246035553Spatrick
49346035553Spatrickint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
49446035553Spatrick{
49546035553Spatrick  return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
49646035553Spatrick}
49746035553Spatrick
49846035553Spatrickint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
49946035553Spatrick                               timespec *__ts)
50046035553Spatrick{
50146035553Spatrick  int __ec = cnd_timedwait(__cv, __m, __ts);
50246035553Spatrick  return __ec == thrd_timedout ? ETIMEDOUT : __ec;
50346035553Spatrick}
50446035553Spatrick
50546035553Spatrickint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
50646035553Spatrick{
50746035553Spatrick  cnd_destroy(__cv);
50846035553Spatrick  return 0;
50946035553Spatrick}
51046035553Spatrick
51146035553Spatrick// Execute once
51246035553Spatrickint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
51346035553Spatrick                          void (*init_routine)(void)) {
51446035553Spatrick  ::call_once(flag, init_routine);
51546035553Spatrick  return 0;
51646035553Spatrick}
51746035553Spatrick
51846035553Spatrick// Thread id
51946035553Spatrick// Returns non-zero if the thread ids are equal, otherwise 0
52046035553Spatrickbool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
52146035553Spatrick{
52246035553Spatrick  return thrd_equal(t1, t2) != 0;
52346035553Spatrick}
52446035553Spatrick
52546035553Spatrick// Returns non-zero if t1 < t2, otherwise 0
52646035553Spatrickbool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
52746035553Spatrick{
52846035553Spatrick  return t1 < t2;
52946035553Spatrick}
53046035553Spatrick
53146035553Spatrick// Thread
53246035553Spatrickbool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
53376d0caaeSpatrick  return __libcpp_thread_get_id(__t) == 0;
53446035553Spatrick}
53546035553Spatrick
53646035553Spatrickint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
53746035553Spatrick                           void *__arg)
53846035553Spatrick{
53946035553Spatrick  int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg);
54046035553Spatrick  return __ec == thrd_nomem ? ENOMEM : __ec;
54146035553Spatrick}
54246035553Spatrick
54346035553Spatrick__libcpp_thread_id __libcpp_thread_get_current_id()
54446035553Spatrick{
54546035553Spatrick  return thrd_current();
54646035553Spatrick}
54746035553Spatrick
54846035553Spatrick__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
54946035553Spatrick{
55046035553Spatrick  return *__t;
55146035553Spatrick}
55246035553Spatrick
55346035553Spatrickint __libcpp_thread_join(__libcpp_thread_t *__t)
55446035553Spatrick{
55546035553Spatrick  return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL;
55646035553Spatrick}
55746035553Spatrick
55846035553Spatrickint __libcpp_thread_detach(__libcpp_thread_t *__t)
55946035553Spatrick{
56046035553Spatrick  return thrd_detach(*__t) == thrd_success ? 0 : EINVAL;
56146035553Spatrick}
56246035553Spatrick
56346035553Spatrickvoid __libcpp_thread_yield()
56446035553Spatrick{
56546035553Spatrick  thrd_yield();
56646035553Spatrick}
56746035553Spatrick
56846035553Spatrickvoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
56946035553Spatrick{
570*4bdff4beSrobert   __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
57146035553Spatrick  thrd_sleep(&__ts, nullptr);
57246035553Spatrick}
57346035553Spatrick
57446035553Spatrick// Thread local storage
57546035553Spatrickint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
57646035553Spatrick{
57746035553Spatrick  return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
57846035553Spatrick}
57946035553Spatrick
58046035553Spatrickvoid *__libcpp_tls_get(__libcpp_tls_key __key)
58146035553Spatrick{
58246035553Spatrick  return tss_get(__key);
58346035553Spatrick}
58446035553Spatrick
58546035553Spatrickint __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
58646035553Spatrick{
58746035553Spatrick  return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
58846035553Spatrick}
58946035553Spatrick
59046035553Spatrick#endif
59146035553Spatrick
592037e7968Spatrick
59346035553Spatrick#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
59446035553Spatrick
59546035553Spatrickclass _LIBCPP_TYPE_VIS thread;
59646035553Spatrickclass _LIBCPP_TYPE_VIS __thread_id;
59746035553Spatrick
59846035553Spatricknamespace this_thread
59946035553Spatrick{
60046035553Spatrick
60146035553Spatrick_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
60246035553Spatrick
603*4bdff4beSrobert} // namespace this_thread
60446035553Spatrick
60546035553Spatricktemplate<> struct hash<__thread_id>;
60646035553Spatrick
60746035553Spatrickclass _LIBCPP_TEMPLATE_VIS __thread_id
60846035553Spatrick{
60946035553Spatrick    // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
61046035553Spatrick    // NULL is the no-thread value on Darwin.  Someone needs to check
61146035553Spatrick    // on other platforms.  We assume 0 works everywhere for now.
61246035553Spatrick    __libcpp_thread_id __id_;
61346035553Spatrick
614*4bdff4beSrobert    static _LIBCPP_HIDE_FROM_ABI
615*4bdff4beSrobert        bool __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT
61646035553Spatrick        { // id==0 is always less than any other thread_id
61746035553Spatrick        if (__x.__id_ == 0) return __y.__id_ != 0;
61846035553Spatrick        if (__y.__id_ == 0) return false;
61946035553Spatrick        return  __libcpp_thread_id_less(__x.__id_, __y.__id_);
62046035553Spatrick        }
621*4bdff4beSrobert
622*4bdff4beSrobertpublic:
623*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY
624*4bdff4beSrobert    __thread_id() _NOEXCEPT : __id_(0) {}
62546035553Spatrick
62646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
62746035553Spatrick    void __reset() { __id_ = 0; }
62846035553Spatrick
629*4bdff4beSrobert    friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
630*4bdff4beSrobert#if _LIBCPP_STD_VER <= 17
631*4bdff4beSrobert    friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT;
632*4bdff4beSrobert#else // _LIBCPP_STD_VER <= 17
633*4bdff4beSrobert    friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept;
634*4bdff4beSrobert#endif // _LIBCPP_STD_VER <= 17
635*4bdff4beSrobert
63646035553Spatrick    template<class _CharT, class _Traits>
63746035553Spatrick    friend
63846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
63946035553Spatrick    basic_ostream<_CharT, _Traits>&
64046035553Spatrick    operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
64146035553Spatrick
64246035553Spatrickprivate:
64346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
64446035553Spatrick    __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
64546035553Spatrick
64646035553Spatrick    friend __thread_id this_thread::get_id() _NOEXCEPT;
64746035553Spatrick    friend class _LIBCPP_TYPE_VIS thread;
64846035553Spatrick    friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
64946035553Spatrick};
65046035553Spatrick
651*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
652*4bdff4beSrobertbool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT {
653*4bdff4beSrobert  // Don't pass id==0 to underlying routines
654*4bdff4beSrobert  if (__x.__id_ == 0)
655*4bdff4beSrobert    return __y.__id_ == 0;
656*4bdff4beSrobert  if (__y.__id_ == 0)
657*4bdff4beSrobert    return false;
658*4bdff4beSrobert  return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
659*4bdff4beSrobert}
660*4bdff4beSrobert
661*4bdff4beSrobert#if _LIBCPP_STD_VER <= 17
662*4bdff4beSrobert
663*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
664*4bdff4beSrobertbool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT {
665*4bdff4beSrobert  return !(__x == __y);
666*4bdff4beSrobert}
667*4bdff4beSrobert
668*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
669*4bdff4beSrobertbool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
670*4bdff4beSrobert  return __thread_id::__lt_impl(__x.__id_, __y.__id_);
671*4bdff4beSrobert}
672*4bdff4beSrobert
673*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
674*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
675*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }
676*4bdff4beSrobert
677*4bdff4beSrobert#else // _LIBCPP_STD_VER <= 17
678*4bdff4beSrobert
679*4bdff4beSrobertinline _LIBCPP_HIDE_FROM_ABI
680*4bdff4beSrobertstrong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept {
681*4bdff4beSrobert  if (__x == __y)
682*4bdff4beSrobert    return strong_ordering::equal;
683*4bdff4beSrobert  if (__thread_id::__lt_impl(__x, __y))
684*4bdff4beSrobert    return strong_ordering::less;
685*4bdff4beSrobert  return strong_ordering::greater;
686*4bdff4beSrobert}
687*4bdff4beSrobert
688*4bdff4beSrobert#endif // _LIBCPP_STD_VER <= 17
689*4bdff4beSrobert
69046035553Spatricknamespace this_thread
69146035553Spatrick{
69246035553Spatrick
69346035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
69446035553Spatrick__thread_id
69546035553Spatrickget_id() _NOEXCEPT
69646035553Spatrick{
69746035553Spatrick    return __libcpp_thread_get_current_id();
69846035553Spatrick}
69946035553Spatrick
700*4bdff4beSrobert} // namespace this_thread
70146035553Spatrick
70246035553Spatrick#endif // !_LIBCPP_HAS_NO_THREADS
70346035553Spatrick
70446035553Spatrick_LIBCPP_END_NAMESPACE_STD
70546035553Spatrick
706*4bdff4beSrobert#endif // _LIBCPP___THREADING_SUPPORT
707