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