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> 142eadbc86SLouis Dionne#include <__availability> 1554a987e1SAsiri Rathnayake#include <chrono> 162b1d4254SMarshall Clow#include <iosfwd> 1754a987e1SAsiri Rathnayake#include <errno.h> 18c7e4239fSAsiri Rathnayake 196a8099e0SZbigniew Sarbinowski#ifdef __MVS__ 206a8099e0SZbigniew Sarbinowski# include <support/ibm/nanosleep.h> 216a8099e0SZbigniew Sarbinowski#endif 226a8099e0SZbigniew Sarbinowski 23c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER 24c7e4239fSAsiri Rathnayake#pragma GCC system_header 25c7e4239fSAsiri Rathnayake#endif 26c7e4239fSAsiri Rathnayake 2700f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 283cf2f7bcSAsiri Rathnayake# include <__external_threading> 2900f6beaeSEric Fiselier#elif !defined(_LIBCPP_HAS_NO_THREADS) 30790e10f6SSaleem Abdulrasool 3100f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 32c7e4239fSAsiri Rathnayake# include <pthread.h> 33c7e4239fSAsiri Rathnayake# include <sched.h> 3454fa9ecdSOlivier Giroux# ifdef __APPLE__ 3554fa9ecdSOlivier Giroux# define _LIBCPP_NO_NATIVE_SEMAPHORES 3654fa9ecdSOlivier Giroux# endif 3762138846Sogiroux# ifndef _LIBCPP_NO_NATIVE_SEMAPHORES 3862138846Sogiroux# include <semaphore.h> 3962138846Sogiroux# endif 40ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 41ab9aefeeSPetr Hosek# include <threads.h> 42790e10f6SSaleem Abdulrasool#endif 43c7e4239fSAsiri Rathnayake 442a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 452a129dc3SPeter Collingbourne defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \ 462a129dc3SPeter Collingbourne defined(_LIBCPP_HAS_THREAD_API_WIN32) 472a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS 482a129dc3SPeter Collingbourne#else 492a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY 502a129dc3SPeter Collingbourne#endif 512a129dc3SPeter Collingbourne 5283dca5c3SDimitry Andric#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis) 5383dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) 5483dca5c3SDimitry Andric#else 5583dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 5683dca5c3SDimitry Andric#endif 5783dca5c3SDimitry Andric 58696630eaSMarshall Clowtypedef ::timespec __libcpp_timespec_t; 59696630eaSMarshall Clow#endif // !defined(_LIBCPP_HAS_NO_THREADS) 60696630eaSMarshall Clow 61696630eaSMarshall Clow_LIBCPP_PUSH_MACROS 62696630eaSMarshall Clow#include <__undef_macros> 63696630eaSMarshall Clow 64c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD 65c7e4239fSAsiri Rathnayake 66696630eaSMarshall Clow#if !defined(_LIBCPP_HAS_NO_THREADS) 67696630eaSMarshall Clow 682a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 69c7e4239fSAsiri Rathnayake// Mutex 70c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t; 718c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 72c7e4239fSAsiri Rathnayake 7358a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t; 7458a0dceeSSaleem Abdulrasool 75790e10f6SSaleem Abdulrasool// Condition Variable 76790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t; 77790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER 78790e10f6SSaleem Abdulrasool 7962138846Sogiroux#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES 8054fa9ecdSOlivier Giroux// Semaphore 8154fa9ecdSOlivier Girouxtypedef sem_t __libcpp_semaphore_t; 8254fa9ecdSOlivier Giroux# define _LIBCPP_SEMAPHORE_MAX SEM_VALUE_MAX 8362138846Sogiroux#endif 8454fa9ecdSOlivier Giroux 85205d7d3fSAsiri Rathnayake// Execute once 86205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag; 87205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT 88205d7d3fSAsiri Rathnayake 89205d7d3fSAsiri Rathnayake// Thread id 90790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_id; 91790e10f6SSaleem Abdulrasool 92790e10f6SSaleem Abdulrasool// Thread 93af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 94af762e91SAsiri Rathnayake 95790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t; 96790e10f6SSaleem Abdulrasool 97cac6d217SFangrui Song// Thread Local Storage 98790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key; 996d7d0becSSaleem Abdulrasool 1006d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC 101ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 102ab9aefeeSPetr Hosek// Mutex 103ab9aefeeSPetr Hosektypedef mtx_t __libcpp_mutex_t; 104ab9aefeeSPetr Hosek// mtx_t is a struct so using {} for initialization is valid. 105ab9aefeeSPetr Hosek#define _LIBCPP_MUTEX_INITIALIZER {} 106ab9aefeeSPetr Hosek 107ab9aefeeSPetr Hosektypedef mtx_t __libcpp_recursive_mutex_t; 108ab9aefeeSPetr Hosek 109ab9aefeeSPetr Hosek// Condition Variable 110ab9aefeeSPetr Hosektypedef cnd_t __libcpp_condvar_t; 111ab9aefeeSPetr Hosek// cnd_t is a struct so using {} for initialization is valid. 112ab9aefeeSPetr Hosek#define _LIBCPP_CONDVAR_INITIALIZER {} 113ab9aefeeSPetr Hosek 114ab9aefeeSPetr Hosek// Execute once 115ab9aefeeSPetr Hosektypedef once_flag __libcpp_exec_once_flag; 116ab9aefeeSPetr Hosek#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT 117ab9aefeeSPetr Hosek 118ab9aefeeSPetr Hosek// Thread id 119ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_id; 120ab9aefeeSPetr Hosek 121ab9aefeeSPetr Hosek// Thread 122ab9aefeeSPetr Hosek#define _LIBCPP_NULL_THREAD 0U 123ab9aefeeSPetr Hosek 124ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_t; 125ab9aefeeSPetr Hosek 126ab9aefeeSPetr Hosek// Thread Local Storage 127ab9aefeeSPetr Hosektypedef tss_t __libcpp_tls_key; 128ab9aefeeSPetr Hosek 129ab9aefeeSPetr Hosek#define _LIBCPP_TLS_DESTRUCTOR_CC 130e2b200b7SDavid Spickett#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 131ac15ae6dSPeter Collingbourne// Mutex 132ac15ae6dSPeter Collingbournetypedef void* __libcpp_mutex_t; 133ac15ae6dSPeter Collingbourne#define _LIBCPP_MUTEX_INITIALIZER 0 134ac15ae6dSPeter Collingbourne 135ac15ae6dSPeter Collingbourne#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) 136ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[6]; 137ac15ae6dSPeter Collingbourne#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__) 138ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[5]; 139ac15ae6dSPeter Collingbourne#else 140ac15ae6dSPeter Collingbourne# error Unsupported architecture 141ac15ae6dSPeter Collingbourne#endif 1426d7d0becSSaleem Abdulrasool 1436d7d0becSSaleem Abdulrasool// Condition Variable 144ac15ae6dSPeter Collingbournetypedef void* __libcpp_condvar_t; 145ac15ae6dSPeter Collingbourne#define _LIBCPP_CONDVAR_INITIALIZER 0 1466d7d0becSSaleem Abdulrasool 14754fa9ecdSOlivier Giroux// Semaphore 14854fa9ecdSOlivier Girouxtypedef void* __libcpp_semaphore_t; 14954fa9ecdSOlivier Giroux 1506d7d0becSSaleem Abdulrasool// Execute Once 151ac15ae6dSPeter Collingbournetypedef void* __libcpp_exec_once_flag; 152ac15ae6dSPeter Collingbourne#define _LIBCPP_EXEC_ONCE_INITIALIZER 0 1536d7d0becSSaleem Abdulrasool 1546d7d0becSSaleem Abdulrasool// Thread ID 155ac15ae6dSPeter Collingbournetypedef long __libcpp_thread_id; 1566d7d0becSSaleem Abdulrasool 1576d7d0becSSaleem Abdulrasool// Thread 158af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 159af762e91SAsiri Rathnayake 160ac15ae6dSPeter Collingbournetypedef void* __libcpp_thread_t; 1616d7d0becSSaleem Abdulrasool 1626d7d0becSSaleem Abdulrasool// Thread Local Storage 163ac15ae6dSPeter Collingbournetypedef long __libcpp_tls_key; 1646d7d0becSSaleem Abdulrasool 165ac15ae6dSPeter Collingbourne#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall 166e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 167790e10f6SSaleem Abdulrasool 168e2b200b7SDavid Spickett#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 169790e10f6SSaleem Abdulrasool// Mutex 1708c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 17158a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); 17258a0dceeSSaleem Abdulrasool 17383dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 17458a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m); 17558a0dceeSSaleem Abdulrasool 17683dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 17708e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m); 17858a0dceeSSaleem Abdulrasool 17983dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 18058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m); 18158a0dceeSSaleem Abdulrasool 18258a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY 18358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m); 184790e10f6SSaleem Abdulrasool 18583dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1868c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m); 187790e10f6SSaleem Abdulrasool 18883dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 18908e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m); 190790e10f6SSaleem Abdulrasool 19183dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1928c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m); 193790e10f6SSaleem Abdulrasool 1948c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1958c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m); 1968c2bf45dSAsiri Rathnayake 1978c2bf45dSAsiri Rathnayake// Condition variable 1988c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1998c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv); 200790e10f6SSaleem Abdulrasool 2018c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2028c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv); 203790e10f6SSaleem Abdulrasool 20483dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 2058c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m); 206790e10f6SSaleem Abdulrasool 20783dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 208790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 209cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts); 210790e10f6SSaleem Abdulrasool 2118c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2128c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); 2138c2bf45dSAsiri Rathnayake 21462138846Sogiroux#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES 21562138846Sogiroux 21654fa9ecdSOlivier Giroux// Semaphore 21754fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 21854fa9ecdSOlivier Girouxbool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init); 21954fa9ecdSOlivier Giroux 22054fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 22154fa9ecdSOlivier Girouxbool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem); 22254fa9ecdSOlivier Giroux 22354fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 22454fa9ecdSOlivier Girouxbool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem); 22554fa9ecdSOlivier Giroux 22654fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 22754fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem); 22854fa9ecdSOlivier Giroux 22954fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 23054fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns); 23154fa9ecdSOlivier Giroux 23262138846Sogiroux#endif // _LIBCPP_NO_NATIVE_SEMAPHORES 23362138846Sogiroux 234205d7d3fSAsiri Rathnayake// Execute once 235205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 236205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 2374603460aSBruce Mitchener void (*init_routine)()); 238205d7d3fSAsiri Rathnayake 239205d7d3fSAsiri Rathnayake// Thread id 2408c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2418c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); 242790e10f6SSaleem Abdulrasool 2438c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2448c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); 2458c2bf45dSAsiri Rathnayake 2468c2bf45dSAsiri Rathnayake// Thread 2478c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 248af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t); 249af762e91SAsiri Rathnayake 250af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 251790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 252790e10f6SSaleem Abdulrasool void *__arg); 253790e10f6SSaleem Abdulrasool 2548c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2558c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id(); 256790e10f6SSaleem Abdulrasool 2578c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2588c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); 259790e10f6SSaleem Abdulrasool 2608c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2618c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t); 262790e10f6SSaleem Abdulrasool 2638c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2648c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t); 265790e10f6SSaleem Abdulrasool 2668c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2678c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield(); 2688c2bf45dSAsiri Rathnayake 26954a987e1SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2709e8a082dSJoerg Sonnenbergervoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns); 27154a987e1SAsiri Rathnayake 2728c2bf45dSAsiri Rathnayake// Thread local storage 2738c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2746d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key, 2756d7d0becSSaleem Abdulrasool void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)); 276790e10f6SSaleem Abdulrasool 2778c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2788c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key); 279790e10f6SSaleem Abdulrasool 2808c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 281205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p); 2828c2bf45dSAsiri Rathnayake 283e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 284e2b200b7SDavid Spickett 28514aef536SMikhail Maltsevstruct __libcpp_timed_backoff_policy { 28621a1a263SLouis Dionne _LIBCPP_INLINE_VISIBILITY 28721a1a263SLouis Dionne bool operator()(chrono::nanoseconds __elapsed) const 2883411a1a9SDavid Nicuesa { 2893411a1a9SDavid Nicuesa if(__elapsed > chrono::milliseconds(128)) 2903411a1a9SDavid Nicuesa __libcpp_thread_sleep_for(chrono::milliseconds(8)); 2913411a1a9SDavid Nicuesa else if(__elapsed > chrono::microseconds(64)) 2923411a1a9SDavid Nicuesa __libcpp_thread_sleep_for(__elapsed / 2); 2933411a1a9SDavid Nicuesa else if(__elapsed > chrono::microseconds(4)) 2943411a1a9SDavid Nicuesa __libcpp_thread_yield(); 2953411a1a9SDavid Nicuesa else 296*d2acf229SMarek Kurdej {} // poll 2973411a1a9SDavid Nicuesa return false; 2983411a1a9SDavid Nicuesa } 29921a1a263SLouis Dionne}; 3003411a1a9SDavid Nicuesa 3013411a1a9SDavid Nicuesastatic _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64; 3023411a1a9SDavid Nicuesa 30314aef536SMikhail Maltsevtemplate<class _Fn, class _BFn> 30446c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 30514aef536SMikhail Maltsevbool __libcpp_thread_poll_with_backoff( 3063411a1a9SDavid Nicuesa _Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()) 3073411a1a9SDavid Nicuesa{ 3083411a1a9SDavid Nicuesa auto const __start = chrono::high_resolution_clock::now(); 3093411a1a9SDavid Nicuesa for(int __count = 0;;) { 3103411a1a9SDavid Nicuesa if(__f()) 3113411a1a9SDavid Nicuesa return true; // _Fn completion means success 3123411a1a9SDavid Nicuesa if(__count < __libcpp_polling_count) { 3133411a1a9SDavid Nicuesa __count += 1; 3143411a1a9SDavid Nicuesa continue; 3153411a1a9SDavid Nicuesa } 3163411a1a9SDavid Nicuesa chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start; 3173411a1a9SDavid Nicuesa if(__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed) 3183411a1a9SDavid Nicuesa return false; // timeout failure 3193411a1a9SDavid Nicuesa if(__bf(__elapsed)) 3203411a1a9SDavid Nicuesa return false; // _BFn completion means failure 3213411a1a9SDavid Nicuesa } 3223411a1a9SDavid Nicuesa} 3233411a1a9SDavid Nicuesa 3243411a1a9SDavid Nicuesa#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 3253411a1a9SDavid Nicuesa defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) 3263411a1a9SDavid Nicuesa 32714aef536SMikhail Maltsev 328ab9aefeeSPetr Hoseknamespace __thread_detail { 329ab9aefeeSPetr Hosek 330ab9aefeeSPetr Hosekinline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) 331ab9aefeeSPetr Hosek{ 332ab9aefeeSPetr Hosek using namespace chrono; 333ab9aefeeSPetr Hosek seconds __s = duration_cast<seconds>(__ns); 334ab9aefeeSPetr Hosek __libcpp_timespec_t __ts; 335ab9aefeeSPetr Hosek typedef decltype(__ts.tv_sec) __ts_sec; 336ab9aefeeSPetr Hosek const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); 337ab9aefeeSPetr Hosek 338ab9aefeeSPetr Hosek if (__s.count() < __ts_sec_max) 339ab9aefeeSPetr Hosek { 340ab9aefeeSPetr Hosek __ts.tv_sec = static_cast<__ts_sec>(__s.count()); 341ab9aefeeSPetr Hosek __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); 342ab9aefeeSPetr Hosek } 343ab9aefeeSPetr Hosek else 344ab9aefeeSPetr Hosek { 345ab9aefeeSPetr Hosek __ts.tv_sec = __ts_sec_max; 346ab9aefeeSPetr Hosek __ts.tv_nsec = 999999999; // (10^9 - 1) 347ab9aefeeSPetr Hosek } 348ab9aefeeSPetr Hosek 349ab9aefeeSPetr Hosek return __ts; 350ab9aefeeSPetr Hosek} 351ab9aefeeSPetr Hosek 352ab9aefeeSPetr Hosek} 353ab9aefeeSPetr Hosek 354ab9aefeeSPetr Hosek#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 3558c2bf45dSAsiri Rathnayake 35658a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 357c7e4239fSAsiri Rathnayake{ 358c7e4239fSAsiri Rathnayake pthread_mutexattr_t attr; 359c7e4239fSAsiri Rathnayake int __ec = pthread_mutexattr_init(&attr); 360c7e4239fSAsiri Rathnayake if (__ec) 361790e10f6SSaleem Abdulrasool return __ec; 362790e10f6SSaleem Abdulrasool __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 363790e10f6SSaleem Abdulrasool if (__ec) { 364c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 365c7e4239fSAsiri Rathnayake return __ec; 366c7e4239fSAsiri Rathnayake } 367c7e4239fSAsiri Rathnayake __ec = pthread_mutex_init(__m, &attr); 368790e10f6SSaleem Abdulrasool if (__ec) { 369c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 370c7e4239fSAsiri Rathnayake return __ec; 371c7e4239fSAsiri Rathnayake } 372c7e4239fSAsiri Rathnayake __ec = pthread_mutexattr_destroy(&attr); 373790e10f6SSaleem Abdulrasool if (__ec) { 374c7e4239fSAsiri Rathnayake pthread_mutex_destroy(__m); 375c7e4239fSAsiri Rathnayake return __ec; 376c7e4239fSAsiri Rathnayake } 377c7e4239fSAsiri Rathnayake return 0; 378c7e4239fSAsiri Rathnayake} 379c7e4239fSAsiri Rathnayake 38058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 38158a0dceeSSaleem Abdulrasool{ 38258a0dceeSSaleem Abdulrasool return pthread_mutex_lock(__m); 38358a0dceeSSaleem Abdulrasool} 38458a0dceeSSaleem Abdulrasool 38508e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 38658a0dceeSSaleem Abdulrasool{ 38708e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 38858a0dceeSSaleem Abdulrasool} 38958a0dceeSSaleem Abdulrasool 39058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m) 39158a0dceeSSaleem Abdulrasool{ 39258a0dceeSSaleem Abdulrasool return pthread_mutex_unlock(__m); 39358a0dceeSSaleem Abdulrasool} 39458a0dceeSSaleem Abdulrasool 39558a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 39658a0dceeSSaleem Abdulrasool{ 39758a0dceeSSaleem Abdulrasool return pthread_mutex_destroy(__m); 39858a0dceeSSaleem Abdulrasool} 39958a0dceeSSaleem Abdulrasool 400c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 401c7e4239fSAsiri Rathnayake{ 402c7e4239fSAsiri Rathnayake return pthread_mutex_lock(__m); 403c7e4239fSAsiri Rathnayake} 404c7e4239fSAsiri Rathnayake 40508e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 406c7e4239fSAsiri Rathnayake{ 40708e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 408c7e4239fSAsiri Rathnayake} 409c7e4239fSAsiri Rathnayake 410c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 411c7e4239fSAsiri Rathnayake{ 412c7e4239fSAsiri Rathnayake return pthread_mutex_unlock(__m); 413c7e4239fSAsiri Rathnayake} 414c7e4239fSAsiri Rathnayake 415c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 416c7e4239fSAsiri Rathnayake{ 417c7e4239fSAsiri Rathnayake return pthread_mutex_destroy(__m); 418c7e4239fSAsiri Rathnayake} 419c7e4239fSAsiri Rathnayake 420790e10f6SSaleem Abdulrasool// Condition Variable 421c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 422c7e4239fSAsiri Rathnayake{ 423c7e4239fSAsiri Rathnayake return pthread_cond_signal(__cv); 424c7e4239fSAsiri Rathnayake} 425c7e4239fSAsiri Rathnayake 426c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 427c7e4239fSAsiri Rathnayake{ 428c7e4239fSAsiri Rathnayake return pthread_cond_broadcast(__cv); 429c7e4239fSAsiri Rathnayake} 430c7e4239fSAsiri Rathnayake 431c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 432c7e4239fSAsiri Rathnayake{ 433c7e4239fSAsiri Rathnayake return pthread_cond_wait(__cv, __m); 434c7e4239fSAsiri Rathnayake} 435c7e4239fSAsiri Rathnayake 436790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 437cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts) 438c7e4239fSAsiri Rathnayake{ 439c7e4239fSAsiri Rathnayake return pthread_cond_timedwait(__cv, __m, __ts); 440c7e4239fSAsiri Rathnayake} 441c7e4239fSAsiri Rathnayake 442c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 443c7e4239fSAsiri Rathnayake{ 444c7e4239fSAsiri Rathnayake return pthread_cond_destroy(__cv); 445c7e4239fSAsiri Rathnayake} 446c7e4239fSAsiri Rathnayake 44754fa9ecdSOlivier Giroux#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES 44854fa9ecdSOlivier Giroux 44954fa9ecdSOlivier Giroux// Semaphore 45054fa9ecdSOlivier Girouxbool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init) 45154fa9ecdSOlivier Giroux{ 45254fa9ecdSOlivier Giroux return sem_init(__sem, 0, __init) == 0; 45354fa9ecdSOlivier Giroux} 45454fa9ecdSOlivier Giroux 45554fa9ecdSOlivier Girouxbool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem) 45654fa9ecdSOlivier Giroux{ 45754fa9ecdSOlivier Giroux return sem_destroy(__sem) == 0; 45854fa9ecdSOlivier Giroux} 45954fa9ecdSOlivier Giroux 46054fa9ecdSOlivier Girouxbool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem) 46154fa9ecdSOlivier Giroux{ 46254fa9ecdSOlivier Giroux return sem_post(__sem) == 0; 46354fa9ecdSOlivier Giroux} 46454fa9ecdSOlivier Giroux 46554fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem) 46654fa9ecdSOlivier Giroux{ 46754fa9ecdSOlivier Giroux return sem_wait(__sem) == 0; 46854fa9ecdSOlivier Giroux} 46954fa9ecdSOlivier Giroux 47054fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns) 47154fa9ecdSOlivier Giroux{ 47254fa9ecdSOlivier Giroux auto const __abs_time = chrono::system_clock::now().time_since_epoch() + __ns; 47354fa9ecdSOlivier Giroux __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__abs_time); 47454fa9ecdSOlivier Giroux return sem_timedwait(__sem, &__ts) == 0; 47554fa9ecdSOlivier Giroux} 47654fa9ecdSOlivier Giroux 47754fa9ecdSOlivier Giroux#endif //_LIBCPP_NO_NATIVE_SEMAPHORES 47854fa9ecdSOlivier Giroux 479205d7d3fSAsiri Rathnayake// Execute once 480205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 4814603460aSBruce Mitchener void (*init_routine)()) { 482205d7d3fSAsiri Rathnayake return pthread_once(flag, init_routine); 483205d7d3fSAsiri Rathnayake} 484205d7d3fSAsiri Rathnayake 485205d7d3fSAsiri Rathnayake// Thread id 486c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0 487c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 488c7e4239fSAsiri Rathnayake{ 489c7e4239fSAsiri Rathnayake return pthread_equal(t1, t2) != 0; 490c7e4239fSAsiri Rathnayake} 491c7e4239fSAsiri Rathnayake 492c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0 493c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 494c7e4239fSAsiri Rathnayake{ 495c7e4239fSAsiri Rathnayake return t1 < t2; 496c7e4239fSAsiri Rathnayake} 497c7e4239fSAsiri Rathnayake 498c7e4239fSAsiri Rathnayake// Thread 499af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 500af762e91SAsiri Rathnayake return *__t == 0; 501af762e91SAsiri Rathnayake} 502af762e91SAsiri Rathnayake 503790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 504790e10f6SSaleem Abdulrasool void *__arg) 505c7e4239fSAsiri Rathnayake{ 506c7e4239fSAsiri Rathnayake return pthread_create(__t, 0, __func, __arg); 507c7e4239fSAsiri Rathnayake} 508c7e4239fSAsiri Rathnayake 509c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id() 510c7e4239fSAsiri Rathnayake{ 511c7e4239fSAsiri Rathnayake return pthread_self(); 512c7e4239fSAsiri Rathnayake} 513c7e4239fSAsiri Rathnayake 514c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 515c7e4239fSAsiri Rathnayake{ 516c7e4239fSAsiri Rathnayake return *__t; 517c7e4239fSAsiri Rathnayake} 518c7e4239fSAsiri Rathnayake 519c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t) 520c7e4239fSAsiri Rathnayake{ 521c7e4239fSAsiri Rathnayake return pthread_join(*__t, 0); 522c7e4239fSAsiri Rathnayake} 523c7e4239fSAsiri Rathnayake 524c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t) 525c7e4239fSAsiri Rathnayake{ 526c7e4239fSAsiri Rathnayake return pthread_detach(*__t); 527c7e4239fSAsiri Rathnayake} 528c7e4239fSAsiri Rathnayake 529c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield() 530c7e4239fSAsiri Rathnayake{ 531c7e4239fSAsiri Rathnayake sched_yield(); 532c7e4239fSAsiri Rathnayake} 533c7e4239fSAsiri Rathnayake 53454a987e1SAsiri Rathnayakevoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 53554a987e1SAsiri Rathnayake{ 536ab9aefeeSPetr Hosek __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); 53754a987e1SAsiri Rathnayake while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); 53854a987e1SAsiri Rathnayake} 53954a987e1SAsiri Rathnayake 540c7e4239fSAsiri Rathnayake// Thread local storage 5418c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 542c7e4239fSAsiri Rathnayake{ 543c7e4239fSAsiri Rathnayake return pthread_key_create(__key, __at_exit); 544c7e4239fSAsiri Rathnayake} 545c7e4239fSAsiri Rathnayake 5468c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key) 547c7e4239fSAsiri Rathnayake{ 548c7e4239fSAsiri Rathnayake return pthread_getspecific(__key); 549c7e4239fSAsiri Rathnayake} 550c7e4239fSAsiri Rathnayake 551205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 552c7e4239fSAsiri Rathnayake{ 553205d7d3fSAsiri Rathnayake return pthread_setspecific(__key, __p); 554c7e4239fSAsiri Rathnayake} 555c7e4239fSAsiri Rathnayake 556ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 557ab9aefeeSPetr Hosek 558ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 559ab9aefeeSPetr Hosek{ 5603481e5d7SPetr Hosek return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL; 561ab9aefeeSPetr Hosek} 562ab9aefeeSPetr Hosek 563ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 564ab9aefeeSPetr Hosek{ 565ab9aefeeSPetr Hosek return mtx_lock(__m) == thrd_success ? 0 : EINVAL; 566ab9aefeeSPetr Hosek} 567ab9aefeeSPetr Hosek 568ab9aefeeSPetr Hosekbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 569ab9aefeeSPetr Hosek{ 570ab9aefeeSPetr Hosek return mtx_trylock(__m) == thrd_success; 571ab9aefeeSPetr Hosek} 572ab9aefeeSPetr Hosek 573ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m) 574ab9aefeeSPetr Hosek{ 575ab9aefeeSPetr Hosek return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; 576ab9aefeeSPetr Hosek} 577ab9aefeeSPetr Hosek 578ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 579ab9aefeeSPetr Hosek{ 580ab9aefeeSPetr Hosek mtx_destroy(__m); 581ab9aefeeSPetr Hosek return 0; 582ab9aefeeSPetr Hosek} 583ab9aefeeSPetr Hosek 584ab9aefeeSPetr Hosekint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 585ab9aefeeSPetr Hosek{ 586ab9aefeeSPetr Hosek return mtx_lock(__m) == thrd_success ? 0 : EINVAL; 587ab9aefeeSPetr Hosek} 588ab9aefeeSPetr Hosek 589ab9aefeeSPetr Hosekbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 590ab9aefeeSPetr Hosek{ 591ab9aefeeSPetr Hosek return mtx_trylock(__m) == thrd_success; 592ab9aefeeSPetr Hosek} 593ab9aefeeSPetr Hosek 594ab9aefeeSPetr Hosekint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 595ab9aefeeSPetr Hosek{ 596ab9aefeeSPetr Hosek return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; 597ab9aefeeSPetr Hosek} 598ab9aefeeSPetr Hosek 599ab9aefeeSPetr Hosekint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 600ab9aefeeSPetr Hosek{ 601ab9aefeeSPetr Hosek mtx_destroy(__m); 602ab9aefeeSPetr Hosek return 0; 603ab9aefeeSPetr Hosek} 604ab9aefeeSPetr Hosek 605ab9aefeeSPetr Hosek// Condition Variable 606ab9aefeeSPetr Hosekint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 607ab9aefeeSPetr Hosek{ 608ab9aefeeSPetr Hosek return cnd_signal(__cv) == thrd_success ? 0 : EINVAL; 609ab9aefeeSPetr Hosek} 610ab9aefeeSPetr Hosek 611ab9aefeeSPetr Hosekint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 612ab9aefeeSPetr Hosek{ 613ab9aefeeSPetr Hosek return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL; 614ab9aefeeSPetr Hosek} 615ab9aefeeSPetr Hosek 616ab9aefeeSPetr Hosekint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 617ab9aefeeSPetr Hosek{ 618ab9aefeeSPetr Hosek return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL; 619ab9aefeeSPetr Hosek} 620ab9aefeeSPetr Hosek 621ab9aefeeSPetr Hosekint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 622ab9aefeeSPetr Hosek timespec *__ts) 623ab9aefeeSPetr Hosek{ 624ab9aefeeSPetr Hosek int __ec = cnd_timedwait(__cv, __m, __ts); 625ab9aefeeSPetr Hosek return __ec == thrd_timedout ? ETIMEDOUT : __ec; 626ab9aefeeSPetr Hosek} 627ab9aefeeSPetr Hosek 628ab9aefeeSPetr Hosekint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 629ab9aefeeSPetr Hosek{ 630ab9aefeeSPetr Hosek cnd_destroy(__cv); 631ab9aefeeSPetr Hosek return 0; 632ab9aefeeSPetr Hosek} 633ab9aefeeSPetr Hosek 634ab9aefeeSPetr Hosek// Execute once 635ab9aefeeSPetr Hosekint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 636ab9aefeeSPetr Hosek void (*init_routine)(void)) { 637ab9aefeeSPetr Hosek ::call_once(flag, init_routine); 638ab9aefeeSPetr Hosek return 0; 639ab9aefeeSPetr Hosek} 640ab9aefeeSPetr Hosek 641ab9aefeeSPetr Hosek// Thread id 642ab9aefeeSPetr Hosek// Returns non-zero if the thread ids are equal, otherwise 0 643ab9aefeeSPetr Hosekbool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 644ab9aefeeSPetr Hosek{ 645ab9aefeeSPetr Hosek return thrd_equal(t1, t2) != 0; 646ab9aefeeSPetr Hosek} 647ab9aefeeSPetr Hosek 648ab9aefeeSPetr Hosek// Returns non-zero if t1 < t2, otherwise 0 649ab9aefeeSPetr Hosekbool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 650ab9aefeeSPetr Hosek{ 651ab9aefeeSPetr Hosek return t1 < t2; 652ab9aefeeSPetr Hosek} 653ab9aefeeSPetr Hosek 654ab9aefeeSPetr Hosek// Thread 655ab9aefeeSPetr Hosekbool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 656ab9aefeeSPetr Hosek return *__t == 0; 657ab9aefeeSPetr Hosek} 658ab9aefeeSPetr Hosek 659ab9aefeeSPetr Hosekint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 660ab9aefeeSPetr Hosek void *__arg) 661ab9aefeeSPetr Hosek{ 662ab9aefeeSPetr Hosek int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg); 663ab9aefeeSPetr Hosek return __ec == thrd_nomem ? ENOMEM : __ec; 664ab9aefeeSPetr Hosek} 665ab9aefeeSPetr Hosek 666ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_current_id() 667ab9aefeeSPetr Hosek{ 668ab9aefeeSPetr Hosek return thrd_current(); 669ab9aefeeSPetr Hosek} 670ab9aefeeSPetr Hosek 671ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 672ab9aefeeSPetr Hosek{ 673ab9aefeeSPetr Hosek return *__t; 674ab9aefeeSPetr Hosek} 675ab9aefeeSPetr Hosek 676ab9aefeeSPetr Hosekint __libcpp_thread_join(__libcpp_thread_t *__t) 677ab9aefeeSPetr Hosek{ 678ab9aefeeSPetr Hosek return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL; 679ab9aefeeSPetr Hosek} 680ab9aefeeSPetr Hosek 681ab9aefeeSPetr Hosekint __libcpp_thread_detach(__libcpp_thread_t *__t) 682ab9aefeeSPetr Hosek{ 683ab9aefeeSPetr Hosek return thrd_detach(*__t) == thrd_success ? 0 : EINVAL; 684ab9aefeeSPetr Hosek} 685ab9aefeeSPetr Hosek 686ab9aefeeSPetr Hosekvoid __libcpp_thread_yield() 687ab9aefeeSPetr Hosek{ 688ab9aefeeSPetr Hosek thrd_yield(); 689ab9aefeeSPetr Hosek} 690ab9aefeeSPetr Hosek 691ab9aefeeSPetr Hosekvoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 692ab9aefeeSPetr Hosek{ 693ab9aefeeSPetr Hosek __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); 694ab9aefeeSPetr Hosek thrd_sleep(&__ts, nullptr); 695ab9aefeeSPetr Hosek} 696ab9aefeeSPetr Hosek 697ab9aefeeSPetr Hosek// Thread local storage 698ab9aefeeSPetr Hosekint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 699ab9aefeeSPetr Hosek{ 700ab9aefeeSPetr Hosek return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL; 701ab9aefeeSPetr Hosek} 702ab9aefeeSPetr Hosek 703ab9aefeeSPetr Hosekvoid *__libcpp_tls_get(__libcpp_tls_key __key) 704ab9aefeeSPetr Hosek{ 705ab9aefeeSPetr Hosek return tss_get(__key); 706ab9aefeeSPetr Hosek} 707ab9aefeeSPetr Hosek 708ab9aefeeSPetr Hosekint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 709ab9aefeeSPetr Hosek{ 710ab9aefeeSPetr Hosek return tss_set(__key, __p) == thrd_success ? 0 : EINVAL; 711ab9aefeeSPetr Hosek} 712ab9aefeeSPetr Hosek 713ab9aefeeSPetr Hosek#endif 714ab9aefeeSPetr Hosek 715e3add3e5SMartin Storsjö 71600f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL 71700f6beaeSEric Fiselier 7182b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS thread; 7192b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS __thread_id; 7202b1d4254SMarshall Clow 7212b1d4254SMarshall Clownamespace this_thread 7222b1d4254SMarshall Clow{ 7232b1d4254SMarshall Clow 7242b1d4254SMarshall Clow_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; 7252b1d4254SMarshall Clow 7262b1d4254SMarshall Clow} // this_thread 7272b1d4254SMarshall Clow 7282b1d4254SMarshall Clowtemplate<> struct hash<__thread_id>; 7292b1d4254SMarshall Clow 7302b1d4254SMarshall Clowclass _LIBCPP_TEMPLATE_VIS __thread_id 7312b1d4254SMarshall Clow{ 7322b1d4254SMarshall Clow // FIXME: pthread_t is a pointer on Darwin but a long on Linux. 7332b1d4254SMarshall Clow // NULL is the no-thread value on Darwin. Someone needs to check 7342b1d4254SMarshall Clow // on other platforms. We assume 0 works everywhere for now. 7352b1d4254SMarshall Clow __libcpp_thread_id __id_; 7362b1d4254SMarshall Clow 7372b1d4254SMarshall Clowpublic: 7382b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7392b1d4254SMarshall Clow __thread_id() _NOEXCEPT : __id_(0) {} 7402b1d4254SMarshall Clow 7412b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7422b1d4254SMarshall Clow bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT 7432e80d01fSMarshall Clow { // don't pass id==0 to underlying routines 7442e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ == 0; 7452e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 7462e80d01fSMarshall Clow return __libcpp_thread_id_equal(__x.__id_, __y.__id_); 7472e80d01fSMarshall Clow } 7482b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7492b1d4254SMarshall Clow bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT 7502b1d4254SMarshall Clow {return !(__x == __y);} 7512b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7522b1d4254SMarshall Clow bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT 7532e80d01fSMarshall Clow { // id==0 is always less than any other thread_id 7542e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ != 0; 7552e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 7562e80d01fSMarshall Clow return __libcpp_thread_id_less(__x.__id_, __y.__id_); 7572e80d01fSMarshall Clow } 7582b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7592b1d4254SMarshall Clow bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT 7602b1d4254SMarshall Clow {return !(__y < __x);} 7612b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7622b1d4254SMarshall Clow bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT 7632b1d4254SMarshall Clow {return __y < __x ;} 7642b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7652b1d4254SMarshall Clow bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT 7662b1d4254SMarshall Clow {return !(__x < __y);} 7672b1d4254SMarshall Clow 7682b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7692e80d01fSMarshall Clow void __reset() { __id_ = 0; } 7702b1d4254SMarshall Clow 7712b1d4254SMarshall Clow template<class _CharT, class _Traits> 7722b1d4254SMarshall Clow friend 7732b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7742b1d4254SMarshall Clow basic_ostream<_CharT, _Traits>& 7752b1d4254SMarshall Clow operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); 7762b1d4254SMarshall Clow 7772b1d4254SMarshall Clowprivate: 7782b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7792b1d4254SMarshall Clow __thread_id(__libcpp_thread_id __id) : __id_(__id) {} 7802b1d4254SMarshall Clow 7812b1d4254SMarshall Clow friend __thread_id this_thread::get_id() _NOEXCEPT; 7822b1d4254SMarshall Clow friend class _LIBCPP_TYPE_VIS thread; 7832b1d4254SMarshall Clow friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; 7842b1d4254SMarshall Clow}; 7852b1d4254SMarshall Clow 7862b1d4254SMarshall Clownamespace this_thread 7872b1d4254SMarshall Clow{ 7882b1d4254SMarshall Clow 7892b1d4254SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY 7902b1d4254SMarshall Clow__thread_id 7912b1d4254SMarshall Clowget_id() _NOEXCEPT 7922b1d4254SMarshall Clow{ 7932b1d4254SMarshall Clow return __libcpp_thread_get_current_id(); 7942b1d4254SMarshall Clow} 7952b1d4254SMarshall Clow 7962b1d4254SMarshall Clow} // this_thread 7972b1d4254SMarshall Clow 798696630eaSMarshall Clow#endif // !_LIBCPP_HAS_NO_THREADS 799696630eaSMarshall Clow 800c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD 801c7e4239fSAsiri Rathnayake 802a016efb1SEric Fiselier_LIBCPP_POP_MACROS 803a016efb1SEric Fiselier 804c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT 805