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>
29790e10f6SSaleem Abdulrasool#endif
30c7e4239fSAsiri Rathnayake
312a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
322a129dc3SPeter Collingbourne    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
332a129dc3SPeter Collingbourne    defined(_LIBCPP_HAS_THREAD_API_WIN32)
342a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
352a129dc3SPeter Collingbourne#else
362a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
372a129dc3SPeter Collingbourne#endif
382a129dc3SPeter Collingbourne
3983dca5c3SDimitry Andric#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
4083dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
4183dca5c3SDimitry Andric#else
4283dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
4383dca5c3SDimitry Andric#endif
4483dca5c3SDimitry Andric
45696630eaSMarshall Clowtypedef ::timespec __libcpp_timespec_t;
46696630eaSMarshall Clow#endif // !defined(_LIBCPP_HAS_NO_THREADS)
47696630eaSMarshall Clow
48696630eaSMarshall Clow_LIBCPP_PUSH_MACROS
49696630eaSMarshall Clow#include <__undef_macros>
50696630eaSMarshall Clow
51c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD
52c7e4239fSAsiri Rathnayake
53696630eaSMarshall Clow#if !defined(_LIBCPP_HAS_NO_THREADS)
54696630eaSMarshall Clow
552a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
56c7e4239fSAsiri Rathnayake// Mutex
57c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t;
588c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
59c7e4239fSAsiri Rathnayake
6058a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t;
6158a0dceeSSaleem Abdulrasool
62790e10f6SSaleem Abdulrasool// Condition Variable
63790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t;
64790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
65790e10f6SSaleem Abdulrasool
66205d7d3fSAsiri Rathnayake// Execute once
67205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag;
68205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
69205d7d3fSAsiri Rathnayake
70205d7d3fSAsiri Rathnayake// Thread id
71790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_id;
72790e10f6SSaleem Abdulrasool
73790e10f6SSaleem Abdulrasool// Thread
74af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U
75af762e91SAsiri Rathnayake
76790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t;
77790e10f6SSaleem Abdulrasool
78cac6d217SFangrui Song// Thread Local Storage
79790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key;
806d7d0becSSaleem Abdulrasool
816d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC
82*e2b200b7SDavid Spickett#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
83ac15ae6dSPeter Collingbourne// Mutex
84ac15ae6dSPeter Collingbournetypedef void* __libcpp_mutex_t;
85ac15ae6dSPeter Collingbourne#define _LIBCPP_MUTEX_INITIALIZER 0
86ac15ae6dSPeter Collingbourne
87ac15ae6dSPeter Collingbourne#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
88ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[6];
89ac15ae6dSPeter Collingbourne#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
90ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[5];
91ac15ae6dSPeter Collingbourne#else
92ac15ae6dSPeter Collingbourne# error Unsupported architecture
93ac15ae6dSPeter Collingbourne#endif
946d7d0becSSaleem Abdulrasool
956d7d0becSSaleem Abdulrasool// Condition Variable
96ac15ae6dSPeter Collingbournetypedef void* __libcpp_condvar_t;
97ac15ae6dSPeter Collingbourne#define _LIBCPP_CONDVAR_INITIALIZER 0
986d7d0becSSaleem Abdulrasool
996d7d0becSSaleem Abdulrasool// Execute Once
100ac15ae6dSPeter Collingbournetypedef void* __libcpp_exec_once_flag;
101ac15ae6dSPeter Collingbourne#define _LIBCPP_EXEC_ONCE_INITIALIZER 0
1026d7d0becSSaleem Abdulrasool
1036d7d0becSSaleem Abdulrasool// Thread ID
104ac15ae6dSPeter Collingbournetypedef long __libcpp_thread_id;
1056d7d0becSSaleem Abdulrasool
1066d7d0becSSaleem Abdulrasool// Thread
107af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U
108af762e91SAsiri Rathnayake
109ac15ae6dSPeter Collingbournetypedef void* __libcpp_thread_t;
1106d7d0becSSaleem Abdulrasool
1116d7d0becSSaleem Abdulrasool// Thread Local Storage
112ac15ae6dSPeter Collingbournetypedef long __libcpp_tls_key;
1136d7d0becSSaleem Abdulrasool
114ac15ae6dSPeter Collingbourne#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
115*e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
116790e10f6SSaleem Abdulrasool
117*e2b200b7SDavid Spickett#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
118790e10f6SSaleem Abdulrasool// Mutex
1198c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
12058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
12158a0dceeSSaleem Abdulrasool
12283dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
12358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
12458a0dceeSSaleem Abdulrasool
12583dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
12608e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
12758a0dceeSSaleem Abdulrasool
12883dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
12958a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
13058a0dceeSSaleem Abdulrasool
13158a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY
13258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
133790e10f6SSaleem Abdulrasool
13483dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1358c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m);
136790e10f6SSaleem Abdulrasool
13783dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
13808e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
139790e10f6SSaleem Abdulrasool
14083dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1418c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
142790e10f6SSaleem Abdulrasool
1438c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1448c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
1458c2bf45dSAsiri Rathnayake
1468c2bf45dSAsiri Rathnayake// Condition variable
1478c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1488c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
149790e10f6SSaleem Abdulrasool
1508c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1518c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
152790e10f6SSaleem Abdulrasool
15383dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1548c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
155790e10f6SSaleem Abdulrasool
15683dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
157790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
158cfdc7f0dSMikhail Maltsev                               __libcpp_timespec_t *__ts);
159790e10f6SSaleem Abdulrasool
1608c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1618c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
1628c2bf45dSAsiri Rathnayake
163205d7d3fSAsiri Rathnayake// Execute once
164205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
165205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
1664603460aSBruce Mitchener                          void (*init_routine)());
167205d7d3fSAsiri Rathnayake
168205d7d3fSAsiri Rathnayake// Thread id
1698c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1708c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
171790e10f6SSaleem Abdulrasool
1728c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1738c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
1748c2bf45dSAsiri Rathnayake
1758c2bf45dSAsiri Rathnayake// Thread
1768c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
177af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
178af762e91SAsiri Rathnayake
179af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
180790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
181790e10f6SSaleem Abdulrasool                           void *__arg);
182790e10f6SSaleem Abdulrasool
1838c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1848c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id();
185790e10f6SSaleem Abdulrasool
1868c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1878c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
188790e10f6SSaleem Abdulrasool
1898c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1908c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t);
191790e10f6SSaleem Abdulrasool
1928c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1938c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t);
194790e10f6SSaleem Abdulrasool
1958c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1968c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield();
1978c2bf45dSAsiri Rathnayake
19854a987e1SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1999e8a082dSJoerg Sonnenbergervoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
20054a987e1SAsiri Rathnayake
2018c2bf45dSAsiri Rathnayake// Thread local storage
2028c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2036d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key,
2046d7d0becSSaleem Abdulrasool                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
205790e10f6SSaleem Abdulrasool
2068c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2078c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key);
208790e10f6SSaleem Abdulrasool
2098c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
210205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
2118c2bf45dSAsiri Rathnayake
212*e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
213*e2b200b7SDavid Spickett
214ac15ae6dSPeter Collingbourne#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
215ac15ae6dSPeter Collingbourne     defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \
216ac15ae6dSPeter Collingbourne    defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
2178c2bf45dSAsiri Rathnayake
21858a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
219c7e4239fSAsiri Rathnayake{
220c7e4239fSAsiri Rathnayake  pthread_mutexattr_t attr;
221c7e4239fSAsiri Rathnayake  int __ec = pthread_mutexattr_init(&attr);
222c7e4239fSAsiri Rathnayake  if (__ec)
223790e10f6SSaleem Abdulrasool    return __ec;
224790e10f6SSaleem Abdulrasool  __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
225790e10f6SSaleem Abdulrasool  if (__ec) {
226c7e4239fSAsiri Rathnayake    pthread_mutexattr_destroy(&attr);
227c7e4239fSAsiri Rathnayake    return __ec;
228c7e4239fSAsiri Rathnayake  }
229c7e4239fSAsiri Rathnayake  __ec = pthread_mutex_init(__m, &attr);
230790e10f6SSaleem Abdulrasool  if (__ec) {
231c7e4239fSAsiri Rathnayake    pthread_mutexattr_destroy(&attr);
232c7e4239fSAsiri Rathnayake    return __ec;
233c7e4239fSAsiri Rathnayake  }
234c7e4239fSAsiri Rathnayake  __ec = pthread_mutexattr_destroy(&attr);
235790e10f6SSaleem Abdulrasool  if (__ec) {
236c7e4239fSAsiri Rathnayake    pthread_mutex_destroy(__m);
237c7e4239fSAsiri Rathnayake    return __ec;
238c7e4239fSAsiri Rathnayake  }
239c7e4239fSAsiri Rathnayake  return 0;
240c7e4239fSAsiri Rathnayake}
241c7e4239fSAsiri Rathnayake
24258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
24358a0dceeSSaleem Abdulrasool{
24458a0dceeSSaleem Abdulrasool  return pthread_mutex_lock(__m);
24558a0dceeSSaleem Abdulrasool}
24658a0dceeSSaleem Abdulrasool
24708e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
24858a0dceeSSaleem Abdulrasool{
24908e1477cSEric Fiselier  return pthread_mutex_trylock(__m) == 0;
25058a0dceeSSaleem Abdulrasool}
25158a0dceeSSaleem Abdulrasool
25258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
25358a0dceeSSaleem Abdulrasool{
25458a0dceeSSaleem Abdulrasool  return pthread_mutex_unlock(__m);
25558a0dceeSSaleem Abdulrasool}
25658a0dceeSSaleem Abdulrasool
25758a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
25858a0dceeSSaleem Abdulrasool{
25958a0dceeSSaleem Abdulrasool  return pthread_mutex_destroy(__m);
26058a0dceeSSaleem Abdulrasool}
26158a0dceeSSaleem Abdulrasool
262c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m)
263c7e4239fSAsiri Rathnayake{
264c7e4239fSAsiri Rathnayake  return pthread_mutex_lock(__m);
265c7e4239fSAsiri Rathnayake}
266c7e4239fSAsiri Rathnayake
26708e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
268c7e4239fSAsiri Rathnayake{
26908e1477cSEric Fiselier  return pthread_mutex_trylock(__m) == 0;
270c7e4239fSAsiri Rathnayake}
271c7e4239fSAsiri Rathnayake
272c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
273c7e4239fSAsiri Rathnayake{
274c7e4239fSAsiri Rathnayake  return pthread_mutex_unlock(__m);
275c7e4239fSAsiri Rathnayake}
276c7e4239fSAsiri Rathnayake
277c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
278c7e4239fSAsiri Rathnayake{
279c7e4239fSAsiri Rathnayake  return pthread_mutex_destroy(__m);
280c7e4239fSAsiri Rathnayake}
281c7e4239fSAsiri Rathnayake
282790e10f6SSaleem Abdulrasool// Condition Variable
283c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
284c7e4239fSAsiri Rathnayake{
285c7e4239fSAsiri Rathnayake  return pthread_cond_signal(__cv);
286c7e4239fSAsiri Rathnayake}
287c7e4239fSAsiri Rathnayake
288c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
289c7e4239fSAsiri Rathnayake{
290c7e4239fSAsiri Rathnayake  return pthread_cond_broadcast(__cv);
291c7e4239fSAsiri Rathnayake}
292c7e4239fSAsiri Rathnayake
293c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
294c7e4239fSAsiri Rathnayake{
295c7e4239fSAsiri Rathnayake  return pthread_cond_wait(__cv, __m);
296c7e4239fSAsiri Rathnayake}
297c7e4239fSAsiri Rathnayake
298790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
299cfdc7f0dSMikhail Maltsev                               __libcpp_timespec_t *__ts)
300c7e4239fSAsiri Rathnayake{
301c7e4239fSAsiri Rathnayake  return pthread_cond_timedwait(__cv, __m, __ts);
302c7e4239fSAsiri Rathnayake}
303c7e4239fSAsiri Rathnayake
304c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
305c7e4239fSAsiri Rathnayake{
306c7e4239fSAsiri Rathnayake  return pthread_cond_destroy(__cv);
307c7e4239fSAsiri Rathnayake}
308c7e4239fSAsiri Rathnayake
309205d7d3fSAsiri Rathnayake// Execute once
310205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
3114603460aSBruce Mitchener                          void (*init_routine)()) {
312205d7d3fSAsiri Rathnayake  return pthread_once(flag, init_routine);
313205d7d3fSAsiri Rathnayake}
314205d7d3fSAsiri Rathnayake
315205d7d3fSAsiri Rathnayake// Thread id
316c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0
317c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
318c7e4239fSAsiri Rathnayake{
319c7e4239fSAsiri Rathnayake  return pthread_equal(t1, t2) != 0;
320c7e4239fSAsiri Rathnayake}
321c7e4239fSAsiri Rathnayake
322c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0
323c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
324c7e4239fSAsiri Rathnayake{
325c7e4239fSAsiri Rathnayake  return t1 < t2;
326c7e4239fSAsiri Rathnayake}
327c7e4239fSAsiri Rathnayake
328c7e4239fSAsiri Rathnayake// Thread
329af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
330af762e91SAsiri Rathnayake  return *__t == 0;
331af762e91SAsiri Rathnayake}
332af762e91SAsiri Rathnayake
333790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
334790e10f6SSaleem Abdulrasool                           void *__arg)
335c7e4239fSAsiri Rathnayake{
336c7e4239fSAsiri Rathnayake  return pthread_create(__t, 0, __func, __arg);
337c7e4239fSAsiri Rathnayake}
338c7e4239fSAsiri Rathnayake
339c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id()
340c7e4239fSAsiri Rathnayake{
341c7e4239fSAsiri Rathnayake  return pthread_self();
342c7e4239fSAsiri Rathnayake}
343c7e4239fSAsiri Rathnayake
344c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
345c7e4239fSAsiri Rathnayake{
346c7e4239fSAsiri Rathnayake  return *__t;
347c7e4239fSAsiri Rathnayake}
348c7e4239fSAsiri Rathnayake
349c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t)
350c7e4239fSAsiri Rathnayake{
351c7e4239fSAsiri Rathnayake  return pthread_join(*__t, 0);
352c7e4239fSAsiri Rathnayake}
353c7e4239fSAsiri Rathnayake
354c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t)
355c7e4239fSAsiri Rathnayake{
356c7e4239fSAsiri Rathnayake  return pthread_detach(*__t);
357c7e4239fSAsiri Rathnayake}
358c7e4239fSAsiri Rathnayake
359c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield()
360c7e4239fSAsiri Rathnayake{
361c7e4239fSAsiri Rathnayake  sched_yield();
362c7e4239fSAsiri Rathnayake}
363c7e4239fSAsiri Rathnayake
36454a987e1SAsiri Rathnayakevoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
36554a987e1SAsiri Rathnayake{
36654a987e1SAsiri Rathnayake   using namespace chrono;
36754a987e1SAsiri Rathnayake   seconds __s = duration_cast<seconds>(__ns);
368cfdc7f0dSMikhail Maltsev   __libcpp_timespec_t __ts;
36954a987e1SAsiri Rathnayake   typedef decltype(__ts.tv_sec) ts_sec;
37054a987e1SAsiri Rathnayake   _LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits<ts_sec>::max();
37154a987e1SAsiri Rathnayake
37254a987e1SAsiri Rathnayake   if (__s.count() < __ts_sec_max)
37354a987e1SAsiri Rathnayake   {
37454a987e1SAsiri Rathnayake     __ts.tv_sec = static_cast<ts_sec>(__s.count());
37554a987e1SAsiri Rathnayake     __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
37654a987e1SAsiri Rathnayake   }
37754a987e1SAsiri Rathnayake   else
37854a987e1SAsiri Rathnayake   {
37954a987e1SAsiri Rathnayake     __ts.tv_sec = __ts_sec_max;
38054a987e1SAsiri Rathnayake     __ts.tv_nsec = 999999999; // (10^9 - 1)
38154a987e1SAsiri Rathnayake   }
38254a987e1SAsiri Rathnayake
38354a987e1SAsiri Rathnayake   while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
38454a987e1SAsiri Rathnayake}
38554a987e1SAsiri Rathnayake
386c7e4239fSAsiri Rathnayake// Thread local storage
3878c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
388c7e4239fSAsiri Rathnayake{
389c7e4239fSAsiri Rathnayake  return pthread_key_create(__key, __at_exit);
390c7e4239fSAsiri Rathnayake}
391c7e4239fSAsiri Rathnayake
3928c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key)
393c7e4239fSAsiri Rathnayake{
394c7e4239fSAsiri Rathnayake  return pthread_getspecific(__key);
395c7e4239fSAsiri Rathnayake}
396c7e4239fSAsiri Rathnayake
397205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
398c7e4239fSAsiri Rathnayake{
399205d7d3fSAsiri Rathnayake    return pthread_setspecific(__key, __p);
400c7e4239fSAsiri Rathnayake}
401c7e4239fSAsiri Rathnayake
40200f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
40300f6beaeSEric Fiselier
4042b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS thread;
4052b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS __thread_id;
4062b1d4254SMarshall Clow
4072b1d4254SMarshall Clownamespace this_thread
4082b1d4254SMarshall Clow{
4092b1d4254SMarshall Clow
4102b1d4254SMarshall Clow_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
4112b1d4254SMarshall Clow
4122b1d4254SMarshall Clow}  // this_thread
4132b1d4254SMarshall Clow
4142b1d4254SMarshall Clowtemplate<> struct hash<__thread_id>;
4152b1d4254SMarshall Clow
4162b1d4254SMarshall Clowclass _LIBCPP_TEMPLATE_VIS __thread_id
4172b1d4254SMarshall Clow{
4182b1d4254SMarshall Clow    // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
4192b1d4254SMarshall Clow    // NULL is the no-thread value on Darwin.  Someone needs to check
4202b1d4254SMarshall Clow    // on other platforms.  We assume 0 works everywhere for now.
4212b1d4254SMarshall Clow    __libcpp_thread_id __id_;
4222b1d4254SMarshall Clow
4232b1d4254SMarshall Clowpublic:
4242b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
4252b1d4254SMarshall Clow    __thread_id() _NOEXCEPT : __id_(0) {}
4262b1d4254SMarshall Clow
4272b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
4282b1d4254SMarshall Clow        bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
4292e80d01fSMarshall Clow        { // don't pass id==0 to underlying routines
4302e80d01fSMarshall Clow        if (__x.__id_ == 0) return __y.__id_ == 0;
4312e80d01fSMarshall Clow        if (__y.__id_ == 0) return false;
4322e80d01fSMarshall Clow        return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
4332e80d01fSMarshall Clow        }
4342b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
4352b1d4254SMarshall Clow        bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT
4362b1d4254SMarshall Clow        {return !(__x == __y);}
4372b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
4382b1d4254SMarshall Clow        bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT
4392e80d01fSMarshall Clow        { // id==0 is always less than any other thread_id
4402e80d01fSMarshall Clow        if (__x.__id_ == 0) return __y.__id_ != 0;
4412e80d01fSMarshall Clow        if (__y.__id_ == 0) return false;
4422e80d01fSMarshall Clow        return  __libcpp_thread_id_less(__x.__id_, __y.__id_);
4432e80d01fSMarshall Clow        }
4442b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
4452b1d4254SMarshall Clow        bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT
4462b1d4254SMarshall Clow        {return !(__y < __x);}
4472b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
4482b1d4254SMarshall Clow        bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT
4492b1d4254SMarshall Clow        {return   __y < __x ;}
4502b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
4512b1d4254SMarshall Clow        bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
4522b1d4254SMarshall Clow        {return !(__x < __y);}
4532b1d4254SMarshall Clow
4542b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
4552e80d01fSMarshall Clow    void __reset() { __id_ = 0; }
4562b1d4254SMarshall Clow
4572b1d4254SMarshall Clow    template<class _CharT, class _Traits>
4582b1d4254SMarshall Clow    friend
4592b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
4602b1d4254SMarshall Clow    basic_ostream<_CharT, _Traits>&
4612b1d4254SMarshall Clow    operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
4622b1d4254SMarshall Clow
4632b1d4254SMarshall Clowprivate:
4642b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
4652b1d4254SMarshall Clow    __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
4662b1d4254SMarshall Clow
4672b1d4254SMarshall Clow    friend __thread_id this_thread::get_id() _NOEXCEPT;
4682b1d4254SMarshall Clow    friend class _LIBCPP_TYPE_VIS thread;
4692b1d4254SMarshall Clow    friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
4702b1d4254SMarshall Clow};
4712b1d4254SMarshall Clow
4722b1d4254SMarshall Clownamespace this_thread
4732b1d4254SMarshall Clow{
4742b1d4254SMarshall Clow
4752b1d4254SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
4762b1d4254SMarshall Clow__thread_id
4772b1d4254SMarshall Clowget_id() _NOEXCEPT
4782b1d4254SMarshall Clow{
4792b1d4254SMarshall Clow    return __libcpp_thread_get_current_id();
4802b1d4254SMarshall Clow}
4812b1d4254SMarshall Clow
4822b1d4254SMarshall Clow}  // this_thread
4832b1d4254SMarshall Clow
484696630eaSMarshall Clow#endif // !_LIBCPP_HAS_NO_THREADS
485696630eaSMarshall Clow
486c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD
487c7e4239fSAsiri Rathnayake
488a016efb1SEric Fiselier_LIBCPP_POP_MACROS
489a016efb1SEric Fiselier
490c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT
491