1c7e4239fSAsiri Rathnayake// -*- C++ -*-
2c7e4239fSAsiri Rathnayake//===----------------------------------------------------------------------===//
3c7e4239fSAsiri Rathnayake//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7c7e4239fSAsiri Rathnayake//
8c7e4239fSAsiri Rathnayake//===----------------------------------------------------------------------===//
9c7e4239fSAsiri Rathnayake
10c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_THREADING_SUPPORT
11c7e4239fSAsiri Rathnayake#define _LIBCPP_THREADING_SUPPORT
12c7e4239fSAsiri Rathnayake
13c7e4239fSAsiri Rathnayake#include <__config>
1454a987e1SAsiri Rathnayake#include <chrono>
152b1d4254SMarshall Clow#include <iosfwd>
1654a987e1SAsiri Rathnayake#include <errno.h>
17c7e4239fSAsiri Rathnayake
18c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
19c7e4239fSAsiri Rathnayake#pragma GCC system_header
20c7e4239fSAsiri Rathnayake#endif
21c7e4239fSAsiri Rathnayake
2200f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
233cf2f7bcSAsiri Rathnayake# include <__external_threading>
2400f6beaeSEric Fiselier#elif !defined(_LIBCPP_HAS_NO_THREADS)
25790e10f6SSaleem Abdulrasool
2600f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
27c7e4239fSAsiri Rathnayake# include <pthread.h>
28c7e4239fSAsiri Rathnayake# include <sched.h>
29*ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11)
30*ab9aefeeSPetr Hosek# include <threads.h>
31790e10f6SSaleem Abdulrasool#endif
32c7e4239fSAsiri Rathnayake
332a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
342a129dc3SPeter Collingbourne    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
352a129dc3SPeter Collingbourne    defined(_LIBCPP_HAS_THREAD_API_WIN32)
362a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
372a129dc3SPeter Collingbourne#else
382a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
392a129dc3SPeter Collingbourne#endif
402a129dc3SPeter Collingbourne
4183dca5c3SDimitry Andric#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
4283dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
4383dca5c3SDimitry Andric#else
4483dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
4583dca5c3SDimitry Andric#endif
4683dca5c3SDimitry Andric
47696630eaSMarshall Clowtypedef ::timespec __libcpp_timespec_t;
48696630eaSMarshall Clow#endif // !defined(_LIBCPP_HAS_NO_THREADS)
49696630eaSMarshall Clow
50696630eaSMarshall Clow_LIBCPP_PUSH_MACROS
51696630eaSMarshall Clow#include <__undef_macros>
52696630eaSMarshall Clow
53c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD
54c7e4239fSAsiri Rathnayake
55696630eaSMarshall Clow#if !defined(_LIBCPP_HAS_NO_THREADS)
56696630eaSMarshall Clow
572a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
58c7e4239fSAsiri Rathnayake// Mutex
59c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t;
608c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
61c7e4239fSAsiri Rathnayake
6258a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t;
6358a0dceeSSaleem Abdulrasool
64790e10f6SSaleem Abdulrasool// Condition Variable
65790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t;
66790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
67790e10f6SSaleem Abdulrasool
68205d7d3fSAsiri Rathnayake// Execute once
69205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag;
70205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
71205d7d3fSAsiri Rathnayake
72205d7d3fSAsiri Rathnayake// Thread id
73790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_id;
74790e10f6SSaleem Abdulrasool
75790e10f6SSaleem Abdulrasool// Thread
76af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U
77af762e91SAsiri Rathnayake
78790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t;
79790e10f6SSaleem Abdulrasool
80cac6d217SFangrui Song// Thread Local Storage
81790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key;
826d7d0becSSaleem Abdulrasool
836d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC
84*ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11)
85*ab9aefeeSPetr Hosek// Mutex
86*ab9aefeeSPetr Hosektypedef mtx_t __libcpp_mutex_t;
87*ab9aefeeSPetr Hosek// mtx_t is a struct so using {} for initialization is valid.
88*ab9aefeeSPetr Hosek#define _LIBCPP_MUTEX_INITIALIZER {}
89*ab9aefeeSPetr Hosek
90*ab9aefeeSPetr Hosektypedef mtx_t __libcpp_recursive_mutex_t;
91*ab9aefeeSPetr Hosek
92*ab9aefeeSPetr Hosek// Condition Variable
93*ab9aefeeSPetr Hosektypedef cnd_t __libcpp_condvar_t;
94*ab9aefeeSPetr Hosek// cnd_t is a struct so using {} for initialization is valid.
95*ab9aefeeSPetr Hosek#define _LIBCPP_CONDVAR_INITIALIZER {}
96*ab9aefeeSPetr Hosek
97*ab9aefeeSPetr Hosek// Execute once
98*ab9aefeeSPetr Hosektypedef once_flag __libcpp_exec_once_flag;
99*ab9aefeeSPetr Hosek#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT
100*ab9aefeeSPetr Hosek
101*ab9aefeeSPetr Hosek// Thread id
102*ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_id;
103*ab9aefeeSPetr Hosek
104*ab9aefeeSPetr Hosek// Thread
105*ab9aefeeSPetr Hosek#define _LIBCPP_NULL_THREAD 0U
106*ab9aefeeSPetr Hosek
107*ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_t;
108*ab9aefeeSPetr Hosek
109*ab9aefeeSPetr Hosek// Thread Local Storage
110*ab9aefeeSPetr Hosektypedef tss_t __libcpp_tls_key;
111*ab9aefeeSPetr Hosek
112*ab9aefeeSPetr Hosek#define _LIBCPP_TLS_DESTRUCTOR_CC
113e2b200b7SDavid Spickett#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
114ac15ae6dSPeter Collingbourne// Mutex
115ac15ae6dSPeter Collingbournetypedef void* __libcpp_mutex_t;
116ac15ae6dSPeter Collingbourne#define _LIBCPP_MUTEX_INITIALIZER 0
117ac15ae6dSPeter Collingbourne
118ac15ae6dSPeter Collingbourne#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
119ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[6];
120ac15ae6dSPeter Collingbourne#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
121ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[5];
122ac15ae6dSPeter Collingbourne#else
123ac15ae6dSPeter Collingbourne# error Unsupported architecture
124ac15ae6dSPeter Collingbourne#endif
1256d7d0becSSaleem Abdulrasool
1266d7d0becSSaleem Abdulrasool// Condition Variable
127ac15ae6dSPeter Collingbournetypedef void* __libcpp_condvar_t;
128ac15ae6dSPeter Collingbourne#define _LIBCPP_CONDVAR_INITIALIZER 0
1296d7d0becSSaleem Abdulrasool
1306d7d0becSSaleem Abdulrasool// Execute Once
131ac15ae6dSPeter Collingbournetypedef void* __libcpp_exec_once_flag;
132ac15ae6dSPeter Collingbourne#define _LIBCPP_EXEC_ONCE_INITIALIZER 0
1336d7d0becSSaleem Abdulrasool
1346d7d0becSSaleem Abdulrasool// Thread ID
135ac15ae6dSPeter Collingbournetypedef long __libcpp_thread_id;
1366d7d0becSSaleem Abdulrasool
1376d7d0becSSaleem Abdulrasool// Thread
138af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U
139af762e91SAsiri Rathnayake
140ac15ae6dSPeter Collingbournetypedef void* __libcpp_thread_t;
1416d7d0becSSaleem Abdulrasool
1426d7d0becSSaleem Abdulrasool// Thread Local Storage
143ac15ae6dSPeter Collingbournetypedef long __libcpp_tls_key;
1446d7d0becSSaleem Abdulrasool
145ac15ae6dSPeter Collingbourne#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
146e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
147790e10f6SSaleem Abdulrasool
148e2b200b7SDavid Spickett#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
149790e10f6SSaleem Abdulrasool// Mutex
1508c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
15158a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
15258a0dceeSSaleem Abdulrasool
15383dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
15458a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
15558a0dceeSSaleem Abdulrasool
15683dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
15708e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
15858a0dceeSSaleem Abdulrasool
15983dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
16058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
16158a0dceeSSaleem Abdulrasool
16258a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY
16358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
164790e10f6SSaleem Abdulrasool
16583dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1668c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m);
167790e10f6SSaleem Abdulrasool
16883dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
16908e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
170790e10f6SSaleem Abdulrasool
17183dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1728c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
173790e10f6SSaleem Abdulrasool
1748c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1758c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
1768c2bf45dSAsiri Rathnayake
1778c2bf45dSAsiri Rathnayake// Condition variable
1788c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1798c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
180790e10f6SSaleem Abdulrasool
1818c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1828c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
183790e10f6SSaleem Abdulrasool
18483dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1858c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
186790e10f6SSaleem Abdulrasool
18783dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
188790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
189cfdc7f0dSMikhail Maltsev                               __libcpp_timespec_t *__ts);
190790e10f6SSaleem Abdulrasool
1918c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1928c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
1938c2bf45dSAsiri Rathnayake
194205d7d3fSAsiri Rathnayake// Execute once
195205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
196205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
1974603460aSBruce Mitchener                          void (*init_routine)());
198205d7d3fSAsiri Rathnayake
199205d7d3fSAsiri Rathnayake// Thread id
2008c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2018c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
202790e10f6SSaleem Abdulrasool
2038c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2048c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
2058c2bf45dSAsiri Rathnayake
2068c2bf45dSAsiri Rathnayake// Thread
2078c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
208af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
209af762e91SAsiri Rathnayake
210af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
211790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
212790e10f6SSaleem Abdulrasool                           void *__arg);
213790e10f6SSaleem Abdulrasool
2148c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2158c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id();
216790e10f6SSaleem Abdulrasool
2178c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2188c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
219790e10f6SSaleem Abdulrasool
2208c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2218c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t);
222790e10f6SSaleem Abdulrasool
2238c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2248c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t);
225790e10f6SSaleem Abdulrasool
2268c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2278c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield();
2288c2bf45dSAsiri Rathnayake
22954a987e1SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2309e8a082dSJoerg Sonnenbergervoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
23154a987e1SAsiri Rathnayake
2328c2bf45dSAsiri Rathnayake// Thread local storage
2338c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2346d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key,
2356d7d0becSSaleem Abdulrasool                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
236790e10f6SSaleem Abdulrasool
2378c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2388c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key);
239790e10f6SSaleem Abdulrasool
2408c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
241205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
2428c2bf45dSAsiri Rathnayake
243e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
244e2b200b7SDavid Spickett
245ac15ae6dSPeter Collingbourne#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
246*ab9aefeeSPetr Hosek     defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
247*ab9aefeeSPetr Hosek
248*ab9aefeeSPetr Hoseknamespace __thread_detail {
249*ab9aefeeSPetr Hosek
250*ab9aefeeSPetr Hosekinline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns)
251*ab9aefeeSPetr Hosek{
252*ab9aefeeSPetr Hosek  using namespace chrono;
253*ab9aefeeSPetr Hosek  seconds __s = duration_cast<seconds>(__ns);
254*ab9aefeeSPetr Hosek  __libcpp_timespec_t __ts;
255*ab9aefeeSPetr Hosek  typedef decltype(__ts.tv_sec) __ts_sec;
256*ab9aefeeSPetr Hosek  const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max();
257*ab9aefeeSPetr Hosek
258*ab9aefeeSPetr Hosek  if (__s.count() < __ts_sec_max)
259*ab9aefeeSPetr Hosek  {
260*ab9aefeeSPetr Hosek    __ts.tv_sec = static_cast<__ts_sec>(__s.count());
261*ab9aefeeSPetr Hosek    __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
262*ab9aefeeSPetr Hosek  }
263*ab9aefeeSPetr Hosek  else
264*ab9aefeeSPetr Hosek  {
265*ab9aefeeSPetr Hosek    __ts.tv_sec = __ts_sec_max;
266*ab9aefeeSPetr Hosek    __ts.tv_nsec = 999999999; // (10^9 - 1)
267*ab9aefeeSPetr Hosek  }
268*ab9aefeeSPetr Hosek
269*ab9aefeeSPetr Hosek  return __ts;
270*ab9aefeeSPetr Hosek}
271*ab9aefeeSPetr Hosek
272*ab9aefeeSPetr Hosek}
273*ab9aefeeSPetr Hosek
274*ab9aefeeSPetr Hosek#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
2758c2bf45dSAsiri Rathnayake
27658a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
277c7e4239fSAsiri Rathnayake{
278c7e4239fSAsiri Rathnayake  pthread_mutexattr_t attr;
279c7e4239fSAsiri Rathnayake  int __ec = pthread_mutexattr_init(&attr);
280c7e4239fSAsiri Rathnayake  if (__ec)
281790e10f6SSaleem Abdulrasool    return __ec;
282790e10f6SSaleem Abdulrasool  __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
283790e10f6SSaleem Abdulrasool  if (__ec) {
284c7e4239fSAsiri Rathnayake    pthread_mutexattr_destroy(&attr);
285c7e4239fSAsiri Rathnayake    return __ec;
286c7e4239fSAsiri Rathnayake  }
287c7e4239fSAsiri Rathnayake  __ec = pthread_mutex_init(__m, &attr);
288790e10f6SSaleem Abdulrasool  if (__ec) {
289c7e4239fSAsiri Rathnayake    pthread_mutexattr_destroy(&attr);
290c7e4239fSAsiri Rathnayake    return __ec;
291c7e4239fSAsiri Rathnayake  }
292c7e4239fSAsiri Rathnayake  __ec = pthread_mutexattr_destroy(&attr);
293790e10f6SSaleem Abdulrasool  if (__ec) {
294c7e4239fSAsiri Rathnayake    pthread_mutex_destroy(__m);
295c7e4239fSAsiri Rathnayake    return __ec;
296c7e4239fSAsiri Rathnayake  }
297c7e4239fSAsiri Rathnayake  return 0;
298c7e4239fSAsiri Rathnayake}
299c7e4239fSAsiri Rathnayake
30058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
30158a0dceeSSaleem Abdulrasool{
30258a0dceeSSaleem Abdulrasool  return pthread_mutex_lock(__m);
30358a0dceeSSaleem Abdulrasool}
30458a0dceeSSaleem Abdulrasool
30508e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
30658a0dceeSSaleem Abdulrasool{
30708e1477cSEric Fiselier  return pthread_mutex_trylock(__m) == 0;
30858a0dceeSSaleem Abdulrasool}
30958a0dceeSSaleem Abdulrasool
31058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
31158a0dceeSSaleem Abdulrasool{
31258a0dceeSSaleem Abdulrasool  return pthread_mutex_unlock(__m);
31358a0dceeSSaleem Abdulrasool}
31458a0dceeSSaleem Abdulrasool
31558a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
31658a0dceeSSaleem Abdulrasool{
31758a0dceeSSaleem Abdulrasool  return pthread_mutex_destroy(__m);
31858a0dceeSSaleem Abdulrasool}
31958a0dceeSSaleem Abdulrasool
320c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m)
321c7e4239fSAsiri Rathnayake{
322c7e4239fSAsiri Rathnayake  return pthread_mutex_lock(__m);
323c7e4239fSAsiri Rathnayake}
324c7e4239fSAsiri Rathnayake
32508e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
326c7e4239fSAsiri Rathnayake{
32708e1477cSEric Fiselier  return pthread_mutex_trylock(__m) == 0;
328c7e4239fSAsiri Rathnayake}
329c7e4239fSAsiri Rathnayake
330c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
331c7e4239fSAsiri Rathnayake{
332c7e4239fSAsiri Rathnayake  return pthread_mutex_unlock(__m);
333c7e4239fSAsiri Rathnayake}
334c7e4239fSAsiri Rathnayake
335c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
336c7e4239fSAsiri Rathnayake{
337c7e4239fSAsiri Rathnayake  return pthread_mutex_destroy(__m);
338c7e4239fSAsiri Rathnayake}
339c7e4239fSAsiri Rathnayake
340790e10f6SSaleem Abdulrasool// Condition Variable
341c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
342c7e4239fSAsiri Rathnayake{
343c7e4239fSAsiri Rathnayake  return pthread_cond_signal(__cv);
344c7e4239fSAsiri Rathnayake}
345c7e4239fSAsiri Rathnayake
346c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
347c7e4239fSAsiri Rathnayake{
348c7e4239fSAsiri Rathnayake  return pthread_cond_broadcast(__cv);
349c7e4239fSAsiri Rathnayake}
350c7e4239fSAsiri Rathnayake
351c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
352c7e4239fSAsiri Rathnayake{
353c7e4239fSAsiri Rathnayake  return pthread_cond_wait(__cv, __m);
354c7e4239fSAsiri Rathnayake}
355c7e4239fSAsiri Rathnayake
356790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
357cfdc7f0dSMikhail Maltsev                               __libcpp_timespec_t *__ts)
358c7e4239fSAsiri Rathnayake{
359c7e4239fSAsiri Rathnayake  return pthread_cond_timedwait(__cv, __m, __ts);
360c7e4239fSAsiri Rathnayake}
361c7e4239fSAsiri Rathnayake
362c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
363c7e4239fSAsiri Rathnayake{
364c7e4239fSAsiri Rathnayake  return pthread_cond_destroy(__cv);
365c7e4239fSAsiri Rathnayake}
366c7e4239fSAsiri Rathnayake
367205d7d3fSAsiri Rathnayake// Execute once
368205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
3694603460aSBruce Mitchener                          void (*init_routine)()) {
370205d7d3fSAsiri Rathnayake  return pthread_once(flag, init_routine);
371205d7d3fSAsiri Rathnayake}
372205d7d3fSAsiri Rathnayake
373205d7d3fSAsiri Rathnayake// Thread id
374c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0
375c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
376c7e4239fSAsiri Rathnayake{
377c7e4239fSAsiri Rathnayake  return pthread_equal(t1, t2) != 0;
378c7e4239fSAsiri Rathnayake}
379c7e4239fSAsiri Rathnayake
380c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0
381c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
382c7e4239fSAsiri Rathnayake{
383c7e4239fSAsiri Rathnayake  return t1 < t2;
384c7e4239fSAsiri Rathnayake}
385c7e4239fSAsiri Rathnayake
386c7e4239fSAsiri Rathnayake// Thread
387af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
388af762e91SAsiri Rathnayake  return *__t == 0;
389af762e91SAsiri Rathnayake}
390af762e91SAsiri Rathnayake
391790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
392790e10f6SSaleem Abdulrasool                           void *__arg)
393c7e4239fSAsiri Rathnayake{
394c7e4239fSAsiri Rathnayake  return pthread_create(__t, 0, __func, __arg);
395c7e4239fSAsiri Rathnayake}
396c7e4239fSAsiri Rathnayake
397c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id()
398c7e4239fSAsiri Rathnayake{
399c7e4239fSAsiri Rathnayake  return pthread_self();
400c7e4239fSAsiri Rathnayake}
401c7e4239fSAsiri Rathnayake
402c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
403c7e4239fSAsiri Rathnayake{
404c7e4239fSAsiri Rathnayake  return *__t;
405c7e4239fSAsiri Rathnayake}
406c7e4239fSAsiri Rathnayake
407c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t)
408c7e4239fSAsiri Rathnayake{
409c7e4239fSAsiri Rathnayake  return pthread_join(*__t, 0);
410c7e4239fSAsiri Rathnayake}
411c7e4239fSAsiri Rathnayake
412c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t)
413c7e4239fSAsiri Rathnayake{
414c7e4239fSAsiri Rathnayake  return pthread_detach(*__t);
415c7e4239fSAsiri Rathnayake}
416c7e4239fSAsiri Rathnayake
417c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield()
418c7e4239fSAsiri Rathnayake{
419c7e4239fSAsiri Rathnayake  sched_yield();
420c7e4239fSAsiri Rathnayake}
421c7e4239fSAsiri Rathnayake
42254a987e1SAsiri Rathnayakevoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
42354a987e1SAsiri Rathnayake{
424*ab9aefeeSPetr Hosek   __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns);
42554a987e1SAsiri Rathnayake   while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
42654a987e1SAsiri Rathnayake}
42754a987e1SAsiri Rathnayake
428c7e4239fSAsiri Rathnayake// Thread local storage
4298c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
430c7e4239fSAsiri Rathnayake{
431c7e4239fSAsiri Rathnayake  return pthread_key_create(__key, __at_exit);
432c7e4239fSAsiri Rathnayake}
433c7e4239fSAsiri Rathnayake
4348c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key)
435c7e4239fSAsiri Rathnayake{
436c7e4239fSAsiri Rathnayake  return pthread_getspecific(__key);
437c7e4239fSAsiri Rathnayake}
438c7e4239fSAsiri Rathnayake
439205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
440c7e4239fSAsiri Rathnayake{
441205d7d3fSAsiri Rathnayake    return pthread_setspecific(__key, __p);
442c7e4239fSAsiri Rathnayake}
443c7e4239fSAsiri Rathnayake
444*ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11)
445*ab9aefeeSPetr Hosek
446*ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
447*ab9aefeeSPetr Hosek{
448*ab9aefeeSPetr Hosek  return mtx_init(__m, mtx_recursive) == thrd_success ? 0 : EINVAL;
449*ab9aefeeSPetr Hosek}
450*ab9aefeeSPetr Hosek
451*ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
452*ab9aefeeSPetr Hosek{
453*ab9aefeeSPetr Hosek  return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
454*ab9aefeeSPetr Hosek}
455*ab9aefeeSPetr Hosek
456*ab9aefeeSPetr Hosekbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
457*ab9aefeeSPetr Hosek{
458*ab9aefeeSPetr Hosek  return mtx_trylock(__m) == thrd_success;
459*ab9aefeeSPetr Hosek}
460*ab9aefeeSPetr Hosek
461*ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
462*ab9aefeeSPetr Hosek{
463*ab9aefeeSPetr Hosek  return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
464*ab9aefeeSPetr Hosek}
465*ab9aefeeSPetr Hosek
466*ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
467*ab9aefeeSPetr Hosek{
468*ab9aefeeSPetr Hosek  mtx_destroy(__m);
469*ab9aefeeSPetr Hosek  return 0;
470*ab9aefeeSPetr Hosek}
471*ab9aefeeSPetr Hosek
472*ab9aefeeSPetr Hosekint __libcpp_mutex_lock(__libcpp_mutex_t *__m)
473*ab9aefeeSPetr Hosek{
474*ab9aefeeSPetr Hosek  return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
475*ab9aefeeSPetr Hosek}
476*ab9aefeeSPetr Hosek
477*ab9aefeeSPetr Hosekbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
478*ab9aefeeSPetr Hosek{
479*ab9aefeeSPetr Hosek  return mtx_trylock(__m) == thrd_success;
480*ab9aefeeSPetr Hosek}
481*ab9aefeeSPetr Hosek
482*ab9aefeeSPetr Hosekint __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
483*ab9aefeeSPetr Hosek{
484*ab9aefeeSPetr Hosek  return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
485*ab9aefeeSPetr Hosek}
486*ab9aefeeSPetr Hosek
487*ab9aefeeSPetr Hosekint __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
488*ab9aefeeSPetr Hosek{
489*ab9aefeeSPetr Hosek  mtx_destroy(__m);
490*ab9aefeeSPetr Hosek  return 0;
491*ab9aefeeSPetr Hosek}
492*ab9aefeeSPetr Hosek
493*ab9aefeeSPetr Hosek// Condition Variable
494*ab9aefeeSPetr Hosekint __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
495*ab9aefeeSPetr Hosek{
496*ab9aefeeSPetr Hosek  return cnd_signal(__cv) == thrd_success ? 0 : EINVAL;
497*ab9aefeeSPetr Hosek}
498*ab9aefeeSPetr Hosek
499*ab9aefeeSPetr Hosekint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
500*ab9aefeeSPetr Hosek{
501*ab9aefeeSPetr Hosek  return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
502*ab9aefeeSPetr Hosek}
503*ab9aefeeSPetr Hosek
504*ab9aefeeSPetr Hosekint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
505*ab9aefeeSPetr Hosek{
506*ab9aefeeSPetr Hosek  return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
507*ab9aefeeSPetr Hosek}
508*ab9aefeeSPetr Hosek
509*ab9aefeeSPetr Hosekint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
510*ab9aefeeSPetr Hosek                               timespec *__ts)
511*ab9aefeeSPetr Hosek{
512*ab9aefeeSPetr Hosek  int __ec = cnd_timedwait(__cv, __m, __ts);
513*ab9aefeeSPetr Hosek  return __ec == thrd_timedout ? ETIMEDOUT : __ec;
514*ab9aefeeSPetr Hosek}
515*ab9aefeeSPetr Hosek
516*ab9aefeeSPetr Hosekint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
517*ab9aefeeSPetr Hosek{
518*ab9aefeeSPetr Hosek  cnd_destroy(__cv);
519*ab9aefeeSPetr Hosek  return 0;
520*ab9aefeeSPetr Hosek}
521*ab9aefeeSPetr Hosek
522*ab9aefeeSPetr Hosek// Execute once
523*ab9aefeeSPetr Hosekint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
524*ab9aefeeSPetr Hosek                          void (*init_routine)(void)) {
525*ab9aefeeSPetr Hosek  ::call_once(flag, init_routine);
526*ab9aefeeSPetr Hosek  return 0;
527*ab9aefeeSPetr Hosek}
528*ab9aefeeSPetr Hosek
529*ab9aefeeSPetr Hosek// Thread id
530*ab9aefeeSPetr Hosek// Returns non-zero if the thread ids are equal, otherwise 0
531*ab9aefeeSPetr Hosekbool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
532*ab9aefeeSPetr Hosek{
533*ab9aefeeSPetr Hosek  return thrd_equal(t1, t2) != 0;
534*ab9aefeeSPetr Hosek}
535*ab9aefeeSPetr Hosek
536*ab9aefeeSPetr Hosek// Returns non-zero if t1 < t2, otherwise 0
537*ab9aefeeSPetr Hosekbool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
538*ab9aefeeSPetr Hosek{
539*ab9aefeeSPetr Hosek  return t1 < t2;
540*ab9aefeeSPetr Hosek}
541*ab9aefeeSPetr Hosek
542*ab9aefeeSPetr Hosek// Thread
543*ab9aefeeSPetr Hosekbool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
544*ab9aefeeSPetr Hosek  return *__t == 0;
545*ab9aefeeSPetr Hosek}
546*ab9aefeeSPetr Hosek
547*ab9aefeeSPetr Hosekint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
548*ab9aefeeSPetr Hosek                           void *__arg)
549*ab9aefeeSPetr Hosek{
550*ab9aefeeSPetr Hosek  int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg);
551*ab9aefeeSPetr Hosek  return __ec == thrd_nomem ? ENOMEM : __ec;
552*ab9aefeeSPetr Hosek}
553*ab9aefeeSPetr Hosek
554*ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_current_id()
555*ab9aefeeSPetr Hosek{
556*ab9aefeeSPetr Hosek  return thrd_current();
557*ab9aefeeSPetr Hosek}
558*ab9aefeeSPetr Hosek
559*ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
560*ab9aefeeSPetr Hosek{
561*ab9aefeeSPetr Hosek  return *__t;
562*ab9aefeeSPetr Hosek}
563*ab9aefeeSPetr Hosek
564*ab9aefeeSPetr Hosekint __libcpp_thread_join(__libcpp_thread_t *__t)
565*ab9aefeeSPetr Hosek{
566*ab9aefeeSPetr Hosek  return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL;
567*ab9aefeeSPetr Hosek}
568*ab9aefeeSPetr Hosek
569*ab9aefeeSPetr Hosekint __libcpp_thread_detach(__libcpp_thread_t *__t)
570*ab9aefeeSPetr Hosek{
571*ab9aefeeSPetr Hosek  return thrd_detach(*__t) == thrd_success ? 0 : EINVAL;
572*ab9aefeeSPetr Hosek}
573*ab9aefeeSPetr Hosek
574*ab9aefeeSPetr Hosekvoid __libcpp_thread_yield()
575*ab9aefeeSPetr Hosek{
576*ab9aefeeSPetr Hosek  thrd_yield();
577*ab9aefeeSPetr Hosek}
578*ab9aefeeSPetr Hosek
579*ab9aefeeSPetr Hosekvoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
580*ab9aefeeSPetr Hosek{
581*ab9aefeeSPetr Hosek   __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns);
582*ab9aefeeSPetr Hosek  thrd_sleep(&__ts, nullptr);
583*ab9aefeeSPetr Hosek}
584*ab9aefeeSPetr Hosek
585*ab9aefeeSPetr Hosek// Thread local storage
586*ab9aefeeSPetr Hosekint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
587*ab9aefeeSPetr Hosek{
588*ab9aefeeSPetr Hosek  return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
589*ab9aefeeSPetr Hosek}
590*ab9aefeeSPetr Hosek
591*ab9aefeeSPetr Hosekvoid *__libcpp_tls_get(__libcpp_tls_key __key)
592*ab9aefeeSPetr Hosek{
593*ab9aefeeSPetr Hosek  return tss_get(__key);
594*ab9aefeeSPetr Hosek}
595*ab9aefeeSPetr Hosek
596*ab9aefeeSPetr Hosekint __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
597*ab9aefeeSPetr Hosek{
598*ab9aefeeSPetr Hosek  return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
599*ab9aefeeSPetr Hosek}
600*ab9aefeeSPetr Hosek
601*ab9aefeeSPetr Hosek#endif
602*ab9aefeeSPetr Hosek
60300f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
60400f6beaeSEric Fiselier
6052b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS thread;
6062b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS __thread_id;
6072b1d4254SMarshall Clow
6082b1d4254SMarshall Clownamespace this_thread
6092b1d4254SMarshall Clow{
6102b1d4254SMarshall Clow
6112b1d4254SMarshall Clow_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
6122b1d4254SMarshall Clow
6132b1d4254SMarshall Clow}  // this_thread
6142b1d4254SMarshall Clow
6152b1d4254SMarshall Clowtemplate<> struct hash<__thread_id>;
6162b1d4254SMarshall Clow
6172b1d4254SMarshall Clowclass _LIBCPP_TEMPLATE_VIS __thread_id
6182b1d4254SMarshall Clow{
6192b1d4254SMarshall Clow    // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
6202b1d4254SMarshall Clow    // NULL is the no-thread value on Darwin.  Someone needs to check
6212b1d4254SMarshall Clow    // on other platforms.  We assume 0 works everywhere for now.
6222b1d4254SMarshall Clow    __libcpp_thread_id __id_;
6232b1d4254SMarshall Clow
6242b1d4254SMarshall Clowpublic:
6252b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
6262b1d4254SMarshall Clow    __thread_id() _NOEXCEPT : __id_(0) {}
6272b1d4254SMarshall Clow
6282b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6292b1d4254SMarshall Clow        bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
6302e80d01fSMarshall Clow        { // don't pass id==0 to underlying routines
6312e80d01fSMarshall Clow        if (__x.__id_ == 0) return __y.__id_ == 0;
6322e80d01fSMarshall Clow        if (__y.__id_ == 0) return false;
6332e80d01fSMarshall Clow        return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
6342e80d01fSMarshall Clow        }
6352b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6362b1d4254SMarshall Clow        bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT
6372b1d4254SMarshall Clow        {return !(__x == __y);}
6382b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6392b1d4254SMarshall Clow        bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT
6402e80d01fSMarshall Clow        { // id==0 is always less than any other thread_id
6412e80d01fSMarshall Clow        if (__x.__id_ == 0) return __y.__id_ != 0;
6422e80d01fSMarshall Clow        if (__y.__id_ == 0) return false;
6432e80d01fSMarshall Clow        return  __libcpp_thread_id_less(__x.__id_, __y.__id_);
6442e80d01fSMarshall Clow        }
6452b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6462b1d4254SMarshall Clow        bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT
6472b1d4254SMarshall Clow        {return !(__y < __x);}
6482b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6492b1d4254SMarshall Clow        bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT
6502b1d4254SMarshall Clow        {return   __y < __x ;}
6512b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6522b1d4254SMarshall Clow        bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
6532b1d4254SMarshall Clow        {return !(__x < __y);}
6542b1d4254SMarshall Clow
6552b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
6562e80d01fSMarshall Clow    void __reset() { __id_ = 0; }
6572b1d4254SMarshall Clow
6582b1d4254SMarshall Clow    template<class _CharT, class _Traits>
6592b1d4254SMarshall Clow    friend
6602b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
6612b1d4254SMarshall Clow    basic_ostream<_CharT, _Traits>&
6622b1d4254SMarshall Clow    operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
6632b1d4254SMarshall Clow
6642b1d4254SMarshall Clowprivate:
6652b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
6662b1d4254SMarshall Clow    __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
6672b1d4254SMarshall Clow
6682b1d4254SMarshall Clow    friend __thread_id this_thread::get_id() _NOEXCEPT;
6692b1d4254SMarshall Clow    friend class _LIBCPP_TYPE_VIS thread;
6702b1d4254SMarshall Clow    friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
6712b1d4254SMarshall Clow};
6722b1d4254SMarshall Clow
6732b1d4254SMarshall Clownamespace this_thread
6742b1d4254SMarshall Clow{
6752b1d4254SMarshall Clow
6762b1d4254SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
6772b1d4254SMarshall Clow__thread_id
6782b1d4254SMarshall Clowget_id() _NOEXCEPT
6792b1d4254SMarshall Clow{
6802b1d4254SMarshall Clow    return __libcpp_thread_get_current_id();
6812b1d4254SMarshall Clow}
6822b1d4254SMarshall Clow
6832b1d4254SMarshall Clow}  // this_thread
6842b1d4254SMarshall Clow
685696630eaSMarshall Clow#endif // !_LIBCPP_HAS_NO_THREADS
686696630eaSMarshall Clow
687c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD
688c7e4239fSAsiri Rathnayake
689a016efb1SEric Fiselier_LIBCPP_POP_MACROS
690a016efb1SEric Fiselier
691c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT
692