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