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__ 20b5175681SLouis Dionne# 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> 34e6c89a49SZbigniew Sarbinowski# if defined(__APPLE__) || defined(__MVS__) 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 90e6c89a49SZbigniew Sarbinowski#if defined(__MVS__) 91e6c89a49SZbigniew Sarbinowski typedef unsigned long long __libcpp_thread_id; 92e6c89a49SZbigniew Sarbinowski#else 93790e10f6SSaleem Abdulrasool typedef pthread_t __libcpp_thread_id; 94e6c89a49SZbigniew Sarbinowski#endif 95790e10f6SSaleem Abdulrasool 96790e10f6SSaleem Abdulrasool// Thread 97e6c89a49SZbigniew Sarbinowski#define _LIBCPP_NULL_THREAD ((__libcpp_thread_t())) 98790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t; 99790e10f6SSaleem Abdulrasool 100cac6d217SFangrui Song// Thread Local Storage 101790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key; 1026d7d0becSSaleem Abdulrasool 1036d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC 104ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 105ab9aefeeSPetr Hosek// Mutex 106ab9aefeeSPetr Hosektypedef mtx_t __libcpp_mutex_t; 107ab9aefeeSPetr Hosek// mtx_t is a struct so using {} for initialization is valid. 108ab9aefeeSPetr Hosek#define _LIBCPP_MUTEX_INITIALIZER {} 109ab9aefeeSPetr Hosek 110ab9aefeeSPetr Hosektypedef mtx_t __libcpp_recursive_mutex_t; 111ab9aefeeSPetr Hosek 112ab9aefeeSPetr Hosek// Condition Variable 113ab9aefeeSPetr Hosektypedef cnd_t __libcpp_condvar_t; 114ab9aefeeSPetr Hosek// cnd_t is a struct so using {} for initialization is valid. 115ab9aefeeSPetr Hosek#define _LIBCPP_CONDVAR_INITIALIZER {} 116ab9aefeeSPetr Hosek 117ab9aefeeSPetr Hosek// Execute once 118ab9aefeeSPetr Hosektypedef once_flag __libcpp_exec_once_flag; 119ab9aefeeSPetr Hosek#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT 120ab9aefeeSPetr Hosek 121ab9aefeeSPetr Hosek// Thread id 122ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_id; 123ab9aefeeSPetr Hosek 124ab9aefeeSPetr Hosek// Thread 125ab9aefeeSPetr Hosek#define _LIBCPP_NULL_THREAD 0U 126ab9aefeeSPetr Hosek 127ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_t; 128ab9aefeeSPetr Hosek 129ab9aefeeSPetr Hosek// Thread Local Storage 130ab9aefeeSPetr Hosektypedef tss_t __libcpp_tls_key; 131ab9aefeeSPetr Hosek 132ab9aefeeSPetr Hosek#define _LIBCPP_TLS_DESTRUCTOR_CC 133e2b200b7SDavid Spickett#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 134ac15ae6dSPeter Collingbourne// Mutex 135ac15ae6dSPeter Collingbournetypedef void* __libcpp_mutex_t; 136ac15ae6dSPeter Collingbourne#define _LIBCPP_MUTEX_INITIALIZER 0 137ac15ae6dSPeter Collingbourne 138ac15ae6dSPeter Collingbourne#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) 139ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[6]; 140ac15ae6dSPeter Collingbourne#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__) 141ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[5]; 142ac15ae6dSPeter Collingbourne#else 143ac15ae6dSPeter Collingbourne# error Unsupported architecture 144ac15ae6dSPeter Collingbourne#endif 1456d7d0becSSaleem Abdulrasool 1466d7d0becSSaleem Abdulrasool// Condition Variable 147ac15ae6dSPeter Collingbournetypedef void* __libcpp_condvar_t; 148ac15ae6dSPeter Collingbourne#define _LIBCPP_CONDVAR_INITIALIZER 0 1496d7d0becSSaleem Abdulrasool 15054fa9ecdSOlivier Giroux// Semaphore 15154fa9ecdSOlivier Girouxtypedef void* __libcpp_semaphore_t; 15254fa9ecdSOlivier Giroux 1536d7d0becSSaleem Abdulrasool// Execute Once 154ac15ae6dSPeter Collingbournetypedef void* __libcpp_exec_once_flag; 155ac15ae6dSPeter Collingbourne#define _LIBCPP_EXEC_ONCE_INITIALIZER 0 1566d7d0becSSaleem Abdulrasool 1576d7d0becSSaleem Abdulrasool// Thread ID 158ac15ae6dSPeter Collingbournetypedef long __libcpp_thread_id; 1596d7d0becSSaleem Abdulrasool 1606d7d0becSSaleem Abdulrasool// Thread 161af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 162af762e91SAsiri Rathnayake 163ac15ae6dSPeter Collingbournetypedef void* __libcpp_thread_t; 1646d7d0becSSaleem Abdulrasool 1656d7d0becSSaleem Abdulrasool// Thread Local Storage 166ac15ae6dSPeter Collingbournetypedef long __libcpp_tls_key; 1676d7d0becSSaleem Abdulrasool 168ac15ae6dSPeter Collingbourne#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall 169e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 170790e10f6SSaleem Abdulrasool 171e2b200b7SDavid Spickett#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 172790e10f6SSaleem Abdulrasool// Mutex 1738c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 17458a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); 17558a0dceeSSaleem Abdulrasool 17683dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 17758a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m); 17858a0dceeSSaleem Abdulrasool 17983dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 18008e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m); 18158a0dceeSSaleem Abdulrasool 18283dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 18358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m); 18458a0dceeSSaleem Abdulrasool 18558a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY 18658a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m); 187790e10f6SSaleem Abdulrasool 18883dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1898c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m); 190790e10f6SSaleem Abdulrasool 19183dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 19208e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m); 193790e10f6SSaleem Abdulrasool 19483dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1958c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m); 196790e10f6SSaleem Abdulrasool 1978c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1988c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m); 1998c2bf45dSAsiri Rathnayake 2008c2bf45dSAsiri Rathnayake// Condition variable 2018c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2028c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv); 203790e10f6SSaleem Abdulrasool 2048c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2058c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv); 206790e10f6SSaleem Abdulrasool 20783dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 2088c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m); 209790e10f6SSaleem Abdulrasool 21083dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 211790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 212cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts); 213790e10f6SSaleem Abdulrasool 2148c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2158c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); 2168c2bf45dSAsiri Rathnayake 21762138846Sogiroux#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES 21862138846Sogiroux 21954fa9ecdSOlivier Giroux// Semaphore 22054fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 22154fa9ecdSOlivier Girouxbool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init); 22254fa9ecdSOlivier Giroux 22354fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 22454fa9ecdSOlivier Girouxbool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem); 22554fa9ecdSOlivier Giroux 22654fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 22754fa9ecdSOlivier Girouxbool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem); 22854fa9ecdSOlivier Giroux 22954fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 23054fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem); 23154fa9ecdSOlivier Giroux 23254fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 23354fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns); 23454fa9ecdSOlivier Giroux 23562138846Sogiroux#endif // _LIBCPP_NO_NATIVE_SEMAPHORES 23662138846Sogiroux 237205d7d3fSAsiri Rathnayake// Execute once 238205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 239205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 2404603460aSBruce Mitchener void (*init_routine)()); 241205d7d3fSAsiri Rathnayake 242205d7d3fSAsiri Rathnayake// Thread id 2438c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2448c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); 245790e10f6SSaleem Abdulrasool 2468c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2478c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); 2488c2bf45dSAsiri Rathnayake 2498c2bf45dSAsiri Rathnayake// Thread 2508c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 251af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t); 252af762e91SAsiri Rathnayake 253af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 254790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 255790e10f6SSaleem Abdulrasool void *__arg); 256790e10f6SSaleem Abdulrasool 2578c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2588c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id(); 259790e10f6SSaleem Abdulrasool 2608c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2618c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); 262790e10f6SSaleem Abdulrasool 2638c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2648c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t); 265790e10f6SSaleem Abdulrasool 2668c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2678c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t); 268790e10f6SSaleem Abdulrasool 2698c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2708c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield(); 2718c2bf45dSAsiri Rathnayake 27254a987e1SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2739e8a082dSJoerg Sonnenbergervoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns); 27454a987e1SAsiri Rathnayake 2758c2bf45dSAsiri Rathnayake// Thread local storage 2768c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2776d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key, 2786d7d0becSSaleem Abdulrasool void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)); 279790e10f6SSaleem Abdulrasool 2808c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2818c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key); 282790e10f6SSaleem Abdulrasool 2838c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 284205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p); 2858c2bf45dSAsiri Rathnayake 286e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 287e2b200b7SDavid Spickett 28814aef536SMikhail Maltsevstruct __libcpp_timed_backoff_policy { 28921a1a263SLouis Dionne _LIBCPP_INLINE_VISIBILITY 29021a1a263SLouis Dionne bool operator()(chrono::nanoseconds __elapsed) const 2913411a1a9SDavid Nicuesa { 2923411a1a9SDavid Nicuesa if(__elapsed > chrono::milliseconds(128)) 2933411a1a9SDavid Nicuesa __libcpp_thread_sleep_for(chrono::milliseconds(8)); 2943411a1a9SDavid Nicuesa else if(__elapsed > chrono::microseconds(64)) 2953411a1a9SDavid Nicuesa __libcpp_thread_sleep_for(__elapsed / 2); 2963411a1a9SDavid Nicuesa else if(__elapsed > chrono::microseconds(4)) 2973411a1a9SDavid Nicuesa __libcpp_thread_yield(); 2983411a1a9SDavid Nicuesa else 299d2acf229SMarek Kurdej {} // poll 3003411a1a9SDavid Nicuesa return false; 3013411a1a9SDavid Nicuesa } 30221a1a263SLouis Dionne}; 3033411a1a9SDavid Nicuesa 3043411a1a9SDavid Nicuesastatic _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64; 3053411a1a9SDavid Nicuesa 30614aef536SMikhail Maltsevtemplate<class _Fn, class _BFn> 30746c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 30814aef536SMikhail Maltsevbool __libcpp_thread_poll_with_backoff( 3093411a1a9SDavid Nicuesa _Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()) 3103411a1a9SDavid Nicuesa{ 3113411a1a9SDavid Nicuesa auto const __start = chrono::high_resolution_clock::now(); 3123411a1a9SDavid Nicuesa for(int __count = 0;;) { 3133411a1a9SDavid Nicuesa if(__f()) 3143411a1a9SDavid Nicuesa return true; // _Fn completion means success 3153411a1a9SDavid Nicuesa if(__count < __libcpp_polling_count) { 3163411a1a9SDavid Nicuesa __count += 1; 3173411a1a9SDavid Nicuesa continue; 3183411a1a9SDavid Nicuesa } 3193411a1a9SDavid Nicuesa chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start; 3203411a1a9SDavid Nicuesa if(__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed) 3213411a1a9SDavid Nicuesa return false; // timeout failure 3223411a1a9SDavid Nicuesa if(__bf(__elapsed)) 3233411a1a9SDavid Nicuesa return false; // _BFn completion means failure 3243411a1a9SDavid Nicuesa } 3253411a1a9SDavid Nicuesa} 3263411a1a9SDavid Nicuesa 3273411a1a9SDavid Nicuesa#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 3283411a1a9SDavid Nicuesa defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) 3293411a1a9SDavid Nicuesa 33014aef536SMikhail Maltsev 331ab9aefeeSPetr Hoseknamespace __thread_detail { 332ab9aefeeSPetr Hosek 333ab9aefeeSPetr Hosekinline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) 334ab9aefeeSPetr Hosek{ 335ab9aefeeSPetr Hosek using namespace chrono; 336ab9aefeeSPetr Hosek seconds __s = duration_cast<seconds>(__ns); 337ab9aefeeSPetr Hosek __libcpp_timespec_t __ts; 338ab9aefeeSPetr Hosek typedef decltype(__ts.tv_sec) __ts_sec; 339ab9aefeeSPetr Hosek const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); 340ab9aefeeSPetr Hosek 341ab9aefeeSPetr Hosek if (__s.count() < __ts_sec_max) 342ab9aefeeSPetr Hosek { 343ab9aefeeSPetr Hosek __ts.tv_sec = static_cast<__ts_sec>(__s.count()); 344ab9aefeeSPetr Hosek __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); 345ab9aefeeSPetr Hosek } 346ab9aefeeSPetr Hosek else 347ab9aefeeSPetr Hosek { 348ab9aefeeSPetr Hosek __ts.tv_sec = __ts_sec_max; 349ab9aefeeSPetr Hosek __ts.tv_nsec = 999999999; // (10^9 - 1) 350ab9aefeeSPetr Hosek } 351ab9aefeeSPetr Hosek 352ab9aefeeSPetr Hosek return __ts; 353ab9aefeeSPetr Hosek} 354ab9aefeeSPetr Hosek 355ab9aefeeSPetr Hosek} 356ab9aefeeSPetr Hosek 357ab9aefeeSPetr Hosek#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 3588c2bf45dSAsiri Rathnayake 35958a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 360c7e4239fSAsiri Rathnayake{ 361c7e4239fSAsiri Rathnayake pthread_mutexattr_t attr; 362c7e4239fSAsiri Rathnayake int __ec = pthread_mutexattr_init(&attr); 363c7e4239fSAsiri Rathnayake if (__ec) 364790e10f6SSaleem Abdulrasool return __ec; 365790e10f6SSaleem Abdulrasool __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 366790e10f6SSaleem Abdulrasool if (__ec) { 367c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 368c7e4239fSAsiri Rathnayake return __ec; 369c7e4239fSAsiri Rathnayake } 370c7e4239fSAsiri Rathnayake __ec = pthread_mutex_init(__m, &attr); 371790e10f6SSaleem Abdulrasool if (__ec) { 372c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 373c7e4239fSAsiri Rathnayake return __ec; 374c7e4239fSAsiri Rathnayake } 375c7e4239fSAsiri Rathnayake __ec = pthread_mutexattr_destroy(&attr); 376790e10f6SSaleem Abdulrasool if (__ec) { 377c7e4239fSAsiri Rathnayake pthread_mutex_destroy(__m); 378c7e4239fSAsiri Rathnayake return __ec; 379c7e4239fSAsiri Rathnayake } 380c7e4239fSAsiri Rathnayake return 0; 381c7e4239fSAsiri Rathnayake} 382c7e4239fSAsiri Rathnayake 38358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 38458a0dceeSSaleem Abdulrasool{ 38558a0dceeSSaleem Abdulrasool return pthread_mutex_lock(__m); 38658a0dceeSSaleem Abdulrasool} 38758a0dceeSSaleem Abdulrasool 38808e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 38958a0dceeSSaleem Abdulrasool{ 39008e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 39158a0dceeSSaleem Abdulrasool} 39258a0dceeSSaleem Abdulrasool 393*ebfadd82SColin Finckint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m) 39458a0dceeSSaleem Abdulrasool{ 39558a0dceeSSaleem Abdulrasool return pthread_mutex_unlock(__m); 39658a0dceeSSaleem Abdulrasool} 39758a0dceeSSaleem Abdulrasool 39858a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 39958a0dceeSSaleem Abdulrasool{ 40058a0dceeSSaleem Abdulrasool return pthread_mutex_destroy(__m); 40158a0dceeSSaleem Abdulrasool} 40258a0dceeSSaleem Abdulrasool 403c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 404c7e4239fSAsiri Rathnayake{ 405c7e4239fSAsiri Rathnayake return pthread_mutex_lock(__m); 406c7e4239fSAsiri Rathnayake} 407c7e4239fSAsiri Rathnayake 40808e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 409c7e4239fSAsiri Rathnayake{ 41008e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 411c7e4239fSAsiri Rathnayake} 412c7e4239fSAsiri Rathnayake 413c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 414c7e4239fSAsiri Rathnayake{ 415c7e4239fSAsiri Rathnayake return pthread_mutex_unlock(__m); 416c7e4239fSAsiri Rathnayake} 417c7e4239fSAsiri Rathnayake 418c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 419c7e4239fSAsiri Rathnayake{ 420c7e4239fSAsiri Rathnayake return pthread_mutex_destroy(__m); 421c7e4239fSAsiri Rathnayake} 422c7e4239fSAsiri Rathnayake 423790e10f6SSaleem Abdulrasool// Condition Variable 424c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 425c7e4239fSAsiri Rathnayake{ 426c7e4239fSAsiri Rathnayake return pthread_cond_signal(__cv); 427c7e4239fSAsiri Rathnayake} 428c7e4239fSAsiri Rathnayake 429c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 430c7e4239fSAsiri Rathnayake{ 431c7e4239fSAsiri Rathnayake return pthread_cond_broadcast(__cv); 432c7e4239fSAsiri Rathnayake} 433c7e4239fSAsiri Rathnayake 434c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 435c7e4239fSAsiri Rathnayake{ 436c7e4239fSAsiri Rathnayake return pthread_cond_wait(__cv, __m); 437c7e4239fSAsiri Rathnayake} 438c7e4239fSAsiri Rathnayake 439790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 440cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts) 441c7e4239fSAsiri Rathnayake{ 442c7e4239fSAsiri Rathnayake return pthread_cond_timedwait(__cv, __m, __ts); 443c7e4239fSAsiri Rathnayake} 444c7e4239fSAsiri Rathnayake 445c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 446c7e4239fSAsiri Rathnayake{ 447c7e4239fSAsiri Rathnayake return pthread_cond_destroy(__cv); 448c7e4239fSAsiri Rathnayake} 449c7e4239fSAsiri Rathnayake 45054fa9ecdSOlivier Giroux#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES 45154fa9ecdSOlivier Giroux 45254fa9ecdSOlivier Giroux// Semaphore 45354fa9ecdSOlivier Girouxbool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init) 45454fa9ecdSOlivier Giroux{ 45554fa9ecdSOlivier Giroux return sem_init(__sem, 0, __init) == 0; 45654fa9ecdSOlivier Giroux} 45754fa9ecdSOlivier Giroux 45854fa9ecdSOlivier Girouxbool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem) 45954fa9ecdSOlivier Giroux{ 46054fa9ecdSOlivier Giroux return sem_destroy(__sem) == 0; 46154fa9ecdSOlivier Giroux} 46254fa9ecdSOlivier Giroux 46354fa9ecdSOlivier Girouxbool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem) 46454fa9ecdSOlivier Giroux{ 46554fa9ecdSOlivier Giroux return sem_post(__sem) == 0; 46654fa9ecdSOlivier Giroux} 46754fa9ecdSOlivier Giroux 46854fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem) 46954fa9ecdSOlivier Giroux{ 47054fa9ecdSOlivier Giroux return sem_wait(__sem) == 0; 47154fa9ecdSOlivier Giroux} 47254fa9ecdSOlivier Giroux 47354fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns) 47454fa9ecdSOlivier Giroux{ 47554fa9ecdSOlivier Giroux auto const __abs_time = chrono::system_clock::now().time_since_epoch() + __ns; 47654fa9ecdSOlivier Giroux __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__abs_time); 47754fa9ecdSOlivier Giroux return sem_timedwait(__sem, &__ts) == 0; 47854fa9ecdSOlivier Giroux} 47954fa9ecdSOlivier Giroux 48054fa9ecdSOlivier Giroux#endif //_LIBCPP_NO_NATIVE_SEMAPHORES 48154fa9ecdSOlivier Giroux 482205d7d3fSAsiri Rathnayake// Execute once 483205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 4844603460aSBruce Mitchener void (*init_routine)()) { 485205d7d3fSAsiri Rathnayake return pthread_once(flag, init_routine); 486205d7d3fSAsiri Rathnayake} 487205d7d3fSAsiri Rathnayake 488205d7d3fSAsiri Rathnayake// Thread id 489c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0 490c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 491c7e4239fSAsiri Rathnayake{ 492e6c89a49SZbigniew Sarbinowski return t1 == t2; 493c7e4239fSAsiri Rathnayake} 494c7e4239fSAsiri Rathnayake 495c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0 496c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 497c7e4239fSAsiri Rathnayake{ 498c7e4239fSAsiri Rathnayake return t1 < t2; 499c7e4239fSAsiri Rathnayake} 500c7e4239fSAsiri Rathnayake 501c7e4239fSAsiri Rathnayake// Thread 502af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 503527a7fdfSBruce Mitchener return *__t == __libcpp_thread_t(); 504af762e91SAsiri Rathnayake} 505af762e91SAsiri Rathnayake 506790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 507790e10f6SSaleem Abdulrasool void *__arg) 508c7e4239fSAsiri Rathnayake{ 509527a7fdfSBruce Mitchener return pthread_create(__t, nullptr, __func, __arg); 510c7e4239fSAsiri Rathnayake} 511c7e4239fSAsiri Rathnayake 512c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id() 513c7e4239fSAsiri Rathnayake{ 514e6c89a49SZbigniew Sarbinowski const __libcpp_thread_t thread = pthread_self(); 515e6c89a49SZbigniew Sarbinowski return __libcpp_thread_get_id(&thread); 516c7e4239fSAsiri Rathnayake} 517c7e4239fSAsiri Rathnayake 518c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 519c7e4239fSAsiri Rathnayake{ 520e6c89a49SZbigniew Sarbinowski#if defined(__MVS__) 521e6c89a49SZbigniew Sarbinowski return __t->__; 522e6c89a49SZbigniew Sarbinowski#else 523c7e4239fSAsiri Rathnayake return *__t; 524e6c89a49SZbigniew Sarbinowski#endif 525c7e4239fSAsiri Rathnayake} 526c7e4239fSAsiri Rathnayake 527c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t) 528c7e4239fSAsiri Rathnayake{ 529527a7fdfSBruce Mitchener return pthread_join(*__t, nullptr); 530c7e4239fSAsiri Rathnayake} 531c7e4239fSAsiri Rathnayake 532c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t) 533c7e4239fSAsiri Rathnayake{ 534c7e4239fSAsiri Rathnayake return pthread_detach(*__t); 535c7e4239fSAsiri Rathnayake} 536c7e4239fSAsiri Rathnayake 537c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield() 538c7e4239fSAsiri Rathnayake{ 539c7e4239fSAsiri Rathnayake sched_yield(); 540c7e4239fSAsiri Rathnayake} 541c7e4239fSAsiri Rathnayake 54254a987e1SAsiri Rathnayakevoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 54354a987e1SAsiri Rathnayake{ 544ab9aefeeSPetr Hosek __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); 54554a987e1SAsiri Rathnayake while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); 54654a987e1SAsiri Rathnayake} 54754a987e1SAsiri Rathnayake 548c7e4239fSAsiri Rathnayake// Thread local storage 5498c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 550c7e4239fSAsiri Rathnayake{ 551c7e4239fSAsiri Rathnayake return pthread_key_create(__key, __at_exit); 552c7e4239fSAsiri Rathnayake} 553c7e4239fSAsiri Rathnayake 5548c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key) 555c7e4239fSAsiri Rathnayake{ 556c7e4239fSAsiri Rathnayake return pthread_getspecific(__key); 557c7e4239fSAsiri Rathnayake} 558c7e4239fSAsiri Rathnayake 559205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 560c7e4239fSAsiri Rathnayake{ 561205d7d3fSAsiri Rathnayake return pthread_setspecific(__key, __p); 562c7e4239fSAsiri Rathnayake} 563c7e4239fSAsiri Rathnayake 564ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 565ab9aefeeSPetr Hosek 566ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 567ab9aefeeSPetr Hosek{ 5683481e5d7SPetr Hosek return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL; 569ab9aefeeSPetr Hosek} 570ab9aefeeSPetr Hosek 571ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 572ab9aefeeSPetr Hosek{ 573ab9aefeeSPetr Hosek return mtx_lock(__m) == thrd_success ? 0 : EINVAL; 574ab9aefeeSPetr Hosek} 575ab9aefeeSPetr Hosek 576ab9aefeeSPetr Hosekbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 577ab9aefeeSPetr Hosek{ 578ab9aefeeSPetr Hosek return mtx_trylock(__m) == thrd_success; 579ab9aefeeSPetr Hosek} 580ab9aefeeSPetr Hosek 581*ebfadd82SColin Finckint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m) 582ab9aefeeSPetr Hosek{ 583ab9aefeeSPetr Hosek return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; 584ab9aefeeSPetr Hosek} 585ab9aefeeSPetr Hosek 586ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 587ab9aefeeSPetr Hosek{ 588ab9aefeeSPetr Hosek mtx_destroy(__m); 589ab9aefeeSPetr Hosek return 0; 590ab9aefeeSPetr Hosek} 591ab9aefeeSPetr Hosek 592ab9aefeeSPetr Hosekint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 593ab9aefeeSPetr Hosek{ 594ab9aefeeSPetr Hosek return mtx_lock(__m) == thrd_success ? 0 : EINVAL; 595ab9aefeeSPetr Hosek} 596ab9aefeeSPetr Hosek 597ab9aefeeSPetr Hosekbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 598ab9aefeeSPetr Hosek{ 599ab9aefeeSPetr Hosek return mtx_trylock(__m) == thrd_success; 600ab9aefeeSPetr Hosek} 601ab9aefeeSPetr Hosek 602ab9aefeeSPetr Hosekint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 603ab9aefeeSPetr Hosek{ 604ab9aefeeSPetr Hosek return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; 605ab9aefeeSPetr Hosek} 606ab9aefeeSPetr Hosek 607ab9aefeeSPetr Hosekint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 608ab9aefeeSPetr Hosek{ 609ab9aefeeSPetr Hosek mtx_destroy(__m); 610ab9aefeeSPetr Hosek return 0; 611ab9aefeeSPetr Hosek} 612ab9aefeeSPetr Hosek 613ab9aefeeSPetr Hosek// Condition Variable 614ab9aefeeSPetr Hosekint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 615ab9aefeeSPetr Hosek{ 616ab9aefeeSPetr Hosek return cnd_signal(__cv) == thrd_success ? 0 : EINVAL; 617ab9aefeeSPetr Hosek} 618ab9aefeeSPetr Hosek 619ab9aefeeSPetr Hosekint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 620ab9aefeeSPetr Hosek{ 621ab9aefeeSPetr Hosek return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL; 622ab9aefeeSPetr Hosek} 623ab9aefeeSPetr Hosek 624ab9aefeeSPetr Hosekint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 625ab9aefeeSPetr Hosek{ 626ab9aefeeSPetr Hosek return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL; 627ab9aefeeSPetr Hosek} 628ab9aefeeSPetr Hosek 629ab9aefeeSPetr Hosekint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 630ab9aefeeSPetr Hosek timespec *__ts) 631ab9aefeeSPetr Hosek{ 632ab9aefeeSPetr Hosek int __ec = cnd_timedwait(__cv, __m, __ts); 633ab9aefeeSPetr Hosek return __ec == thrd_timedout ? ETIMEDOUT : __ec; 634ab9aefeeSPetr Hosek} 635ab9aefeeSPetr Hosek 636ab9aefeeSPetr Hosekint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 637ab9aefeeSPetr Hosek{ 638ab9aefeeSPetr Hosek cnd_destroy(__cv); 639ab9aefeeSPetr Hosek return 0; 640ab9aefeeSPetr Hosek} 641ab9aefeeSPetr Hosek 642ab9aefeeSPetr Hosek// Execute once 643ab9aefeeSPetr Hosekint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 644ab9aefeeSPetr Hosek void (*init_routine)(void)) { 645ab9aefeeSPetr Hosek ::call_once(flag, init_routine); 646ab9aefeeSPetr Hosek return 0; 647ab9aefeeSPetr Hosek} 648ab9aefeeSPetr Hosek 649ab9aefeeSPetr Hosek// Thread id 650ab9aefeeSPetr Hosek// Returns non-zero if the thread ids are equal, otherwise 0 651ab9aefeeSPetr Hosekbool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 652ab9aefeeSPetr Hosek{ 653ab9aefeeSPetr Hosek return thrd_equal(t1, t2) != 0; 654ab9aefeeSPetr Hosek} 655ab9aefeeSPetr Hosek 656ab9aefeeSPetr Hosek// Returns non-zero if t1 < t2, otherwise 0 657ab9aefeeSPetr Hosekbool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 658ab9aefeeSPetr Hosek{ 659ab9aefeeSPetr Hosek return t1 < t2; 660ab9aefeeSPetr Hosek} 661ab9aefeeSPetr Hosek 662ab9aefeeSPetr Hosek// Thread 663ab9aefeeSPetr Hosekbool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 664e6c89a49SZbigniew Sarbinowski return __libcpp_thread_get_id(__t) == 0; 665ab9aefeeSPetr Hosek} 666ab9aefeeSPetr Hosek 667ab9aefeeSPetr Hosekint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 668ab9aefeeSPetr Hosek void *__arg) 669ab9aefeeSPetr Hosek{ 670ab9aefeeSPetr Hosek int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg); 671ab9aefeeSPetr Hosek return __ec == thrd_nomem ? ENOMEM : __ec; 672ab9aefeeSPetr Hosek} 673ab9aefeeSPetr Hosek 674ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_current_id() 675ab9aefeeSPetr Hosek{ 676ab9aefeeSPetr Hosek return thrd_current(); 677ab9aefeeSPetr Hosek} 678ab9aefeeSPetr Hosek 679ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 680ab9aefeeSPetr Hosek{ 681ab9aefeeSPetr Hosek return *__t; 682ab9aefeeSPetr Hosek} 683ab9aefeeSPetr Hosek 684ab9aefeeSPetr Hosekint __libcpp_thread_join(__libcpp_thread_t *__t) 685ab9aefeeSPetr Hosek{ 686ab9aefeeSPetr Hosek return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL; 687ab9aefeeSPetr Hosek} 688ab9aefeeSPetr Hosek 689ab9aefeeSPetr Hosekint __libcpp_thread_detach(__libcpp_thread_t *__t) 690ab9aefeeSPetr Hosek{ 691ab9aefeeSPetr Hosek return thrd_detach(*__t) == thrd_success ? 0 : EINVAL; 692ab9aefeeSPetr Hosek} 693ab9aefeeSPetr Hosek 694ab9aefeeSPetr Hosekvoid __libcpp_thread_yield() 695ab9aefeeSPetr Hosek{ 696ab9aefeeSPetr Hosek thrd_yield(); 697ab9aefeeSPetr Hosek} 698ab9aefeeSPetr Hosek 699ab9aefeeSPetr Hosekvoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 700ab9aefeeSPetr Hosek{ 701ab9aefeeSPetr Hosek __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); 702ab9aefeeSPetr Hosek thrd_sleep(&__ts, nullptr); 703ab9aefeeSPetr Hosek} 704ab9aefeeSPetr Hosek 705ab9aefeeSPetr Hosek// Thread local storage 706ab9aefeeSPetr Hosekint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 707ab9aefeeSPetr Hosek{ 708ab9aefeeSPetr Hosek return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL; 709ab9aefeeSPetr Hosek} 710ab9aefeeSPetr Hosek 711ab9aefeeSPetr Hosekvoid *__libcpp_tls_get(__libcpp_tls_key __key) 712ab9aefeeSPetr Hosek{ 713ab9aefeeSPetr Hosek return tss_get(__key); 714ab9aefeeSPetr Hosek} 715ab9aefeeSPetr Hosek 716ab9aefeeSPetr Hosekint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 717ab9aefeeSPetr Hosek{ 718ab9aefeeSPetr Hosek return tss_set(__key, __p) == thrd_success ? 0 : EINVAL; 719ab9aefeeSPetr Hosek} 720ab9aefeeSPetr Hosek 721ab9aefeeSPetr Hosek#endif 722ab9aefeeSPetr Hosek 723e3add3e5SMartin Storsjö 72400f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL 72500f6beaeSEric Fiselier 7262b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS thread; 7272b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS __thread_id; 7282b1d4254SMarshall Clow 7292b1d4254SMarshall Clownamespace this_thread 7302b1d4254SMarshall Clow{ 7312b1d4254SMarshall Clow 7322b1d4254SMarshall Clow_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; 7332b1d4254SMarshall Clow 7342b1d4254SMarshall Clow} // this_thread 7352b1d4254SMarshall Clow 7362b1d4254SMarshall Clowtemplate<> struct hash<__thread_id>; 7372b1d4254SMarshall Clow 7382b1d4254SMarshall Clowclass _LIBCPP_TEMPLATE_VIS __thread_id 7392b1d4254SMarshall Clow{ 7402b1d4254SMarshall Clow // FIXME: pthread_t is a pointer on Darwin but a long on Linux. 7412b1d4254SMarshall Clow // NULL is the no-thread value on Darwin. Someone needs to check 7422b1d4254SMarshall Clow // on other platforms. We assume 0 works everywhere for now. 7432b1d4254SMarshall Clow __libcpp_thread_id __id_; 7442b1d4254SMarshall Clow 7452b1d4254SMarshall Clowpublic: 7462b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7472b1d4254SMarshall Clow __thread_id() _NOEXCEPT : __id_(0) {} 7482b1d4254SMarshall Clow 7492b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7502b1d4254SMarshall Clow bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT 7512e80d01fSMarshall Clow { // don't pass id==0 to underlying routines 7522e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ == 0; 7532e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 7542e80d01fSMarshall Clow return __libcpp_thread_id_equal(__x.__id_, __y.__id_); 7552e80d01fSMarshall Clow } 7562b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7572b1d4254SMarshall Clow bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT 7582b1d4254SMarshall Clow {return !(__x == __y);} 7592b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7602b1d4254SMarshall Clow bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT 7612e80d01fSMarshall Clow { // id==0 is always less than any other thread_id 7622e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ != 0; 7632e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 7642e80d01fSMarshall Clow return __libcpp_thread_id_less(__x.__id_, __y.__id_); 7652e80d01fSMarshall Clow } 7662b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7672b1d4254SMarshall Clow bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT 7682b1d4254SMarshall Clow {return !(__y < __x);} 7692b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7702b1d4254SMarshall Clow bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT 7712b1d4254SMarshall Clow {return __y < __x ;} 7722b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7732b1d4254SMarshall Clow bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT 7742b1d4254SMarshall Clow {return !(__x < __y);} 7752b1d4254SMarshall Clow 7762b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7772e80d01fSMarshall Clow void __reset() { __id_ = 0; } 7782b1d4254SMarshall Clow 7792b1d4254SMarshall Clow template<class _CharT, class _Traits> 7802b1d4254SMarshall Clow friend 7812b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7822b1d4254SMarshall Clow basic_ostream<_CharT, _Traits>& 7832b1d4254SMarshall Clow operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); 7842b1d4254SMarshall Clow 7852b1d4254SMarshall Clowprivate: 7862b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7872b1d4254SMarshall Clow __thread_id(__libcpp_thread_id __id) : __id_(__id) {} 7882b1d4254SMarshall Clow 7892b1d4254SMarshall Clow friend __thread_id this_thread::get_id() _NOEXCEPT; 7902b1d4254SMarshall Clow friend class _LIBCPP_TYPE_VIS thread; 7912b1d4254SMarshall Clow friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; 7922b1d4254SMarshall Clow}; 7932b1d4254SMarshall Clow 7942b1d4254SMarshall Clownamespace this_thread 7952b1d4254SMarshall Clow{ 7962b1d4254SMarshall Clow 7972b1d4254SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY 7982b1d4254SMarshall Clow__thread_id 7992b1d4254SMarshall Clowget_id() _NOEXCEPT 8002b1d4254SMarshall Clow{ 8012b1d4254SMarshall Clow return __libcpp_thread_get_current_id(); 8022b1d4254SMarshall Clow} 8032b1d4254SMarshall Clow 8042b1d4254SMarshall Clow} // this_thread 8052b1d4254SMarshall Clow 806696630eaSMarshall Clow#endif // !_LIBCPP_HAS_NO_THREADS 807696630eaSMarshall Clow 808c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD 809c7e4239fSAsiri Rathnayake 810a016efb1SEric Fiselier_LIBCPP_POP_MACROS 811a016efb1SEric Fiselier 812c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT 813