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>
1554a987e1SAsiri Rathnayake#include <errno.h>
16c7e4239fSAsiri Rathnayake
17c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
18c7e4239fSAsiri Rathnayake#pragma GCC system_header
19c7e4239fSAsiri Rathnayake#endif
20c7e4239fSAsiri Rathnayake
2100f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
223cf2f7bcSAsiri Rathnayake# include <__external_threading>
2300f6beaeSEric Fiselier#elif !defined(_LIBCPP_HAS_NO_THREADS)
24790e10f6SSaleem Abdulrasool
25*cfdc7f0dSMikhail Maltsevtypedef ::timespec __libcpp_timespec_t;
26*cfdc7f0dSMikhail Maltsev
2700f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
28c7e4239fSAsiri Rathnayake# include <pthread.h>
29c7e4239fSAsiri Rathnayake# include <sched.h>
30790e10f6SSaleem Abdulrasool#endif
31c7e4239fSAsiri Rathnayake
32a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS
33a016efb1SEric Fiselier#include <__undef_macros>
34a016efb1SEric Fiselier
352a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
362a129dc3SPeter Collingbourne    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
372a129dc3SPeter Collingbourne    defined(_LIBCPP_HAS_THREAD_API_WIN32)
382a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
392a129dc3SPeter Collingbourne#else
402a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
412a129dc3SPeter Collingbourne#endif
422a129dc3SPeter Collingbourne
4383dca5c3SDimitry Andric#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
4483dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
4583dca5c3SDimitry Andric#else
4683dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
4783dca5c3SDimitry Andric#endif
4883dca5c3SDimitry Andric
49c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD
50c7e4239fSAsiri Rathnayake
512a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
52c7e4239fSAsiri Rathnayake// Mutex
53c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t;
548c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
55c7e4239fSAsiri Rathnayake
5658a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t;
5758a0dceeSSaleem Abdulrasool
58790e10f6SSaleem Abdulrasool// Condition Variable
59790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t;
60790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
61790e10f6SSaleem Abdulrasool
62205d7d3fSAsiri Rathnayake// Execute once
63205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag;
64205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
65205d7d3fSAsiri Rathnayake
66205d7d3fSAsiri Rathnayake// Thread id
67790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_id;
68790e10f6SSaleem Abdulrasool
69790e10f6SSaleem Abdulrasool// Thread
70af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U
71af762e91SAsiri Rathnayake
72790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t;
73790e10f6SSaleem Abdulrasool
74cac6d217SFangrui Song// Thread Local Storage
75790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key;
766d7d0becSSaleem Abdulrasool
776d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC
786d7d0becSSaleem Abdulrasool#else
79ac15ae6dSPeter Collingbourne// Mutex
80ac15ae6dSPeter Collingbournetypedef void* __libcpp_mutex_t;
81ac15ae6dSPeter Collingbourne#define _LIBCPP_MUTEX_INITIALIZER 0
82ac15ae6dSPeter Collingbourne
83ac15ae6dSPeter Collingbourne#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
84ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[6];
85ac15ae6dSPeter Collingbourne#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
86ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[5];
87ac15ae6dSPeter Collingbourne#else
88ac15ae6dSPeter Collingbourne# error Unsupported architecture
89ac15ae6dSPeter Collingbourne#endif
906d7d0becSSaleem Abdulrasool
916d7d0becSSaleem Abdulrasool// Condition Variable
92ac15ae6dSPeter Collingbournetypedef void* __libcpp_condvar_t;
93ac15ae6dSPeter Collingbourne#define _LIBCPP_CONDVAR_INITIALIZER 0
946d7d0becSSaleem Abdulrasool
956d7d0becSSaleem Abdulrasool// Execute Once
96ac15ae6dSPeter Collingbournetypedef void* __libcpp_exec_once_flag;
97ac15ae6dSPeter Collingbourne#define _LIBCPP_EXEC_ONCE_INITIALIZER 0
986d7d0becSSaleem Abdulrasool
996d7d0becSSaleem Abdulrasool// Thread ID
100ac15ae6dSPeter Collingbournetypedef long __libcpp_thread_id;
1016d7d0becSSaleem Abdulrasool
1026d7d0becSSaleem Abdulrasool// Thread
103af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U
104af762e91SAsiri Rathnayake
105ac15ae6dSPeter Collingbournetypedef void* __libcpp_thread_t;
1066d7d0becSSaleem Abdulrasool
1076d7d0becSSaleem Abdulrasool// Thread Local Storage
108ac15ae6dSPeter Collingbournetypedef long __libcpp_tls_key;
1096d7d0becSSaleem Abdulrasool
110ac15ae6dSPeter Collingbourne#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
111790e10f6SSaleem Abdulrasool#endif
112790e10f6SSaleem Abdulrasool
113790e10f6SSaleem Abdulrasool// Mutex
1148c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
11558a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
11658a0dceeSSaleem Abdulrasool
11783dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
11858a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
11958a0dceeSSaleem Abdulrasool
12083dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
12108e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
12258a0dceeSSaleem Abdulrasool
12383dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
12458a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
12558a0dceeSSaleem Abdulrasool
12658a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY
12758a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
128790e10f6SSaleem Abdulrasool
12983dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1308c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m);
131790e10f6SSaleem Abdulrasool
13283dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
13308e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
134790e10f6SSaleem Abdulrasool
13583dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1368c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
137790e10f6SSaleem Abdulrasool
1388c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1398c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
1408c2bf45dSAsiri Rathnayake
1418c2bf45dSAsiri Rathnayake// Condition variable
1428c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1438c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
144790e10f6SSaleem Abdulrasool
1458c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1468c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
147790e10f6SSaleem Abdulrasool
14883dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1498c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
150790e10f6SSaleem Abdulrasool
15183dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
152790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
153*cfdc7f0dSMikhail Maltsev                               __libcpp_timespec_t *__ts);
154790e10f6SSaleem Abdulrasool
1558c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1568c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
1578c2bf45dSAsiri Rathnayake
158205d7d3fSAsiri Rathnayake// Execute once
159205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
160205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
161205d7d3fSAsiri Rathnayake                          void (*init_routine)(void));
162205d7d3fSAsiri Rathnayake
163205d7d3fSAsiri Rathnayake// Thread id
1648c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1658c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
166790e10f6SSaleem Abdulrasool
1678c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1688c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
1698c2bf45dSAsiri Rathnayake
1708c2bf45dSAsiri Rathnayake// Thread
1718c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
172af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
173af762e91SAsiri Rathnayake
174af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
175790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
176790e10f6SSaleem Abdulrasool                           void *__arg);
177790e10f6SSaleem Abdulrasool
1788c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1798c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id();
180790e10f6SSaleem Abdulrasool
1818c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1828c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
183790e10f6SSaleem Abdulrasool
1848c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1858c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t);
186790e10f6SSaleem Abdulrasool
1878c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1888c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t);
189790e10f6SSaleem Abdulrasool
1908c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1918c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield();
1928c2bf45dSAsiri Rathnayake
19354a987e1SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1949e8a082dSJoerg Sonnenbergervoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
19554a987e1SAsiri Rathnayake
1968c2bf45dSAsiri Rathnayake// Thread local storage
1978c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1986d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key,
1996d7d0becSSaleem Abdulrasool                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
200790e10f6SSaleem Abdulrasool
2018c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2028c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key);
203790e10f6SSaleem Abdulrasool
2048c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
205205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
2068c2bf45dSAsiri Rathnayake
207ac15ae6dSPeter Collingbourne#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
208ac15ae6dSPeter Collingbourne     defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \
209ac15ae6dSPeter Collingbourne    defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
2108c2bf45dSAsiri Rathnayake
21158a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
212c7e4239fSAsiri Rathnayake{
213c7e4239fSAsiri Rathnayake  pthread_mutexattr_t attr;
214c7e4239fSAsiri Rathnayake  int __ec = pthread_mutexattr_init(&attr);
215c7e4239fSAsiri Rathnayake  if (__ec)
216790e10f6SSaleem Abdulrasool    return __ec;
217790e10f6SSaleem Abdulrasool  __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
218790e10f6SSaleem Abdulrasool  if (__ec) {
219c7e4239fSAsiri Rathnayake    pthread_mutexattr_destroy(&attr);
220c7e4239fSAsiri Rathnayake    return __ec;
221c7e4239fSAsiri Rathnayake  }
222c7e4239fSAsiri Rathnayake  __ec = pthread_mutex_init(__m, &attr);
223790e10f6SSaleem Abdulrasool  if (__ec) {
224c7e4239fSAsiri Rathnayake    pthread_mutexattr_destroy(&attr);
225c7e4239fSAsiri Rathnayake    return __ec;
226c7e4239fSAsiri Rathnayake  }
227c7e4239fSAsiri Rathnayake  __ec = pthread_mutexattr_destroy(&attr);
228790e10f6SSaleem Abdulrasool  if (__ec) {
229c7e4239fSAsiri Rathnayake    pthread_mutex_destroy(__m);
230c7e4239fSAsiri Rathnayake    return __ec;
231c7e4239fSAsiri Rathnayake  }
232c7e4239fSAsiri Rathnayake  return 0;
233c7e4239fSAsiri Rathnayake}
234c7e4239fSAsiri Rathnayake
23558a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
23658a0dceeSSaleem Abdulrasool{
23758a0dceeSSaleem Abdulrasool  return pthread_mutex_lock(__m);
23858a0dceeSSaleem Abdulrasool}
23958a0dceeSSaleem Abdulrasool
24008e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
24158a0dceeSSaleem Abdulrasool{
24208e1477cSEric Fiselier  return pthread_mutex_trylock(__m) == 0;
24358a0dceeSSaleem Abdulrasool}
24458a0dceeSSaleem Abdulrasool
24558a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
24658a0dceeSSaleem Abdulrasool{
24758a0dceeSSaleem Abdulrasool  return pthread_mutex_unlock(__m);
24858a0dceeSSaleem Abdulrasool}
24958a0dceeSSaleem Abdulrasool
25058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
25158a0dceeSSaleem Abdulrasool{
25258a0dceeSSaleem Abdulrasool  return pthread_mutex_destroy(__m);
25358a0dceeSSaleem Abdulrasool}
25458a0dceeSSaleem Abdulrasool
255c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m)
256c7e4239fSAsiri Rathnayake{
257c7e4239fSAsiri Rathnayake  return pthread_mutex_lock(__m);
258c7e4239fSAsiri Rathnayake}
259c7e4239fSAsiri Rathnayake
26008e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
261c7e4239fSAsiri Rathnayake{
26208e1477cSEric Fiselier  return pthread_mutex_trylock(__m) == 0;
263c7e4239fSAsiri Rathnayake}
264c7e4239fSAsiri Rathnayake
265c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
266c7e4239fSAsiri Rathnayake{
267c7e4239fSAsiri Rathnayake  return pthread_mutex_unlock(__m);
268c7e4239fSAsiri Rathnayake}
269c7e4239fSAsiri Rathnayake
270c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
271c7e4239fSAsiri Rathnayake{
272c7e4239fSAsiri Rathnayake  return pthread_mutex_destroy(__m);
273c7e4239fSAsiri Rathnayake}
274c7e4239fSAsiri Rathnayake
275790e10f6SSaleem Abdulrasool// Condition Variable
276c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
277c7e4239fSAsiri Rathnayake{
278c7e4239fSAsiri Rathnayake  return pthread_cond_signal(__cv);
279c7e4239fSAsiri Rathnayake}
280c7e4239fSAsiri Rathnayake
281c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
282c7e4239fSAsiri Rathnayake{
283c7e4239fSAsiri Rathnayake  return pthread_cond_broadcast(__cv);
284c7e4239fSAsiri Rathnayake}
285c7e4239fSAsiri Rathnayake
286c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
287c7e4239fSAsiri Rathnayake{
288c7e4239fSAsiri Rathnayake  return pthread_cond_wait(__cv, __m);
289c7e4239fSAsiri Rathnayake}
290c7e4239fSAsiri Rathnayake
291790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
292*cfdc7f0dSMikhail Maltsev                               __libcpp_timespec_t *__ts)
293c7e4239fSAsiri Rathnayake{
294c7e4239fSAsiri Rathnayake  return pthread_cond_timedwait(__cv, __m, __ts);
295c7e4239fSAsiri Rathnayake}
296c7e4239fSAsiri Rathnayake
297c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
298c7e4239fSAsiri Rathnayake{
299c7e4239fSAsiri Rathnayake  return pthread_cond_destroy(__cv);
300c7e4239fSAsiri Rathnayake}
301c7e4239fSAsiri Rathnayake
302205d7d3fSAsiri Rathnayake// Execute once
303205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
304205d7d3fSAsiri Rathnayake                          void (*init_routine)(void)) {
305205d7d3fSAsiri Rathnayake  return pthread_once(flag, init_routine);
306205d7d3fSAsiri Rathnayake}
307205d7d3fSAsiri Rathnayake
308205d7d3fSAsiri Rathnayake// Thread id
309c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0
310c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
311c7e4239fSAsiri Rathnayake{
312c7e4239fSAsiri Rathnayake  return pthread_equal(t1, t2) != 0;
313c7e4239fSAsiri Rathnayake}
314c7e4239fSAsiri Rathnayake
315c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0
316c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
317c7e4239fSAsiri Rathnayake{
318c7e4239fSAsiri Rathnayake  return t1 < t2;
319c7e4239fSAsiri Rathnayake}
320c7e4239fSAsiri Rathnayake
321c7e4239fSAsiri Rathnayake// Thread
322af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
323af762e91SAsiri Rathnayake  return *__t == 0;
324af762e91SAsiri Rathnayake}
325af762e91SAsiri Rathnayake
326790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
327790e10f6SSaleem Abdulrasool                           void *__arg)
328c7e4239fSAsiri Rathnayake{
329c7e4239fSAsiri Rathnayake  return pthread_create(__t, 0, __func, __arg);
330c7e4239fSAsiri Rathnayake}
331c7e4239fSAsiri Rathnayake
332c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id()
333c7e4239fSAsiri Rathnayake{
334c7e4239fSAsiri Rathnayake  return pthread_self();
335c7e4239fSAsiri Rathnayake}
336c7e4239fSAsiri Rathnayake
337c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
338c7e4239fSAsiri Rathnayake{
339c7e4239fSAsiri Rathnayake  return *__t;
340c7e4239fSAsiri Rathnayake}
341c7e4239fSAsiri Rathnayake
342c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t)
343c7e4239fSAsiri Rathnayake{
344c7e4239fSAsiri Rathnayake  return pthread_join(*__t, 0);
345c7e4239fSAsiri Rathnayake}
346c7e4239fSAsiri Rathnayake
347c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t)
348c7e4239fSAsiri Rathnayake{
349c7e4239fSAsiri Rathnayake  return pthread_detach(*__t);
350c7e4239fSAsiri Rathnayake}
351c7e4239fSAsiri Rathnayake
352c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield()
353c7e4239fSAsiri Rathnayake{
354c7e4239fSAsiri Rathnayake  sched_yield();
355c7e4239fSAsiri Rathnayake}
356c7e4239fSAsiri Rathnayake
35754a987e1SAsiri Rathnayakevoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
35854a987e1SAsiri Rathnayake{
35954a987e1SAsiri Rathnayake   using namespace chrono;
36054a987e1SAsiri Rathnayake   seconds __s = duration_cast<seconds>(__ns);
361*cfdc7f0dSMikhail Maltsev   __libcpp_timespec_t __ts;
36254a987e1SAsiri Rathnayake   typedef decltype(__ts.tv_sec) ts_sec;
36354a987e1SAsiri Rathnayake   _LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits<ts_sec>::max();
36454a987e1SAsiri Rathnayake
36554a987e1SAsiri Rathnayake   if (__s.count() < __ts_sec_max)
36654a987e1SAsiri Rathnayake   {
36754a987e1SAsiri Rathnayake     __ts.tv_sec = static_cast<ts_sec>(__s.count());
36854a987e1SAsiri Rathnayake     __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
36954a987e1SAsiri Rathnayake   }
37054a987e1SAsiri Rathnayake   else
37154a987e1SAsiri Rathnayake   {
37254a987e1SAsiri Rathnayake     __ts.tv_sec = __ts_sec_max;
37354a987e1SAsiri Rathnayake     __ts.tv_nsec = 999999999; // (10^9 - 1)
37454a987e1SAsiri Rathnayake   }
37554a987e1SAsiri Rathnayake
37654a987e1SAsiri Rathnayake   while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
37754a987e1SAsiri Rathnayake}
37854a987e1SAsiri Rathnayake
379c7e4239fSAsiri Rathnayake// Thread local storage
3808c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
381c7e4239fSAsiri Rathnayake{
382c7e4239fSAsiri Rathnayake  return pthread_key_create(__key, __at_exit);
383c7e4239fSAsiri Rathnayake}
384c7e4239fSAsiri Rathnayake
3858c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key)
386c7e4239fSAsiri Rathnayake{
387c7e4239fSAsiri Rathnayake  return pthread_getspecific(__key);
388c7e4239fSAsiri Rathnayake}
389c7e4239fSAsiri Rathnayake
390205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
391c7e4239fSAsiri Rathnayake{
392205d7d3fSAsiri Rathnayake    return pthread_setspecific(__key, __p);
393c7e4239fSAsiri Rathnayake}
394c7e4239fSAsiri Rathnayake
39500f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
39600f6beaeSEric Fiselier
397c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD
398c7e4239fSAsiri Rathnayake
399a016efb1SEric Fiselier_LIBCPP_POP_MACROS
400a016efb1SEric Fiselier
40100f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_NO_THREADS
402c7e4239fSAsiri Rathnayake
403c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT
404