1c7e4239fSAsiri Rathnayake// -*- C++ -*- 2c7e4239fSAsiri Rathnayake//===----------------------------------------------------------------------===// 3c7e4239fSAsiri Rathnayake// 457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7c7e4239fSAsiri Rathnayake// 8c7e4239fSAsiri Rathnayake//===----------------------------------------------------------------------===// 9c7e4239fSAsiri Rathnayake 10c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_THREADING_SUPPORT 11c7e4239fSAsiri Rathnayake#define _LIBCPP_THREADING_SUPPORT 12c7e4239fSAsiri Rathnayake 13c7e4239fSAsiri Rathnayake#include <__config> 1454a987e1SAsiri Rathnayake#include <chrono> 152b1d4254SMarshall Clow#include <iosfwd> 1654a987e1SAsiri Rathnayake#include <errno.h> 17c7e4239fSAsiri Rathnayake 18c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER 19c7e4239fSAsiri Rathnayake#pragma GCC system_header 20c7e4239fSAsiri Rathnayake#endif 21c7e4239fSAsiri Rathnayake 2200f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 233cf2f7bcSAsiri Rathnayake# include <__external_threading> 2400f6beaeSEric Fiselier#elif !defined(_LIBCPP_HAS_NO_THREADS) 25790e10f6SSaleem Abdulrasool 2600f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 27c7e4239fSAsiri Rathnayake# include <pthread.h> 28c7e4239fSAsiri Rathnayake# include <sched.h> 29*ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 30*ab9aefeeSPetr Hosek# include <threads.h> 31790e10f6SSaleem Abdulrasool#endif 32c7e4239fSAsiri Rathnayake 332a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 342a129dc3SPeter Collingbourne defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \ 352a129dc3SPeter Collingbourne defined(_LIBCPP_HAS_THREAD_API_WIN32) 362a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS 372a129dc3SPeter Collingbourne#else 382a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY 392a129dc3SPeter Collingbourne#endif 402a129dc3SPeter Collingbourne 4183dca5c3SDimitry Andric#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis) 4283dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) 4383dca5c3SDimitry Andric#else 4483dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 4583dca5c3SDimitry Andric#endif 4683dca5c3SDimitry Andric 47696630eaSMarshall Clowtypedef ::timespec __libcpp_timespec_t; 48696630eaSMarshall Clow#endif // !defined(_LIBCPP_HAS_NO_THREADS) 49696630eaSMarshall Clow 50696630eaSMarshall Clow_LIBCPP_PUSH_MACROS 51696630eaSMarshall Clow#include <__undef_macros> 52696630eaSMarshall Clow 53c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD 54c7e4239fSAsiri Rathnayake 55696630eaSMarshall Clow#if !defined(_LIBCPP_HAS_NO_THREADS) 56696630eaSMarshall Clow 572a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 58c7e4239fSAsiri Rathnayake// Mutex 59c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t; 608c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 61c7e4239fSAsiri Rathnayake 6258a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t; 6358a0dceeSSaleem Abdulrasool 64790e10f6SSaleem Abdulrasool// Condition Variable 65790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t; 66790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER 67790e10f6SSaleem Abdulrasool 68205d7d3fSAsiri Rathnayake// Execute once 69205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag; 70205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT 71205d7d3fSAsiri Rathnayake 72205d7d3fSAsiri Rathnayake// Thread id 73790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_id; 74790e10f6SSaleem Abdulrasool 75790e10f6SSaleem Abdulrasool// Thread 76af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 77af762e91SAsiri Rathnayake 78790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t; 79790e10f6SSaleem Abdulrasool 80cac6d217SFangrui Song// Thread Local Storage 81790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key; 826d7d0becSSaleem Abdulrasool 836d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC 84*ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 85*ab9aefeeSPetr Hosek// Mutex 86*ab9aefeeSPetr Hosektypedef mtx_t __libcpp_mutex_t; 87*ab9aefeeSPetr Hosek// mtx_t is a struct so using {} for initialization is valid. 88*ab9aefeeSPetr Hosek#define _LIBCPP_MUTEX_INITIALIZER {} 89*ab9aefeeSPetr Hosek 90*ab9aefeeSPetr Hosektypedef mtx_t __libcpp_recursive_mutex_t; 91*ab9aefeeSPetr Hosek 92*ab9aefeeSPetr Hosek// Condition Variable 93*ab9aefeeSPetr Hosektypedef cnd_t __libcpp_condvar_t; 94*ab9aefeeSPetr Hosek// cnd_t is a struct so using {} for initialization is valid. 95*ab9aefeeSPetr Hosek#define _LIBCPP_CONDVAR_INITIALIZER {} 96*ab9aefeeSPetr Hosek 97*ab9aefeeSPetr Hosek// Execute once 98*ab9aefeeSPetr Hosektypedef once_flag __libcpp_exec_once_flag; 99*ab9aefeeSPetr Hosek#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT 100*ab9aefeeSPetr Hosek 101*ab9aefeeSPetr Hosek// Thread id 102*ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_id; 103*ab9aefeeSPetr Hosek 104*ab9aefeeSPetr Hosek// Thread 105*ab9aefeeSPetr Hosek#define _LIBCPP_NULL_THREAD 0U 106*ab9aefeeSPetr Hosek 107*ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_t; 108*ab9aefeeSPetr Hosek 109*ab9aefeeSPetr Hosek// Thread Local Storage 110*ab9aefeeSPetr Hosektypedef tss_t __libcpp_tls_key; 111*ab9aefeeSPetr Hosek 112*ab9aefeeSPetr Hosek#define _LIBCPP_TLS_DESTRUCTOR_CC 113e2b200b7SDavid Spickett#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 114ac15ae6dSPeter Collingbourne// Mutex 115ac15ae6dSPeter Collingbournetypedef void* __libcpp_mutex_t; 116ac15ae6dSPeter Collingbourne#define _LIBCPP_MUTEX_INITIALIZER 0 117ac15ae6dSPeter Collingbourne 118ac15ae6dSPeter Collingbourne#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) 119ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[6]; 120ac15ae6dSPeter Collingbourne#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__) 121ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[5]; 122ac15ae6dSPeter Collingbourne#else 123ac15ae6dSPeter Collingbourne# error Unsupported architecture 124ac15ae6dSPeter Collingbourne#endif 1256d7d0becSSaleem Abdulrasool 1266d7d0becSSaleem Abdulrasool// Condition Variable 127ac15ae6dSPeter Collingbournetypedef void* __libcpp_condvar_t; 128ac15ae6dSPeter Collingbourne#define _LIBCPP_CONDVAR_INITIALIZER 0 1296d7d0becSSaleem Abdulrasool 1306d7d0becSSaleem Abdulrasool// Execute Once 131ac15ae6dSPeter Collingbournetypedef void* __libcpp_exec_once_flag; 132ac15ae6dSPeter Collingbourne#define _LIBCPP_EXEC_ONCE_INITIALIZER 0 1336d7d0becSSaleem Abdulrasool 1346d7d0becSSaleem Abdulrasool// Thread ID 135ac15ae6dSPeter Collingbournetypedef long __libcpp_thread_id; 1366d7d0becSSaleem Abdulrasool 1376d7d0becSSaleem Abdulrasool// Thread 138af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 139af762e91SAsiri Rathnayake 140ac15ae6dSPeter Collingbournetypedef void* __libcpp_thread_t; 1416d7d0becSSaleem Abdulrasool 1426d7d0becSSaleem Abdulrasool// Thread Local Storage 143ac15ae6dSPeter Collingbournetypedef long __libcpp_tls_key; 1446d7d0becSSaleem Abdulrasool 145ac15ae6dSPeter Collingbourne#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall 146e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 147790e10f6SSaleem Abdulrasool 148e2b200b7SDavid Spickett#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 149790e10f6SSaleem Abdulrasool// Mutex 1508c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 15158a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); 15258a0dceeSSaleem Abdulrasool 15383dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 15458a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m); 15558a0dceeSSaleem Abdulrasool 15683dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 15708e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m); 15858a0dceeSSaleem Abdulrasool 15983dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 16058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m); 16158a0dceeSSaleem Abdulrasool 16258a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY 16358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m); 164790e10f6SSaleem Abdulrasool 16583dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1668c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m); 167790e10f6SSaleem Abdulrasool 16883dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 16908e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m); 170790e10f6SSaleem Abdulrasool 17183dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1728c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m); 173790e10f6SSaleem Abdulrasool 1748c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1758c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m); 1768c2bf45dSAsiri Rathnayake 1778c2bf45dSAsiri Rathnayake// Condition variable 1788c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1798c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv); 180790e10f6SSaleem Abdulrasool 1818c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1828c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv); 183790e10f6SSaleem Abdulrasool 18483dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1858c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m); 186790e10f6SSaleem Abdulrasool 18783dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 188790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 189cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts); 190790e10f6SSaleem Abdulrasool 1918c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1928c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); 1938c2bf45dSAsiri Rathnayake 194205d7d3fSAsiri Rathnayake// Execute once 195205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 196205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 1974603460aSBruce Mitchener void (*init_routine)()); 198205d7d3fSAsiri Rathnayake 199205d7d3fSAsiri Rathnayake// Thread id 2008c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2018c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); 202790e10f6SSaleem Abdulrasool 2038c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2048c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); 2058c2bf45dSAsiri Rathnayake 2068c2bf45dSAsiri Rathnayake// Thread 2078c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 208af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t); 209af762e91SAsiri Rathnayake 210af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 211790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 212790e10f6SSaleem Abdulrasool void *__arg); 213790e10f6SSaleem Abdulrasool 2148c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2158c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id(); 216790e10f6SSaleem Abdulrasool 2178c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2188c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); 219790e10f6SSaleem Abdulrasool 2208c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2218c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t); 222790e10f6SSaleem Abdulrasool 2238c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2248c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t); 225790e10f6SSaleem Abdulrasool 2268c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2278c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield(); 2288c2bf45dSAsiri Rathnayake 22954a987e1SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2309e8a082dSJoerg Sonnenbergervoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns); 23154a987e1SAsiri Rathnayake 2328c2bf45dSAsiri Rathnayake// Thread local storage 2338c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2346d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key, 2356d7d0becSSaleem Abdulrasool void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)); 236790e10f6SSaleem Abdulrasool 2378c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2388c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key); 239790e10f6SSaleem Abdulrasool 2408c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 241205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p); 2428c2bf45dSAsiri Rathnayake 243e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 244e2b200b7SDavid Spickett 245ac15ae6dSPeter Collingbourne#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 246*ab9aefeeSPetr Hosek defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) 247*ab9aefeeSPetr Hosek 248*ab9aefeeSPetr Hoseknamespace __thread_detail { 249*ab9aefeeSPetr Hosek 250*ab9aefeeSPetr Hosekinline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) 251*ab9aefeeSPetr Hosek{ 252*ab9aefeeSPetr Hosek using namespace chrono; 253*ab9aefeeSPetr Hosek seconds __s = duration_cast<seconds>(__ns); 254*ab9aefeeSPetr Hosek __libcpp_timespec_t __ts; 255*ab9aefeeSPetr Hosek typedef decltype(__ts.tv_sec) __ts_sec; 256*ab9aefeeSPetr Hosek const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); 257*ab9aefeeSPetr Hosek 258*ab9aefeeSPetr Hosek if (__s.count() < __ts_sec_max) 259*ab9aefeeSPetr Hosek { 260*ab9aefeeSPetr Hosek __ts.tv_sec = static_cast<__ts_sec>(__s.count()); 261*ab9aefeeSPetr Hosek __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); 262*ab9aefeeSPetr Hosek } 263*ab9aefeeSPetr Hosek else 264*ab9aefeeSPetr Hosek { 265*ab9aefeeSPetr Hosek __ts.tv_sec = __ts_sec_max; 266*ab9aefeeSPetr Hosek __ts.tv_nsec = 999999999; // (10^9 - 1) 267*ab9aefeeSPetr Hosek } 268*ab9aefeeSPetr Hosek 269*ab9aefeeSPetr Hosek return __ts; 270*ab9aefeeSPetr Hosek} 271*ab9aefeeSPetr Hosek 272*ab9aefeeSPetr Hosek} 273*ab9aefeeSPetr Hosek 274*ab9aefeeSPetr Hosek#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 2758c2bf45dSAsiri Rathnayake 27658a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 277c7e4239fSAsiri Rathnayake{ 278c7e4239fSAsiri Rathnayake pthread_mutexattr_t attr; 279c7e4239fSAsiri Rathnayake int __ec = pthread_mutexattr_init(&attr); 280c7e4239fSAsiri Rathnayake if (__ec) 281790e10f6SSaleem Abdulrasool return __ec; 282790e10f6SSaleem Abdulrasool __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 283790e10f6SSaleem Abdulrasool if (__ec) { 284c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 285c7e4239fSAsiri Rathnayake return __ec; 286c7e4239fSAsiri Rathnayake } 287c7e4239fSAsiri Rathnayake __ec = pthread_mutex_init(__m, &attr); 288790e10f6SSaleem Abdulrasool if (__ec) { 289c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 290c7e4239fSAsiri Rathnayake return __ec; 291c7e4239fSAsiri Rathnayake } 292c7e4239fSAsiri Rathnayake __ec = pthread_mutexattr_destroy(&attr); 293790e10f6SSaleem Abdulrasool if (__ec) { 294c7e4239fSAsiri Rathnayake pthread_mutex_destroy(__m); 295c7e4239fSAsiri Rathnayake return __ec; 296c7e4239fSAsiri Rathnayake } 297c7e4239fSAsiri Rathnayake return 0; 298c7e4239fSAsiri Rathnayake} 299c7e4239fSAsiri Rathnayake 30058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 30158a0dceeSSaleem Abdulrasool{ 30258a0dceeSSaleem Abdulrasool return pthread_mutex_lock(__m); 30358a0dceeSSaleem Abdulrasool} 30458a0dceeSSaleem Abdulrasool 30508e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 30658a0dceeSSaleem Abdulrasool{ 30708e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 30858a0dceeSSaleem Abdulrasool} 30958a0dceeSSaleem Abdulrasool 31058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m) 31158a0dceeSSaleem Abdulrasool{ 31258a0dceeSSaleem Abdulrasool return pthread_mutex_unlock(__m); 31358a0dceeSSaleem Abdulrasool} 31458a0dceeSSaleem Abdulrasool 31558a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 31658a0dceeSSaleem Abdulrasool{ 31758a0dceeSSaleem Abdulrasool return pthread_mutex_destroy(__m); 31858a0dceeSSaleem Abdulrasool} 31958a0dceeSSaleem Abdulrasool 320c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 321c7e4239fSAsiri Rathnayake{ 322c7e4239fSAsiri Rathnayake return pthread_mutex_lock(__m); 323c7e4239fSAsiri Rathnayake} 324c7e4239fSAsiri Rathnayake 32508e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 326c7e4239fSAsiri Rathnayake{ 32708e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 328c7e4239fSAsiri Rathnayake} 329c7e4239fSAsiri Rathnayake 330c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 331c7e4239fSAsiri Rathnayake{ 332c7e4239fSAsiri Rathnayake return pthread_mutex_unlock(__m); 333c7e4239fSAsiri Rathnayake} 334c7e4239fSAsiri Rathnayake 335c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 336c7e4239fSAsiri Rathnayake{ 337c7e4239fSAsiri Rathnayake return pthread_mutex_destroy(__m); 338c7e4239fSAsiri Rathnayake} 339c7e4239fSAsiri Rathnayake 340790e10f6SSaleem Abdulrasool// Condition Variable 341c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 342c7e4239fSAsiri Rathnayake{ 343c7e4239fSAsiri Rathnayake return pthread_cond_signal(__cv); 344c7e4239fSAsiri Rathnayake} 345c7e4239fSAsiri Rathnayake 346c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 347c7e4239fSAsiri Rathnayake{ 348c7e4239fSAsiri Rathnayake return pthread_cond_broadcast(__cv); 349c7e4239fSAsiri Rathnayake} 350c7e4239fSAsiri Rathnayake 351c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 352c7e4239fSAsiri Rathnayake{ 353c7e4239fSAsiri Rathnayake return pthread_cond_wait(__cv, __m); 354c7e4239fSAsiri Rathnayake} 355c7e4239fSAsiri Rathnayake 356790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 357cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts) 358c7e4239fSAsiri Rathnayake{ 359c7e4239fSAsiri Rathnayake return pthread_cond_timedwait(__cv, __m, __ts); 360c7e4239fSAsiri Rathnayake} 361c7e4239fSAsiri Rathnayake 362c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 363c7e4239fSAsiri Rathnayake{ 364c7e4239fSAsiri Rathnayake return pthread_cond_destroy(__cv); 365c7e4239fSAsiri Rathnayake} 366c7e4239fSAsiri Rathnayake 367205d7d3fSAsiri Rathnayake// Execute once 368205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 3694603460aSBruce Mitchener void (*init_routine)()) { 370205d7d3fSAsiri Rathnayake return pthread_once(flag, init_routine); 371205d7d3fSAsiri Rathnayake} 372205d7d3fSAsiri Rathnayake 373205d7d3fSAsiri Rathnayake// Thread id 374c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0 375c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 376c7e4239fSAsiri Rathnayake{ 377c7e4239fSAsiri Rathnayake return pthread_equal(t1, t2) != 0; 378c7e4239fSAsiri Rathnayake} 379c7e4239fSAsiri Rathnayake 380c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0 381c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 382c7e4239fSAsiri Rathnayake{ 383c7e4239fSAsiri Rathnayake return t1 < t2; 384c7e4239fSAsiri Rathnayake} 385c7e4239fSAsiri Rathnayake 386c7e4239fSAsiri Rathnayake// Thread 387af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 388af762e91SAsiri Rathnayake return *__t == 0; 389af762e91SAsiri Rathnayake} 390af762e91SAsiri Rathnayake 391790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 392790e10f6SSaleem Abdulrasool void *__arg) 393c7e4239fSAsiri Rathnayake{ 394c7e4239fSAsiri Rathnayake return pthread_create(__t, 0, __func, __arg); 395c7e4239fSAsiri Rathnayake} 396c7e4239fSAsiri Rathnayake 397c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id() 398c7e4239fSAsiri Rathnayake{ 399c7e4239fSAsiri Rathnayake return pthread_self(); 400c7e4239fSAsiri Rathnayake} 401c7e4239fSAsiri Rathnayake 402c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 403c7e4239fSAsiri Rathnayake{ 404c7e4239fSAsiri Rathnayake return *__t; 405c7e4239fSAsiri Rathnayake} 406c7e4239fSAsiri Rathnayake 407c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t) 408c7e4239fSAsiri Rathnayake{ 409c7e4239fSAsiri Rathnayake return pthread_join(*__t, 0); 410c7e4239fSAsiri Rathnayake} 411c7e4239fSAsiri Rathnayake 412c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t) 413c7e4239fSAsiri Rathnayake{ 414c7e4239fSAsiri Rathnayake return pthread_detach(*__t); 415c7e4239fSAsiri Rathnayake} 416c7e4239fSAsiri Rathnayake 417c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield() 418c7e4239fSAsiri Rathnayake{ 419c7e4239fSAsiri Rathnayake sched_yield(); 420c7e4239fSAsiri Rathnayake} 421c7e4239fSAsiri Rathnayake 42254a987e1SAsiri Rathnayakevoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 42354a987e1SAsiri Rathnayake{ 424*ab9aefeeSPetr Hosek __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); 42554a987e1SAsiri Rathnayake while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); 42654a987e1SAsiri Rathnayake} 42754a987e1SAsiri Rathnayake 428c7e4239fSAsiri Rathnayake// Thread local storage 4298c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 430c7e4239fSAsiri Rathnayake{ 431c7e4239fSAsiri Rathnayake return pthread_key_create(__key, __at_exit); 432c7e4239fSAsiri Rathnayake} 433c7e4239fSAsiri Rathnayake 4348c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key) 435c7e4239fSAsiri Rathnayake{ 436c7e4239fSAsiri Rathnayake return pthread_getspecific(__key); 437c7e4239fSAsiri Rathnayake} 438c7e4239fSAsiri Rathnayake 439205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 440c7e4239fSAsiri Rathnayake{ 441205d7d3fSAsiri Rathnayake return pthread_setspecific(__key, __p); 442c7e4239fSAsiri Rathnayake} 443c7e4239fSAsiri Rathnayake 444*ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 445*ab9aefeeSPetr Hosek 446*ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 447*ab9aefeeSPetr Hosek{ 448*ab9aefeeSPetr Hosek return mtx_init(__m, mtx_recursive) == thrd_success ? 0 : EINVAL; 449*ab9aefeeSPetr Hosek} 450*ab9aefeeSPetr Hosek 451*ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 452*ab9aefeeSPetr Hosek{ 453*ab9aefeeSPetr Hosek return mtx_lock(__m) == thrd_success ? 0 : EINVAL; 454*ab9aefeeSPetr Hosek} 455*ab9aefeeSPetr Hosek 456*ab9aefeeSPetr Hosekbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 457*ab9aefeeSPetr Hosek{ 458*ab9aefeeSPetr Hosek return mtx_trylock(__m) == thrd_success; 459*ab9aefeeSPetr Hosek} 460*ab9aefeeSPetr Hosek 461*ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m) 462*ab9aefeeSPetr Hosek{ 463*ab9aefeeSPetr Hosek return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; 464*ab9aefeeSPetr Hosek} 465*ab9aefeeSPetr Hosek 466*ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 467*ab9aefeeSPetr Hosek{ 468*ab9aefeeSPetr Hosek mtx_destroy(__m); 469*ab9aefeeSPetr Hosek return 0; 470*ab9aefeeSPetr Hosek} 471*ab9aefeeSPetr Hosek 472*ab9aefeeSPetr Hosekint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 473*ab9aefeeSPetr Hosek{ 474*ab9aefeeSPetr Hosek return mtx_lock(__m) == thrd_success ? 0 : EINVAL; 475*ab9aefeeSPetr Hosek} 476*ab9aefeeSPetr Hosek 477*ab9aefeeSPetr Hosekbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 478*ab9aefeeSPetr Hosek{ 479*ab9aefeeSPetr Hosek return mtx_trylock(__m) == thrd_success; 480*ab9aefeeSPetr Hosek} 481*ab9aefeeSPetr Hosek 482*ab9aefeeSPetr Hosekint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 483*ab9aefeeSPetr Hosek{ 484*ab9aefeeSPetr Hosek return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; 485*ab9aefeeSPetr Hosek} 486*ab9aefeeSPetr Hosek 487*ab9aefeeSPetr Hosekint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 488*ab9aefeeSPetr Hosek{ 489*ab9aefeeSPetr Hosek mtx_destroy(__m); 490*ab9aefeeSPetr Hosek return 0; 491*ab9aefeeSPetr Hosek} 492*ab9aefeeSPetr Hosek 493*ab9aefeeSPetr Hosek// Condition Variable 494*ab9aefeeSPetr Hosekint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 495*ab9aefeeSPetr Hosek{ 496*ab9aefeeSPetr Hosek return cnd_signal(__cv) == thrd_success ? 0 : EINVAL; 497*ab9aefeeSPetr Hosek} 498*ab9aefeeSPetr Hosek 499*ab9aefeeSPetr Hosekint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 500*ab9aefeeSPetr Hosek{ 501*ab9aefeeSPetr Hosek return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL; 502*ab9aefeeSPetr Hosek} 503*ab9aefeeSPetr Hosek 504*ab9aefeeSPetr Hosekint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 505*ab9aefeeSPetr Hosek{ 506*ab9aefeeSPetr Hosek return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL; 507*ab9aefeeSPetr Hosek} 508*ab9aefeeSPetr Hosek 509*ab9aefeeSPetr Hosekint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 510*ab9aefeeSPetr Hosek timespec *__ts) 511*ab9aefeeSPetr Hosek{ 512*ab9aefeeSPetr Hosek int __ec = cnd_timedwait(__cv, __m, __ts); 513*ab9aefeeSPetr Hosek return __ec == thrd_timedout ? ETIMEDOUT : __ec; 514*ab9aefeeSPetr Hosek} 515*ab9aefeeSPetr Hosek 516*ab9aefeeSPetr Hosekint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 517*ab9aefeeSPetr Hosek{ 518*ab9aefeeSPetr Hosek cnd_destroy(__cv); 519*ab9aefeeSPetr Hosek return 0; 520*ab9aefeeSPetr Hosek} 521*ab9aefeeSPetr Hosek 522*ab9aefeeSPetr Hosek// Execute once 523*ab9aefeeSPetr Hosekint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 524*ab9aefeeSPetr Hosek void (*init_routine)(void)) { 525*ab9aefeeSPetr Hosek ::call_once(flag, init_routine); 526*ab9aefeeSPetr Hosek return 0; 527*ab9aefeeSPetr Hosek} 528*ab9aefeeSPetr Hosek 529*ab9aefeeSPetr Hosek// Thread id 530*ab9aefeeSPetr Hosek// Returns non-zero if the thread ids are equal, otherwise 0 531*ab9aefeeSPetr Hosekbool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 532*ab9aefeeSPetr Hosek{ 533*ab9aefeeSPetr Hosek return thrd_equal(t1, t2) != 0; 534*ab9aefeeSPetr Hosek} 535*ab9aefeeSPetr Hosek 536*ab9aefeeSPetr Hosek// Returns non-zero if t1 < t2, otherwise 0 537*ab9aefeeSPetr Hosekbool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 538*ab9aefeeSPetr Hosek{ 539*ab9aefeeSPetr Hosek return t1 < t2; 540*ab9aefeeSPetr Hosek} 541*ab9aefeeSPetr Hosek 542*ab9aefeeSPetr Hosek// Thread 543*ab9aefeeSPetr Hosekbool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 544*ab9aefeeSPetr Hosek return *__t == 0; 545*ab9aefeeSPetr Hosek} 546*ab9aefeeSPetr Hosek 547*ab9aefeeSPetr Hosekint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 548*ab9aefeeSPetr Hosek void *__arg) 549*ab9aefeeSPetr Hosek{ 550*ab9aefeeSPetr Hosek int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg); 551*ab9aefeeSPetr Hosek return __ec == thrd_nomem ? ENOMEM : __ec; 552*ab9aefeeSPetr Hosek} 553*ab9aefeeSPetr Hosek 554*ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_current_id() 555*ab9aefeeSPetr Hosek{ 556*ab9aefeeSPetr Hosek return thrd_current(); 557*ab9aefeeSPetr Hosek} 558*ab9aefeeSPetr Hosek 559*ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 560*ab9aefeeSPetr Hosek{ 561*ab9aefeeSPetr Hosek return *__t; 562*ab9aefeeSPetr Hosek} 563*ab9aefeeSPetr Hosek 564*ab9aefeeSPetr Hosekint __libcpp_thread_join(__libcpp_thread_t *__t) 565*ab9aefeeSPetr Hosek{ 566*ab9aefeeSPetr Hosek return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL; 567*ab9aefeeSPetr Hosek} 568*ab9aefeeSPetr Hosek 569*ab9aefeeSPetr Hosekint __libcpp_thread_detach(__libcpp_thread_t *__t) 570*ab9aefeeSPetr Hosek{ 571*ab9aefeeSPetr Hosek return thrd_detach(*__t) == thrd_success ? 0 : EINVAL; 572*ab9aefeeSPetr Hosek} 573*ab9aefeeSPetr Hosek 574*ab9aefeeSPetr Hosekvoid __libcpp_thread_yield() 575*ab9aefeeSPetr Hosek{ 576*ab9aefeeSPetr Hosek thrd_yield(); 577*ab9aefeeSPetr Hosek} 578*ab9aefeeSPetr Hosek 579*ab9aefeeSPetr Hosekvoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 580*ab9aefeeSPetr Hosek{ 581*ab9aefeeSPetr Hosek __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); 582*ab9aefeeSPetr Hosek thrd_sleep(&__ts, nullptr); 583*ab9aefeeSPetr Hosek} 584*ab9aefeeSPetr Hosek 585*ab9aefeeSPetr Hosek// Thread local storage 586*ab9aefeeSPetr Hosekint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 587*ab9aefeeSPetr Hosek{ 588*ab9aefeeSPetr Hosek return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL; 589*ab9aefeeSPetr Hosek} 590*ab9aefeeSPetr Hosek 591*ab9aefeeSPetr Hosekvoid *__libcpp_tls_get(__libcpp_tls_key __key) 592*ab9aefeeSPetr Hosek{ 593*ab9aefeeSPetr Hosek return tss_get(__key); 594*ab9aefeeSPetr Hosek} 595*ab9aefeeSPetr Hosek 596*ab9aefeeSPetr Hosekint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 597*ab9aefeeSPetr Hosek{ 598*ab9aefeeSPetr Hosek return tss_set(__key, __p) == thrd_success ? 0 : EINVAL; 599*ab9aefeeSPetr Hosek} 600*ab9aefeeSPetr Hosek 601*ab9aefeeSPetr Hosek#endif 602*ab9aefeeSPetr Hosek 60300f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL 60400f6beaeSEric Fiselier 6052b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS thread; 6062b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS __thread_id; 6072b1d4254SMarshall Clow 6082b1d4254SMarshall Clownamespace this_thread 6092b1d4254SMarshall Clow{ 6102b1d4254SMarshall Clow 6112b1d4254SMarshall Clow_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; 6122b1d4254SMarshall Clow 6132b1d4254SMarshall Clow} // this_thread 6142b1d4254SMarshall Clow 6152b1d4254SMarshall Clowtemplate<> struct hash<__thread_id>; 6162b1d4254SMarshall Clow 6172b1d4254SMarshall Clowclass _LIBCPP_TEMPLATE_VIS __thread_id 6182b1d4254SMarshall Clow{ 6192b1d4254SMarshall Clow // FIXME: pthread_t is a pointer on Darwin but a long on Linux. 6202b1d4254SMarshall Clow // NULL is the no-thread value on Darwin. Someone needs to check 6212b1d4254SMarshall Clow // on other platforms. We assume 0 works everywhere for now. 6222b1d4254SMarshall Clow __libcpp_thread_id __id_; 6232b1d4254SMarshall Clow 6242b1d4254SMarshall Clowpublic: 6252b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 6262b1d4254SMarshall Clow __thread_id() _NOEXCEPT : __id_(0) {} 6272b1d4254SMarshall Clow 6282b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6292b1d4254SMarshall Clow bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT 6302e80d01fSMarshall Clow { // don't pass id==0 to underlying routines 6312e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ == 0; 6322e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 6332e80d01fSMarshall Clow return __libcpp_thread_id_equal(__x.__id_, __y.__id_); 6342e80d01fSMarshall Clow } 6352b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6362b1d4254SMarshall Clow bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT 6372b1d4254SMarshall Clow {return !(__x == __y);} 6382b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6392b1d4254SMarshall Clow bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT 6402e80d01fSMarshall Clow { // id==0 is always less than any other thread_id 6412e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ != 0; 6422e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 6432e80d01fSMarshall Clow return __libcpp_thread_id_less(__x.__id_, __y.__id_); 6442e80d01fSMarshall Clow } 6452b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6462b1d4254SMarshall Clow bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT 6472b1d4254SMarshall Clow {return !(__y < __x);} 6482b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6492b1d4254SMarshall Clow bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT 6502b1d4254SMarshall Clow {return __y < __x ;} 6512b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6522b1d4254SMarshall Clow bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT 6532b1d4254SMarshall Clow {return !(__x < __y);} 6542b1d4254SMarshall Clow 6552b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 6562e80d01fSMarshall Clow void __reset() { __id_ = 0; } 6572b1d4254SMarshall Clow 6582b1d4254SMarshall Clow template<class _CharT, class _Traits> 6592b1d4254SMarshall Clow friend 6602b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 6612b1d4254SMarshall Clow basic_ostream<_CharT, _Traits>& 6622b1d4254SMarshall Clow operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); 6632b1d4254SMarshall Clow 6642b1d4254SMarshall Clowprivate: 6652b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 6662b1d4254SMarshall Clow __thread_id(__libcpp_thread_id __id) : __id_(__id) {} 6672b1d4254SMarshall Clow 6682b1d4254SMarshall Clow friend __thread_id this_thread::get_id() _NOEXCEPT; 6692b1d4254SMarshall Clow friend class _LIBCPP_TYPE_VIS thread; 6702b1d4254SMarshall Clow friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; 6712b1d4254SMarshall Clow}; 6722b1d4254SMarshall Clow 6732b1d4254SMarshall Clownamespace this_thread 6742b1d4254SMarshall Clow{ 6752b1d4254SMarshall Clow 6762b1d4254SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY 6772b1d4254SMarshall Clow__thread_id 6782b1d4254SMarshall Clowget_id() _NOEXCEPT 6792b1d4254SMarshall Clow{ 6802b1d4254SMarshall Clow return __libcpp_thread_get_current_id(); 6812b1d4254SMarshall Clow} 6822b1d4254SMarshall Clow 6832b1d4254SMarshall Clow} // this_thread 6842b1d4254SMarshall Clow 685696630eaSMarshall Clow#endif // !_LIBCPP_HAS_NO_THREADS 686696630eaSMarshall Clow 687c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD 688c7e4239fSAsiri Rathnayake 689a016efb1SEric Fiselier_LIBCPP_POP_MACROS 690a016efb1SEric Fiselier 691c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT 692