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 132eadbc86SLouis Dionne#include <__availability> 14*bfbd73f8SArthur O'Dwyer#include <__config> 1554a987e1SAsiri Rathnayake#include <chrono> 1654a987e1SAsiri Rathnayake#include <errno.h> 17*bfbd73f8SArthur O'Dwyer#include <iosfwd> 181773eec6SMartin Storsjö#include <limits> 19c7e4239fSAsiri Rathnayake 206a8099e0SZbigniew Sarbinowski#ifdef __MVS__ 21b5175681SLouis Dionne# include <__support/ibm/nanosleep.h> 226a8099e0SZbigniew Sarbinowski#endif 236a8099e0SZbigniew Sarbinowski 24c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER 25c7e4239fSAsiri Rathnayake#pragma GCC system_header 26c7e4239fSAsiri Rathnayake#endif 27c7e4239fSAsiri Rathnayake 2800f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 293cf2f7bcSAsiri Rathnayake# include <__external_threading> 3000f6beaeSEric Fiselier#elif !defined(_LIBCPP_HAS_NO_THREADS) 31790e10f6SSaleem Abdulrasool 3200f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 33c7e4239fSAsiri Rathnayake# include <pthread.h> 34c7e4239fSAsiri Rathnayake# include <sched.h> 35e6c89a49SZbigniew Sarbinowski# if defined(__APPLE__) || defined(__MVS__) 3654fa9ecdSOlivier Giroux# define _LIBCPP_NO_NATIVE_SEMAPHORES 3754fa9ecdSOlivier Giroux# endif 3862138846Sogiroux# ifndef _LIBCPP_NO_NATIVE_SEMAPHORES 3962138846Sogiroux# include <semaphore.h> 4062138846Sogiroux# endif 41ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 42ab9aefeeSPetr Hosek# include <threads.h> 43790e10f6SSaleem Abdulrasool#endif 44c7e4239fSAsiri Rathnayake 452a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 462a129dc3SPeter Collingbourne defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \ 472a129dc3SPeter Collingbourne defined(_LIBCPP_HAS_THREAD_API_WIN32) 482a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS 492a129dc3SPeter Collingbourne#else 502a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY 512a129dc3SPeter Collingbourne#endif 522a129dc3SPeter Collingbourne 5383dca5c3SDimitry Andric#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis) 5483dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) 5583dca5c3SDimitry Andric#else 5683dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 5783dca5c3SDimitry Andric#endif 5883dca5c3SDimitry Andric 59696630eaSMarshall Clowtypedef ::timespec __libcpp_timespec_t; 60696630eaSMarshall Clow#endif // !defined(_LIBCPP_HAS_NO_THREADS) 61696630eaSMarshall Clow 62696630eaSMarshall Clow_LIBCPP_PUSH_MACROS 63696630eaSMarshall Clow#include <__undef_macros> 64696630eaSMarshall Clow 65c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD 66c7e4239fSAsiri Rathnayake 67696630eaSMarshall Clow#if !defined(_LIBCPP_HAS_NO_THREADS) 68696630eaSMarshall Clow 692a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 70c7e4239fSAsiri Rathnayake// Mutex 71c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t; 728c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 73c7e4239fSAsiri Rathnayake 7458a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t; 7558a0dceeSSaleem Abdulrasool 76790e10f6SSaleem Abdulrasool// Condition Variable 77790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t; 78790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER 79790e10f6SSaleem Abdulrasool 8062138846Sogiroux#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES 8154fa9ecdSOlivier Giroux// Semaphore 8254fa9ecdSOlivier Girouxtypedef sem_t __libcpp_semaphore_t; 8354fa9ecdSOlivier Giroux# define _LIBCPP_SEMAPHORE_MAX SEM_VALUE_MAX 8462138846Sogiroux#endif 8554fa9ecdSOlivier Giroux 86205d7d3fSAsiri Rathnayake// Execute once 87205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag; 88205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT 89205d7d3fSAsiri Rathnayake 90205d7d3fSAsiri Rathnayake// Thread id 91e6c89a49SZbigniew Sarbinowski#if defined(__MVS__) 92e6c89a49SZbigniew Sarbinowski typedef unsigned long long __libcpp_thread_id; 93e6c89a49SZbigniew Sarbinowski#else 94790e10f6SSaleem Abdulrasool typedef pthread_t __libcpp_thread_id; 95e6c89a49SZbigniew Sarbinowski#endif 96790e10f6SSaleem Abdulrasool 97790e10f6SSaleem Abdulrasool// Thread 98e6c89a49SZbigniew Sarbinowski#define _LIBCPP_NULL_THREAD ((__libcpp_thread_t())) 99790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t; 100790e10f6SSaleem Abdulrasool 101cac6d217SFangrui Song// Thread Local Storage 102790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key; 1036d7d0becSSaleem Abdulrasool 1046d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC 105ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 106ab9aefeeSPetr Hosek// Mutex 107ab9aefeeSPetr Hosektypedef mtx_t __libcpp_mutex_t; 108ab9aefeeSPetr Hosek// mtx_t is a struct so using {} for initialization is valid. 109ab9aefeeSPetr Hosek#define _LIBCPP_MUTEX_INITIALIZER {} 110ab9aefeeSPetr Hosek 111ab9aefeeSPetr Hosektypedef mtx_t __libcpp_recursive_mutex_t; 112ab9aefeeSPetr Hosek 113ab9aefeeSPetr Hosek// Condition Variable 114ab9aefeeSPetr Hosektypedef cnd_t __libcpp_condvar_t; 115ab9aefeeSPetr Hosek// cnd_t is a struct so using {} for initialization is valid. 116ab9aefeeSPetr Hosek#define _LIBCPP_CONDVAR_INITIALIZER {} 117ab9aefeeSPetr Hosek 118ab9aefeeSPetr Hosek// Execute once 119ab9aefeeSPetr Hosektypedef once_flag __libcpp_exec_once_flag; 120ab9aefeeSPetr Hosek#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT 121ab9aefeeSPetr Hosek 122ab9aefeeSPetr Hosek// Thread id 123ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_id; 124ab9aefeeSPetr Hosek 125ab9aefeeSPetr Hosek// Thread 126ab9aefeeSPetr Hosek#define _LIBCPP_NULL_THREAD 0U 127ab9aefeeSPetr Hosek 128ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_t; 129ab9aefeeSPetr Hosek 130ab9aefeeSPetr Hosek// Thread Local Storage 131ab9aefeeSPetr Hosektypedef tss_t __libcpp_tls_key; 132ab9aefeeSPetr Hosek 133ab9aefeeSPetr Hosek#define _LIBCPP_TLS_DESTRUCTOR_CC 134e2b200b7SDavid Spickett#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 135ac15ae6dSPeter Collingbourne// Mutex 136ac15ae6dSPeter Collingbournetypedef void* __libcpp_mutex_t; 137ac15ae6dSPeter Collingbourne#define _LIBCPP_MUTEX_INITIALIZER 0 138ac15ae6dSPeter Collingbourne 139ac15ae6dSPeter Collingbourne#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) 140ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[6]; 141ac15ae6dSPeter Collingbourne#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__) 142ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[5]; 143ac15ae6dSPeter Collingbourne#else 144ac15ae6dSPeter Collingbourne# error Unsupported architecture 145ac15ae6dSPeter Collingbourne#endif 1466d7d0becSSaleem Abdulrasool 1476d7d0becSSaleem Abdulrasool// Condition Variable 148ac15ae6dSPeter Collingbournetypedef void* __libcpp_condvar_t; 149ac15ae6dSPeter Collingbourne#define _LIBCPP_CONDVAR_INITIALIZER 0 1506d7d0becSSaleem Abdulrasool 15154fa9ecdSOlivier Giroux// Semaphore 15254fa9ecdSOlivier Girouxtypedef void* __libcpp_semaphore_t; 1531773eec6SMartin Storsjö#if defined(_LIBCPP_HAS_THREAD_API_WIN32) 1541773eec6SMartin Storsjö# define _LIBCPP_SEMAPHORE_MAX (::std::numeric_limits<long>::max()) 1551773eec6SMartin Storsjö#endif 15654fa9ecdSOlivier Giroux 1576d7d0becSSaleem Abdulrasool// Execute Once 158ac15ae6dSPeter Collingbournetypedef void* __libcpp_exec_once_flag; 159ac15ae6dSPeter Collingbourne#define _LIBCPP_EXEC_ONCE_INITIALIZER 0 1606d7d0becSSaleem Abdulrasool 1616d7d0becSSaleem Abdulrasool// Thread ID 162ac15ae6dSPeter Collingbournetypedef long __libcpp_thread_id; 1636d7d0becSSaleem Abdulrasool 1646d7d0becSSaleem Abdulrasool// Thread 165af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 166af762e91SAsiri Rathnayake 167ac15ae6dSPeter Collingbournetypedef void* __libcpp_thread_t; 1686d7d0becSSaleem Abdulrasool 1696d7d0becSSaleem Abdulrasool// Thread Local Storage 170ac15ae6dSPeter Collingbournetypedef long __libcpp_tls_key; 1716d7d0becSSaleem Abdulrasool 172ac15ae6dSPeter Collingbourne#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall 173e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 174790e10f6SSaleem Abdulrasool 175e2b200b7SDavid Spickett#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 176790e10f6SSaleem Abdulrasool// Mutex 1778c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 17858a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); 17958a0dceeSSaleem Abdulrasool 18083dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 18158a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m); 18258a0dceeSSaleem Abdulrasool 18383dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 18408e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m); 18558a0dceeSSaleem Abdulrasool 18683dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 18758a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m); 18858a0dceeSSaleem Abdulrasool 18958a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY 19058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m); 191790e10f6SSaleem Abdulrasool 19283dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1938c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m); 194790e10f6SSaleem Abdulrasool 19583dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 19608e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m); 197790e10f6SSaleem Abdulrasool 19883dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1998c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m); 200790e10f6SSaleem Abdulrasool 2018c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2028c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m); 2038c2bf45dSAsiri Rathnayake 2048c2bf45dSAsiri Rathnayake// Condition variable 2058c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2068c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv); 207790e10f6SSaleem Abdulrasool 2088c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2098c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv); 210790e10f6SSaleem Abdulrasool 21183dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 2128c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m); 213790e10f6SSaleem Abdulrasool 21483dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 215790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 216cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts); 217790e10f6SSaleem Abdulrasool 2188c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2198c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); 2208c2bf45dSAsiri Rathnayake 22162138846Sogiroux#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES 22262138846Sogiroux 22354fa9ecdSOlivier Giroux// Semaphore 22454fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 22554fa9ecdSOlivier Girouxbool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init); 22654fa9ecdSOlivier Giroux 22754fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 22854fa9ecdSOlivier Girouxbool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem); 22954fa9ecdSOlivier Giroux 23054fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 23154fa9ecdSOlivier Girouxbool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem); 23254fa9ecdSOlivier Giroux 23354fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 23454fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem); 23554fa9ecdSOlivier Giroux 23654fa9ecdSOlivier Giroux_LIBCPP_THREAD_ABI_VISIBILITY 23754fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns); 23854fa9ecdSOlivier Giroux 23962138846Sogiroux#endif // _LIBCPP_NO_NATIVE_SEMAPHORES 24062138846Sogiroux 241205d7d3fSAsiri Rathnayake// Execute once 242205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 243205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 2444603460aSBruce Mitchener void (*init_routine)()); 245205d7d3fSAsiri Rathnayake 246205d7d3fSAsiri Rathnayake// Thread id 2478c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2488c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); 249790e10f6SSaleem Abdulrasool 2508c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2518c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); 2528c2bf45dSAsiri Rathnayake 2538c2bf45dSAsiri Rathnayake// Thread 2548c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 255af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t); 256af762e91SAsiri Rathnayake 257af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 258790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 259790e10f6SSaleem Abdulrasool void *__arg); 260790e10f6SSaleem Abdulrasool 2618c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2628c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id(); 263790e10f6SSaleem Abdulrasool 2648c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2658c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); 266790e10f6SSaleem Abdulrasool 2678c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2688c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t); 269790e10f6SSaleem Abdulrasool 2708c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2718c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t); 272790e10f6SSaleem Abdulrasool 2738c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2748c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield(); 2758c2bf45dSAsiri Rathnayake 27654a987e1SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2779e8a082dSJoerg Sonnenbergervoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns); 27854a987e1SAsiri Rathnayake 2798c2bf45dSAsiri Rathnayake// Thread local storage 2808c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2816d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key, 2826d7d0becSSaleem Abdulrasool void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)); 283790e10f6SSaleem Abdulrasool 2848c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2858c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key); 286790e10f6SSaleem Abdulrasool 2878c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 288205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p); 2898c2bf45dSAsiri Rathnayake 290e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 291e2b200b7SDavid Spickett 29214aef536SMikhail Maltsevstruct __libcpp_timed_backoff_policy { 29321a1a263SLouis Dionne _LIBCPP_INLINE_VISIBILITY 29421a1a263SLouis Dionne bool operator()(chrono::nanoseconds __elapsed) const 2953411a1a9SDavid Nicuesa { 2963411a1a9SDavid Nicuesa if(__elapsed > chrono::milliseconds(128)) 2973411a1a9SDavid Nicuesa __libcpp_thread_sleep_for(chrono::milliseconds(8)); 2983411a1a9SDavid Nicuesa else if(__elapsed > chrono::microseconds(64)) 2993411a1a9SDavid Nicuesa __libcpp_thread_sleep_for(__elapsed / 2); 3003411a1a9SDavid Nicuesa else if(__elapsed > chrono::microseconds(4)) 3013411a1a9SDavid Nicuesa __libcpp_thread_yield(); 3023411a1a9SDavid Nicuesa else 303d2acf229SMarek Kurdej {} // poll 3043411a1a9SDavid Nicuesa return false; 3053411a1a9SDavid Nicuesa } 30621a1a263SLouis Dionne}; 3073411a1a9SDavid Nicuesa 3083411a1a9SDavid Nicuesastatic _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64; 3093411a1a9SDavid Nicuesa 31014aef536SMikhail Maltsevtemplate<class _Fn, class _BFn> 31146c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 31214aef536SMikhail Maltsevbool __libcpp_thread_poll_with_backoff( 3133411a1a9SDavid Nicuesa _Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()) 3143411a1a9SDavid Nicuesa{ 3153411a1a9SDavid Nicuesa auto const __start = chrono::high_resolution_clock::now(); 3163411a1a9SDavid Nicuesa for(int __count = 0;;) { 3173411a1a9SDavid Nicuesa if(__f()) 3183411a1a9SDavid Nicuesa return true; // _Fn completion means success 3193411a1a9SDavid Nicuesa if(__count < __libcpp_polling_count) { 3203411a1a9SDavid Nicuesa __count += 1; 3213411a1a9SDavid Nicuesa continue; 3223411a1a9SDavid Nicuesa } 3233411a1a9SDavid Nicuesa chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start; 3243411a1a9SDavid Nicuesa if(__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed) 3253411a1a9SDavid Nicuesa return false; // timeout failure 3263411a1a9SDavid Nicuesa if(__bf(__elapsed)) 3273411a1a9SDavid Nicuesa return false; // _BFn completion means failure 3283411a1a9SDavid Nicuesa } 3293411a1a9SDavid Nicuesa} 3303411a1a9SDavid Nicuesa 3313411a1a9SDavid Nicuesa#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 3323411a1a9SDavid Nicuesa defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) 3333411a1a9SDavid Nicuesa 33414aef536SMikhail Maltsev 335ab9aefeeSPetr Hoseknamespace __thread_detail { 336ab9aefeeSPetr Hosek 337ab9aefeeSPetr Hosekinline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) 338ab9aefeeSPetr Hosek{ 339ab9aefeeSPetr Hosek using namespace chrono; 340ab9aefeeSPetr Hosek seconds __s = duration_cast<seconds>(__ns); 341ab9aefeeSPetr Hosek __libcpp_timespec_t __ts; 342ab9aefeeSPetr Hosek typedef decltype(__ts.tv_sec) __ts_sec; 343ab9aefeeSPetr Hosek const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); 344ab9aefeeSPetr Hosek 345ab9aefeeSPetr Hosek if (__s.count() < __ts_sec_max) 346ab9aefeeSPetr Hosek { 347ab9aefeeSPetr Hosek __ts.tv_sec = static_cast<__ts_sec>(__s.count()); 348ab9aefeeSPetr Hosek __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); 349ab9aefeeSPetr Hosek } 350ab9aefeeSPetr Hosek else 351ab9aefeeSPetr Hosek { 352ab9aefeeSPetr Hosek __ts.tv_sec = __ts_sec_max; 353ab9aefeeSPetr Hosek __ts.tv_nsec = 999999999; // (10^9 - 1) 354ab9aefeeSPetr Hosek } 355ab9aefeeSPetr Hosek 356ab9aefeeSPetr Hosek return __ts; 357ab9aefeeSPetr Hosek} 358ab9aefeeSPetr Hosek 359ab9aefeeSPetr Hosek} 360ab9aefeeSPetr Hosek 361ab9aefeeSPetr Hosek#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 3628c2bf45dSAsiri Rathnayake 36358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 364c7e4239fSAsiri Rathnayake{ 365c7e4239fSAsiri Rathnayake pthread_mutexattr_t attr; 366c7e4239fSAsiri Rathnayake int __ec = pthread_mutexattr_init(&attr); 367c7e4239fSAsiri Rathnayake if (__ec) 368790e10f6SSaleem Abdulrasool return __ec; 369790e10f6SSaleem Abdulrasool __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 370790e10f6SSaleem Abdulrasool if (__ec) { 371c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 372c7e4239fSAsiri Rathnayake return __ec; 373c7e4239fSAsiri Rathnayake } 374c7e4239fSAsiri Rathnayake __ec = pthread_mutex_init(__m, &attr); 375790e10f6SSaleem Abdulrasool if (__ec) { 376c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 377c7e4239fSAsiri Rathnayake return __ec; 378c7e4239fSAsiri Rathnayake } 379c7e4239fSAsiri Rathnayake __ec = pthread_mutexattr_destroy(&attr); 380790e10f6SSaleem Abdulrasool if (__ec) { 381c7e4239fSAsiri Rathnayake pthread_mutex_destroy(__m); 382c7e4239fSAsiri Rathnayake return __ec; 383c7e4239fSAsiri Rathnayake } 384c7e4239fSAsiri Rathnayake return 0; 385c7e4239fSAsiri Rathnayake} 386c7e4239fSAsiri Rathnayake 38758a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 38858a0dceeSSaleem Abdulrasool{ 38958a0dceeSSaleem Abdulrasool return pthread_mutex_lock(__m); 39058a0dceeSSaleem Abdulrasool} 39158a0dceeSSaleem Abdulrasool 39208e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 39358a0dceeSSaleem Abdulrasool{ 39408e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 39558a0dceeSSaleem Abdulrasool} 39658a0dceeSSaleem Abdulrasool 397ebfadd82SColin Finckint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m) 39858a0dceeSSaleem Abdulrasool{ 39958a0dceeSSaleem Abdulrasool return pthread_mutex_unlock(__m); 40058a0dceeSSaleem Abdulrasool} 40158a0dceeSSaleem Abdulrasool 40258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 40358a0dceeSSaleem Abdulrasool{ 40458a0dceeSSaleem Abdulrasool return pthread_mutex_destroy(__m); 40558a0dceeSSaleem Abdulrasool} 40658a0dceeSSaleem Abdulrasool 407c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 408c7e4239fSAsiri Rathnayake{ 409c7e4239fSAsiri Rathnayake return pthread_mutex_lock(__m); 410c7e4239fSAsiri Rathnayake} 411c7e4239fSAsiri Rathnayake 41208e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 413c7e4239fSAsiri Rathnayake{ 41408e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 415c7e4239fSAsiri Rathnayake} 416c7e4239fSAsiri Rathnayake 417c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 418c7e4239fSAsiri Rathnayake{ 419c7e4239fSAsiri Rathnayake return pthread_mutex_unlock(__m); 420c7e4239fSAsiri Rathnayake} 421c7e4239fSAsiri Rathnayake 422c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 423c7e4239fSAsiri Rathnayake{ 424c7e4239fSAsiri Rathnayake return pthread_mutex_destroy(__m); 425c7e4239fSAsiri Rathnayake} 426c7e4239fSAsiri Rathnayake 427790e10f6SSaleem Abdulrasool// Condition Variable 428c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 429c7e4239fSAsiri Rathnayake{ 430c7e4239fSAsiri Rathnayake return pthread_cond_signal(__cv); 431c7e4239fSAsiri Rathnayake} 432c7e4239fSAsiri Rathnayake 433c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 434c7e4239fSAsiri Rathnayake{ 435c7e4239fSAsiri Rathnayake return pthread_cond_broadcast(__cv); 436c7e4239fSAsiri Rathnayake} 437c7e4239fSAsiri Rathnayake 438c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 439c7e4239fSAsiri Rathnayake{ 440c7e4239fSAsiri Rathnayake return pthread_cond_wait(__cv, __m); 441c7e4239fSAsiri Rathnayake} 442c7e4239fSAsiri Rathnayake 443790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 444cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts) 445c7e4239fSAsiri Rathnayake{ 446c7e4239fSAsiri Rathnayake return pthread_cond_timedwait(__cv, __m, __ts); 447c7e4239fSAsiri Rathnayake} 448c7e4239fSAsiri Rathnayake 449c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 450c7e4239fSAsiri Rathnayake{ 451c7e4239fSAsiri Rathnayake return pthread_cond_destroy(__cv); 452c7e4239fSAsiri Rathnayake} 453c7e4239fSAsiri Rathnayake 45454fa9ecdSOlivier Giroux#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES 45554fa9ecdSOlivier Giroux 45654fa9ecdSOlivier Giroux// Semaphore 45754fa9ecdSOlivier Girouxbool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init) 45854fa9ecdSOlivier Giroux{ 45954fa9ecdSOlivier Giroux return sem_init(__sem, 0, __init) == 0; 46054fa9ecdSOlivier Giroux} 46154fa9ecdSOlivier Giroux 46254fa9ecdSOlivier Girouxbool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem) 46354fa9ecdSOlivier Giroux{ 46454fa9ecdSOlivier Giroux return sem_destroy(__sem) == 0; 46554fa9ecdSOlivier Giroux} 46654fa9ecdSOlivier Giroux 46754fa9ecdSOlivier Girouxbool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem) 46854fa9ecdSOlivier Giroux{ 46954fa9ecdSOlivier Giroux return sem_post(__sem) == 0; 47054fa9ecdSOlivier Giroux} 47154fa9ecdSOlivier Giroux 47254fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem) 47354fa9ecdSOlivier Giroux{ 47454fa9ecdSOlivier Giroux return sem_wait(__sem) == 0; 47554fa9ecdSOlivier Giroux} 47654fa9ecdSOlivier Giroux 47754fa9ecdSOlivier Girouxbool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns) 47854fa9ecdSOlivier Giroux{ 47954fa9ecdSOlivier Giroux auto const __abs_time = chrono::system_clock::now().time_since_epoch() + __ns; 48054fa9ecdSOlivier Giroux __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__abs_time); 48154fa9ecdSOlivier Giroux return sem_timedwait(__sem, &__ts) == 0; 48254fa9ecdSOlivier Giroux} 48354fa9ecdSOlivier Giroux 48454fa9ecdSOlivier Giroux#endif //_LIBCPP_NO_NATIVE_SEMAPHORES 48554fa9ecdSOlivier Giroux 486205d7d3fSAsiri Rathnayake// Execute once 487205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 4884603460aSBruce Mitchener void (*init_routine)()) { 489205d7d3fSAsiri Rathnayake return pthread_once(flag, init_routine); 490205d7d3fSAsiri Rathnayake} 491205d7d3fSAsiri Rathnayake 492205d7d3fSAsiri Rathnayake// Thread id 493c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0 494c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 495c7e4239fSAsiri Rathnayake{ 496e6c89a49SZbigniew Sarbinowski return t1 == t2; 497c7e4239fSAsiri Rathnayake} 498c7e4239fSAsiri Rathnayake 499c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0 500c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 501c7e4239fSAsiri Rathnayake{ 502c7e4239fSAsiri Rathnayake return t1 < t2; 503c7e4239fSAsiri Rathnayake} 504c7e4239fSAsiri Rathnayake 505c7e4239fSAsiri Rathnayake// Thread 506af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 50748fcce1aSZbigniew Sarbinowski return __libcpp_thread_get_id(__t) == 0; 508af762e91SAsiri Rathnayake} 509af762e91SAsiri Rathnayake 510790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 511790e10f6SSaleem Abdulrasool void *__arg) 512c7e4239fSAsiri Rathnayake{ 513527a7fdfSBruce Mitchener return pthread_create(__t, nullptr, __func, __arg); 514c7e4239fSAsiri Rathnayake} 515c7e4239fSAsiri Rathnayake 516c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id() 517c7e4239fSAsiri Rathnayake{ 518e6c89a49SZbigniew Sarbinowski const __libcpp_thread_t thread = pthread_self(); 519e6c89a49SZbigniew Sarbinowski return __libcpp_thread_get_id(&thread); 520c7e4239fSAsiri Rathnayake} 521c7e4239fSAsiri Rathnayake 522c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 523c7e4239fSAsiri Rathnayake{ 524e6c89a49SZbigniew Sarbinowski#if defined(__MVS__) 525e6c89a49SZbigniew Sarbinowski return __t->__; 526e6c89a49SZbigniew Sarbinowski#else 527c7e4239fSAsiri Rathnayake return *__t; 528e6c89a49SZbigniew Sarbinowski#endif 529c7e4239fSAsiri Rathnayake} 530c7e4239fSAsiri Rathnayake 531c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t) 532c7e4239fSAsiri Rathnayake{ 533527a7fdfSBruce Mitchener return pthread_join(*__t, nullptr); 534c7e4239fSAsiri Rathnayake} 535c7e4239fSAsiri Rathnayake 536c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t) 537c7e4239fSAsiri Rathnayake{ 538c7e4239fSAsiri Rathnayake return pthread_detach(*__t); 539c7e4239fSAsiri Rathnayake} 540c7e4239fSAsiri Rathnayake 541c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield() 542c7e4239fSAsiri Rathnayake{ 543c7e4239fSAsiri Rathnayake sched_yield(); 544c7e4239fSAsiri Rathnayake} 545c7e4239fSAsiri Rathnayake 54654a987e1SAsiri Rathnayakevoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 54754a987e1SAsiri Rathnayake{ 548ab9aefeeSPetr Hosek __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); 54954a987e1SAsiri Rathnayake while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); 55054a987e1SAsiri Rathnayake} 55154a987e1SAsiri Rathnayake 552c7e4239fSAsiri Rathnayake// Thread local storage 5538c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 554c7e4239fSAsiri Rathnayake{ 555c7e4239fSAsiri Rathnayake return pthread_key_create(__key, __at_exit); 556c7e4239fSAsiri Rathnayake} 557c7e4239fSAsiri Rathnayake 5588c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key) 559c7e4239fSAsiri Rathnayake{ 560c7e4239fSAsiri Rathnayake return pthread_getspecific(__key); 561c7e4239fSAsiri Rathnayake} 562c7e4239fSAsiri Rathnayake 563205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 564c7e4239fSAsiri Rathnayake{ 565205d7d3fSAsiri Rathnayake return pthread_setspecific(__key, __p); 566c7e4239fSAsiri Rathnayake} 567c7e4239fSAsiri Rathnayake 568ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 569ab9aefeeSPetr Hosek 570ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 571ab9aefeeSPetr Hosek{ 5723481e5d7SPetr Hosek return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL; 573ab9aefeeSPetr Hosek} 574ab9aefeeSPetr Hosek 575ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 576ab9aefeeSPetr Hosek{ 577ab9aefeeSPetr Hosek return mtx_lock(__m) == thrd_success ? 0 : EINVAL; 578ab9aefeeSPetr Hosek} 579ab9aefeeSPetr Hosek 580ab9aefeeSPetr Hosekbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 581ab9aefeeSPetr Hosek{ 582ab9aefeeSPetr Hosek return mtx_trylock(__m) == thrd_success; 583ab9aefeeSPetr Hosek} 584ab9aefeeSPetr Hosek 585ebfadd82SColin Finckint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m) 586ab9aefeeSPetr Hosek{ 587ab9aefeeSPetr Hosek return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; 588ab9aefeeSPetr Hosek} 589ab9aefeeSPetr Hosek 590ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 591ab9aefeeSPetr Hosek{ 592ab9aefeeSPetr Hosek mtx_destroy(__m); 593ab9aefeeSPetr Hosek return 0; 594ab9aefeeSPetr Hosek} 595ab9aefeeSPetr Hosek 596ab9aefeeSPetr Hosekint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 597ab9aefeeSPetr Hosek{ 598ab9aefeeSPetr Hosek return mtx_lock(__m) == thrd_success ? 0 : EINVAL; 599ab9aefeeSPetr Hosek} 600ab9aefeeSPetr Hosek 601ab9aefeeSPetr Hosekbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 602ab9aefeeSPetr Hosek{ 603ab9aefeeSPetr Hosek return mtx_trylock(__m) == thrd_success; 604ab9aefeeSPetr Hosek} 605ab9aefeeSPetr Hosek 606ab9aefeeSPetr Hosekint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 607ab9aefeeSPetr Hosek{ 608ab9aefeeSPetr Hosek return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; 609ab9aefeeSPetr Hosek} 610ab9aefeeSPetr Hosek 611ab9aefeeSPetr Hosekint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 612ab9aefeeSPetr Hosek{ 613ab9aefeeSPetr Hosek mtx_destroy(__m); 614ab9aefeeSPetr Hosek return 0; 615ab9aefeeSPetr Hosek} 616ab9aefeeSPetr Hosek 617ab9aefeeSPetr Hosek// Condition Variable 618ab9aefeeSPetr Hosekint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 619ab9aefeeSPetr Hosek{ 620ab9aefeeSPetr Hosek return cnd_signal(__cv) == thrd_success ? 0 : EINVAL; 621ab9aefeeSPetr Hosek} 622ab9aefeeSPetr Hosek 623ab9aefeeSPetr Hosekint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 624ab9aefeeSPetr Hosek{ 625ab9aefeeSPetr Hosek return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL; 626ab9aefeeSPetr Hosek} 627ab9aefeeSPetr Hosek 628ab9aefeeSPetr Hosekint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 629ab9aefeeSPetr Hosek{ 630ab9aefeeSPetr Hosek return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL; 631ab9aefeeSPetr Hosek} 632ab9aefeeSPetr Hosek 633ab9aefeeSPetr Hosekint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 634ab9aefeeSPetr Hosek timespec *__ts) 635ab9aefeeSPetr Hosek{ 636ab9aefeeSPetr Hosek int __ec = cnd_timedwait(__cv, __m, __ts); 637ab9aefeeSPetr Hosek return __ec == thrd_timedout ? ETIMEDOUT : __ec; 638ab9aefeeSPetr Hosek} 639ab9aefeeSPetr Hosek 640ab9aefeeSPetr Hosekint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 641ab9aefeeSPetr Hosek{ 642ab9aefeeSPetr Hosek cnd_destroy(__cv); 643ab9aefeeSPetr Hosek return 0; 644ab9aefeeSPetr Hosek} 645ab9aefeeSPetr Hosek 646ab9aefeeSPetr Hosek// Execute once 647ab9aefeeSPetr Hosekint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 648ab9aefeeSPetr Hosek void (*init_routine)(void)) { 649ab9aefeeSPetr Hosek ::call_once(flag, init_routine); 650ab9aefeeSPetr Hosek return 0; 651ab9aefeeSPetr Hosek} 652ab9aefeeSPetr Hosek 653ab9aefeeSPetr Hosek// Thread id 654ab9aefeeSPetr Hosek// Returns non-zero if the thread ids are equal, otherwise 0 655ab9aefeeSPetr Hosekbool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 656ab9aefeeSPetr Hosek{ 657ab9aefeeSPetr Hosek return thrd_equal(t1, t2) != 0; 658ab9aefeeSPetr Hosek} 659ab9aefeeSPetr Hosek 660ab9aefeeSPetr Hosek// Returns non-zero if t1 < t2, otherwise 0 661ab9aefeeSPetr Hosekbool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 662ab9aefeeSPetr Hosek{ 663ab9aefeeSPetr Hosek return t1 < t2; 664ab9aefeeSPetr Hosek} 665ab9aefeeSPetr Hosek 666ab9aefeeSPetr Hosek// Thread 667ab9aefeeSPetr Hosekbool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 668e6c89a49SZbigniew Sarbinowski return __libcpp_thread_get_id(__t) == 0; 669ab9aefeeSPetr Hosek} 670ab9aefeeSPetr Hosek 671ab9aefeeSPetr Hosekint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 672ab9aefeeSPetr Hosek void *__arg) 673ab9aefeeSPetr Hosek{ 674ab9aefeeSPetr Hosek int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg); 675ab9aefeeSPetr Hosek return __ec == thrd_nomem ? ENOMEM : __ec; 676ab9aefeeSPetr Hosek} 677ab9aefeeSPetr Hosek 678ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_current_id() 679ab9aefeeSPetr Hosek{ 680ab9aefeeSPetr Hosek return thrd_current(); 681ab9aefeeSPetr Hosek} 682ab9aefeeSPetr Hosek 683ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 684ab9aefeeSPetr Hosek{ 685ab9aefeeSPetr Hosek return *__t; 686ab9aefeeSPetr Hosek} 687ab9aefeeSPetr Hosek 688ab9aefeeSPetr Hosekint __libcpp_thread_join(__libcpp_thread_t *__t) 689ab9aefeeSPetr Hosek{ 690ab9aefeeSPetr Hosek return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL; 691ab9aefeeSPetr Hosek} 692ab9aefeeSPetr Hosek 693ab9aefeeSPetr Hosekint __libcpp_thread_detach(__libcpp_thread_t *__t) 694ab9aefeeSPetr Hosek{ 695ab9aefeeSPetr Hosek return thrd_detach(*__t) == thrd_success ? 0 : EINVAL; 696ab9aefeeSPetr Hosek} 697ab9aefeeSPetr Hosek 698ab9aefeeSPetr Hosekvoid __libcpp_thread_yield() 699ab9aefeeSPetr Hosek{ 700ab9aefeeSPetr Hosek thrd_yield(); 701ab9aefeeSPetr Hosek} 702ab9aefeeSPetr Hosek 703ab9aefeeSPetr Hosekvoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 704ab9aefeeSPetr Hosek{ 705ab9aefeeSPetr Hosek __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); 706ab9aefeeSPetr Hosek thrd_sleep(&__ts, nullptr); 707ab9aefeeSPetr Hosek} 708ab9aefeeSPetr Hosek 709ab9aefeeSPetr Hosek// Thread local storage 710ab9aefeeSPetr Hosekint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 711ab9aefeeSPetr Hosek{ 712ab9aefeeSPetr Hosek return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL; 713ab9aefeeSPetr Hosek} 714ab9aefeeSPetr Hosek 715ab9aefeeSPetr Hosekvoid *__libcpp_tls_get(__libcpp_tls_key __key) 716ab9aefeeSPetr Hosek{ 717ab9aefeeSPetr Hosek return tss_get(__key); 718ab9aefeeSPetr Hosek} 719ab9aefeeSPetr Hosek 720ab9aefeeSPetr Hosekint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 721ab9aefeeSPetr Hosek{ 722ab9aefeeSPetr Hosek return tss_set(__key, __p) == thrd_success ? 0 : EINVAL; 723ab9aefeeSPetr Hosek} 724ab9aefeeSPetr Hosek 725ab9aefeeSPetr Hosek#endif 726ab9aefeeSPetr Hosek 727e3add3e5SMartin Storsjö 72800f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL 72900f6beaeSEric Fiselier 7302b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS thread; 7312b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS __thread_id; 7322b1d4254SMarshall Clow 7332b1d4254SMarshall Clownamespace this_thread 7342b1d4254SMarshall Clow{ 7352b1d4254SMarshall Clow 7362b1d4254SMarshall Clow_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; 7372b1d4254SMarshall Clow 7382b1d4254SMarshall Clow} // this_thread 7392b1d4254SMarshall Clow 7402b1d4254SMarshall Clowtemplate<> struct hash<__thread_id>; 7412b1d4254SMarshall Clow 7422b1d4254SMarshall Clowclass _LIBCPP_TEMPLATE_VIS __thread_id 7432b1d4254SMarshall Clow{ 7442b1d4254SMarshall Clow // FIXME: pthread_t is a pointer on Darwin but a long on Linux. 7452b1d4254SMarshall Clow // NULL is the no-thread value on Darwin. Someone needs to check 7462b1d4254SMarshall Clow // on other platforms. We assume 0 works everywhere for now. 7472b1d4254SMarshall Clow __libcpp_thread_id __id_; 7482b1d4254SMarshall Clow 7492b1d4254SMarshall Clowpublic: 7502b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7512b1d4254SMarshall Clow __thread_id() _NOEXCEPT : __id_(0) {} 7522b1d4254SMarshall Clow 7532b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7542b1d4254SMarshall Clow bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT 7552e80d01fSMarshall Clow { // don't pass id==0 to underlying routines 7562e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ == 0; 7572e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 7582e80d01fSMarshall Clow return __libcpp_thread_id_equal(__x.__id_, __y.__id_); 7592e80d01fSMarshall Clow } 7602b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7612b1d4254SMarshall Clow bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT 7622b1d4254SMarshall Clow {return !(__x == __y);} 7632b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7642b1d4254SMarshall Clow bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT 7652e80d01fSMarshall Clow { // id==0 is always less than any other thread_id 7662e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ != 0; 7672e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 7682e80d01fSMarshall Clow return __libcpp_thread_id_less(__x.__id_, __y.__id_); 7692e80d01fSMarshall Clow } 7702b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7712b1d4254SMarshall Clow bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT 7722b1d4254SMarshall Clow {return !(__y < __x);} 7732b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7742b1d4254SMarshall Clow bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT 7752b1d4254SMarshall Clow {return __y < __x ;} 7762b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 7772b1d4254SMarshall Clow bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT 7782b1d4254SMarshall Clow {return !(__x < __y);} 7792b1d4254SMarshall Clow 7802b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7812e80d01fSMarshall Clow void __reset() { __id_ = 0; } 7822b1d4254SMarshall Clow 7832b1d4254SMarshall Clow template<class _CharT, class _Traits> 7842b1d4254SMarshall Clow friend 7852b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7862b1d4254SMarshall Clow basic_ostream<_CharT, _Traits>& 7872b1d4254SMarshall Clow operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); 7882b1d4254SMarshall Clow 7892b1d4254SMarshall Clowprivate: 7902b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 7912b1d4254SMarshall Clow __thread_id(__libcpp_thread_id __id) : __id_(__id) {} 7922b1d4254SMarshall Clow 7932b1d4254SMarshall Clow friend __thread_id this_thread::get_id() _NOEXCEPT; 7942b1d4254SMarshall Clow friend class _LIBCPP_TYPE_VIS thread; 7952b1d4254SMarshall Clow friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; 7962b1d4254SMarshall Clow}; 7972b1d4254SMarshall Clow 7982b1d4254SMarshall Clownamespace this_thread 7992b1d4254SMarshall Clow{ 8002b1d4254SMarshall Clow 8012b1d4254SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY 8022b1d4254SMarshall Clow__thread_id 8032b1d4254SMarshall Clowget_id() _NOEXCEPT 8042b1d4254SMarshall Clow{ 8052b1d4254SMarshall Clow return __libcpp_thread_get_current_id(); 8062b1d4254SMarshall Clow} 8072b1d4254SMarshall Clow 8082b1d4254SMarshall Clow} // this_thread 8092b1d4254SMarshall Clow 810696630eaSMarshall Clow#endif // !_LIBCPP_HAS_NO_THREADS 811696630eaSMarshall Clow 812c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD 813c7e4239fSAsiri Rathnayake 814a016efb1SEric Fiselier_LIBCPP_POP_MACROS 815a016efb1SEric Fiselier 816c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT 817