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> 14bfbd73f8SArthur O'Dwyer#include <__config> 1592832e48SLouis Dionne#include <__thread/poll_with_backoff.h> 1654a987e1SAsiri Rathnayake#include <chrono> 1754a987e1SAsiri Rathnayake#include <errno.h> 18bfbd73f8SArthur O'Dwyer#include <iosfwd> 191773eec6SMartin Storsjö#include <limits> 20c7e4239fSAsiri Rathnayake 216a8099e0SZbigniew Sarbinowski#ifdef __MVS__ 22b5175681SLouis Dionne# include <__support/ibm/nanosleep.h> 236a8099e0SZbigniew Sarbinowski#endif 246a8099e0SZbigniew Sarbinowski 25c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER 26c7e4239fSAsiri Rathnayake#pragma GCC system_header 27c7e4239fSAsiri Rathnayake#endif 28c7e4239fSAsiri Rathnayake 2900f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 303cf2f7bcSAsiri Rathnayake# include <__external_threading> 3100f6beaeSEric Fiselier#elif !defined(_LIBCPP_HAS_NO_THREADS) 32790e10f6SSaleem Abdulrasool 33db757ba7SLouis Dionne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 34db757ba7SLouis Dionne# include <pthread.h> 35db757ba7SLouis Dionne# include <sched.h> 36ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 37ab9aefeeSPetr Hosek# include <threads.h> 38790e10f6SSaleem Abdulrasool#endif 39c7e4239fSAsiri Rathnayake 402a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 412a129dc3SPeter Collingbourne defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \ 422a129dc3SPeter Collingbourne defined(_LIBCPP_HAS_THREAD_API_WIN32) 432a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS 442a129dc3SPeter Collingbourne#else 452a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY 462a129dc3SPeter Collingbourne#endif 472a129dc3SPeter Collingbourne 4883dca5c3SDimitry Andric#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis) 4983dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) 5083dca5c3SDimitry Andric#else 5183dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 5283dca5c3SDimitry Andric#endif 5383dca5c3SDimitry Andric 54696630eaSMarshall Clowtypedef ::timespec __libcpp_timespec_t; 55696630eaSMarshall Clow#endif // !defined(_LIBCPP_HAS_NO_THREADS) 56696630eaSMarshall Clow 57696630eaSMarshall Clow_LIBCPP_PUSH_MACROS 58696630eaSMarshall Clow#include <__undef_macros> 59696630eaSMarshall Clow 60c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD 61c7e4239fSAsiri Rathnayake 62696630eaSMarshall Clow#if !defined(_LIBCPP_HAS_NO_THREADS) 63696630eaSMarshall Clow 642a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 65c7e4239fSAsiri Rathnayake// Mutex 66c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t; 678c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 68c7e4239fSAsiri Rathnayake 6958a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t; 7058a0dceeSSaleem Abdulrasool 71790e10f6SSaleem Abdulrasool// Condition Variable 72790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t; 73790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER 74790e10f6SSaleem Abdulrasool 75205d7d3fSAsiri Rathnayake// Execute once 76205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag; 77205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT 78205d7d3fSAsiri Rathnayake 79205d7d3fSAsiri Rathnayake// Thread id 80e6c89a49SZbigniew Sarbinowski#if defined(__MVS__) 81e6c89a49SZbigniew Sarbinowski typedef unsigned long long __libcpp_thread_id; 82e6c89a49SZbigniew Sarbinowski#else 83790e10f6SSaleem Abdulrasool typedef pthread_t __libcpp_thread_id; 84e6c89a49SZbigniew Sarbinowski#endif 85790e10f6SSaleem Abdulrasool 86790e10f6SSaleem Abdulrasool// Thread 87e6c89a49SZbigniew Sarbinowski#define _LIBCPP_NULL_THREAD ((__libcpp_thread_t())) 88790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t; 89790e10f6SSaleem Abdulrasool 90cac6d217SFangrui Song// Thread Local Storage 91790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key; 926d7d0becSSaleem Abdulrasool 936d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC 94ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 95ab9aefeeSPetr Hosek// Mutex 96ab9aefeeSPetr Hosektypedef mtx_t __libcpp_mutex_t; 97ab9aefeeSPetr Hosek// mtx_t is a struct so using {} for initialization is valid. 98ab9aefeeSPetr Hosek#define _LIBCPP_MUTEX_INITIALIZER {} 99ab9aefeeSPetr Hosek 100ab9aefeeSPetr Hosektypedef mtx_t __libcpp_recursive_mutex_t; 101ab9aefeeSPetr Hosek 102ab9aefeeSPetr Hosek// Condition Variable 103ab9aefeeSPetr Hosektypedef cnd_t __libcpp_condvar_t; 104ab9aefeeSPetr Hosek// cnd_t is a struct so using {} for initialization is valid. 105ab9aefeeSPetr Hosek#define _LIBCPP_CONDVAR_INITIALIZER {} 106ab9aefeeSPetr Hosek 107ab9aefeeSPetr Hosek// Execute once 108ab9aefeeSPetr Hosektypedef once_flag __libcpp_exec_once_flag; 109ab9aefeeSPetr Hosek#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT 110ab9aefeeSPetr Hosek 111ab9aefeeSPetr Hosek// Thread id 112ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_id; 113ab9aefeeSPetr Hosek 114ab9aefeeSPetr Hosek// Thread 115ab9aefeeSPetr Hosek#define _LIBCPP_NULL_THREAD 0U 116ab9aefeeSPetr Hosek 117ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_t; 118ab9aefeeSPetr Hosek 119ab9aefeeSPetr Hosek// Thread Local Storage 120ab9aefeeSPetr Hosektypedef tss_t __libcpp_tls_key; 121ab9aefeeSPetr Hosek 122ab9aefeeSPetr Hosek#define _LIBCPP_TLS_DESTRUCTOR_CC 123e2b200b7SDavid Spickett#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 124ac15ae6dSPeter Collingbourne// Mutex 125ac15ae6dSPeter Collingbournetypedef void* __libcpp_mutex_t; 126ac15ae6dSPeter Collingbourne#define _LIBCPP_MUTEX_INITIALIZER 0 127ac15ae6dSPeter Collingbourne 128ac15ae6dSPeter Collingbourne#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) 129ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[6]; 130ac15ae6dSPeter Collingbourne#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__) 131ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[5]; 132ac15ae6dSPeter Collingbourne#else 133ac15ae6dSPeter Collingbourne# error Unsupported architecture 134ac15ae6dSPeter Collingbourne#endif 1356d7d0becSSaleem Abdulrasool 1366d7d0becSSaleem Abdulrasool// Condition Variable 137ac15ae6dSPeter Collingbournetypedef void* __libcpp_condvar_t; 138ac15ae6dSPeter Collingbourne#define _LIBCPP_CONDVAR_INITIALIZER 0 1396d7d0becSSaleem Abdulrasool 1406d7d0becSSaleem Abdulrasool// Execute Once 141ac15ae6dSPeter Collingbournetypedef void* __libcpp_exec_once_flag; 142ac15ae6dSPeter Collingbourne#define _LIBCPP_EXEC_ONCE_INITIALIZER 0 1436d7d0becSSaleem Abdulrasool 1446d7d0becSSaleem Abdulrasool// Thread ID 145ac15ae6dSPeter Collingbournetypedef long __libcpp_thread_id; 1466d7d0becSSaleem Abdulrasool 1476d7d0becSSaleem Abdulrasool// Thread 148af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 149af762e91SAsiri Rathnayake 150ac15ae6dSPeter Collingbournetypedef void* __libcpp_thread_t; 1516d7d0becSSaleem Abdulrasool 1526d7d0becSSaleem Abdulrasool// Thread Local Storage 153ac15ae6dSPeter Collingbournetypedef long __libcpp_tls_key; 1546d7d0becSSaleem Abdulrasool 155ac15ae6dSPeter Collingbourne#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall 156e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 157790e10f6SSaleem Abdulrasool 158e2b200b7SDavid Spickett#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 159790e10f6SSaleem Abdulrasool// Mutex 1608c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 16158a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); 16258a0dceeSSaleem Abdulrasool 16383dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 16458a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m); 16558a0dceeSSaleem Abdulrasool 16683dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 16708e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m); 16858a0dceeSSaleem Abdulrasool 16983dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 17058a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m); 17158a0dceeSSaleem Abdulrasool 17258a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY 17358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m); 174790e10f6SSaleem Abdulrasool 17583dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1768c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m); 177790e10f6SSaleem Abdulrasool 17883dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 17908e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m); 180790e10f6SSaleem Abdulrasool 18183dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1828c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m); 183790e10f6SSaleem Abdulrasool 1848c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1858c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m); 1868c2bf45dSAsiri Rathnayake 1878c2bf45dSAsiri Rathnayake// Condition variable 1888c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1898c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv); 190790e10f6SSaleem Abdulrasool 1918c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1928c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv); 193790e10f6SSaleem Abdulrasool 19483dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1958c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m); 196790e10f6SSaleem Abdulrasool 19783dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 198790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 199cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts); 200790e10f6SSaleem Abdulrasool 2018c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2028c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); 2038c2bf45dSAsiri Rathnayake 204205d7d3fSAsiri Rathnayake// Execute once 205205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 206205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 2074603460aSBruce Mitchener void (*init_routine)()); 208205d7d3fSAsiri Rathnayake 209205d7d3fSAsiri Rathnayake// Thread id 2108c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2118c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); 212790e10f6SSaleem Abdulrasool 2138c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2148c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); 2158c2bf45dSAsiri Rathnayake 2168c2bf45dSAsiri Rathnayake// Thread 2178c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 218af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t); 219af762e91SAsiri Rathnayake 220af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 221790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 222790e10f6SSaleem Abdulrasool void *__arg); 223790e10f6SSaleem Abdulrasool 2248c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2258c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id(); 226790e10f6SSaleem Abdulrasool 2278c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2288c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); 229790e10f6SSaleem Abdulrasool 2308c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2318c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t); 232790e10f6SSaleem Abdulrasool 2338c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2348c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t); 235790e10f6SSaleem Abdulrasool 2368c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2378c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield(); 2388c2bf45dSAsiri Rathnayake 23954a987e1SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2409e8a082dSJoerg Sonnenbergervoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns); 24154a987e1SAsiri Rathnayake 2428c2bf45dSAsiri Rathnayake// Thread local storage 2438c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2446d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key, 2456d7d0becSSaleem Abdulrasool void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)); 246790e10f6SSaleem Abdulrasool 2478c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2488c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key); 249790e10f6SSaleem Abdulrasool 2508c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 251205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p); 2528c2bf45dSAsiri Rathnayake 253e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 254e2b200b7SDavid Spickett 25514aef536SMikhail Maltsevstruct __libcpp_timed_backoff_policy { 25621a1a263SLouis Dionne _LIBCPP_INLINE_VISIBILITY 25721a1a263SLouis Dionne bool operator()(chrono::nanoseconds __elapsed) const 2583411a1a9SDavid Nicuesa { 2593411a1a9SDavid Nicuesa if(__elapsed > chrono::milliseconds(128)) 2603411a1a9SDavid Nicuesa __libcpp_thread_sleep_for(chrono::milliseconds(8)); 2613411a1a9SDavid Nicuesa else if(__elapsed > chrono::microseconds(64)) 2623411a1a9SDavid Nicuesa __libcpp_thread_sleep_for(__elapsed / 2); 2633411a1a9SDavid Nicuesa else if(__elapsed > chrono::microseconds(4)) 2643411a1a9SDavid Nicuesa __libcpp_thread_yield(); 2653411a1a9SDavid Nicuesa else 266d2acf229SMarek Kurdej {} // poll 2673411a1a9SDavid Nicuesa return false; 2683411a1a9SDavid Nicuesa } 26921a1a263SLouis Dionne}; 2703411a1a9SDavid Nicuesa 2713411a1a9SDavid Nicuesa#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 2723411a1a9SDavid Nicuesa defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) 2733411a1a9SDavid Nicuesa 27414aef536SMikhail Maltsev 275ab9aefeeSPetr Hoseknamespace __thread_detail { 276ab9aefeeSPetr Hosek 277ab9aefeeSPetr Hosekinline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) 278ab9aefeeSPetr Hosek{ 279ab9aefeeSPetr Hosek using namespace chrono; 280ab9aefeeSPetr Hosek seconds __s = duration_cast<seconds>(__ns); 281ab9aefeeSPetr Hosek __libcpp_timespec_t __ts; 282ab9aefeeSPetr Hosek typedef decltype(__ts.tv_sec) __ts_sec; 283ab9aefeeSPetr Hosek const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); 284ab9aefeeSPetr Hosek 285ab9aefeeSPetr Hosek if (__s.count() < __ts_sec_max) 286ab9aefeeSPetr Hosek { 287ab9aefeeSPetr Hosek __ts.tv_sec = static_cast<__ts_sec>(__s.count()); 288ab9aefeeSPetr Hosek __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); 289ab9aefeeSPetr Hosek } 290ab9aefeeSPetr Hosek else 291ab9aefeeSPetr Hosek { 292ab9aefeeSPetr Hosek __ts.tv_sec = __ts_sec_max; 293ab9aefeeSPetr Hosek __ts.tv_nsec = 999999999; // (10^9 - 1) 294ab9aefeeSPetr Hosek } 295ab9aefeeSPetr Hosek 296ab9aefeeSPetr Hosek return __ts; 297ab9aefeeSPetr Hosek} 298ab9aefeeSPetr Hosek 299*d2b0df35SNikolas Klauser} // namespace __thread_detail 300ab9aefeeSPetr Hosek 301ab9aefeeSPetr Hosek#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 3028c2bf45dSAsiri Rathnayake 30358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 304c7e4239fSAsiri Rathnayake{ 305c7e4239fSAsiri Rathnayake pthread_mutexattr_t attr; 306c7e4239fSAsiri Rathnayake int __ec = pthread_mutexattr_init(&attr); 307c7e4239fSAsiri Rathnayake if (__ec) 308790e10f6SSaleem Abdulrasool return __ec; 309790e10f6SSaleem Abdulrasool __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 310790e10f6SSaleem Abdulrasool if (__ec) { 311c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 312c7e4239fSAsiri Rathnayake return __ec; 313c7e4239fSAsiri Rathnayake } 314c7e4239fSAsiri Rathnayake __ec = pthread_mutex_init(__m, &attr); 315790e10f6SSaleem Abdulrasool if (__ec) { 316c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 317c7e4239fSAsiri Rathnayake return __ec; 318c7e4239fSAsiri Rathnayake } 319c7e4239fSAsiri Rathnayake __ec = pthread_mutexattr_destroy(&attr); 320790e10f6SSaleem Abdulrasool if (__ec) { 321c7e4239fSAsiri Rathnayake pthread_mutex_destroy(__m); 322c7e4239fSAsiri Rathnayake return __ec; 323c7e4239fSAsiri Rathnayake } 324c7e4239fSAsiri Rathnayake return 0; 325c7e4239fSAsiri Rathnayake} 326c7e4239fSAsiri Rathnayake 32758a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 32858a0dceeSSaleem Abdulrasool{ 32958a0dceeSSaleem Abdulrasool return pthread_mutex_lock(__m); 33058a0dceeSSaleem Abdulrasool} 33158a0dceeSSaleem Abdulrasool 33208e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 33358a0dceeSSaleem Abdulrasool{ 33408e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 33558a0dceeSSaleem Abdulrasool} 33658a0dceeSSaleem Abdulrasool 337ebfadd82SColin Finckint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m) 33858a0dceeSSaleem Abdulrasool{ 33958a0dceeSSaleem Abdulrasool return pthread_mutex_unlock(__m); 34058a0dceeSSaleem Abdulrasool} 34158a0dceeSSaleem Abdulrasool 34258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 34358a0dceeSSaleem Abdulrasool{ 34458a0dceeSSaleem Abdulrasool return pthread_mutex_destroy(__m); 34558a0dceeSSaleem Abdulrasool} 34658a0dceeSSaleem Abdulrasool 347c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 348c7e4239fSAsiri Rathnayake{ 349c7e4239fSAsiri Rathnayake return pthread_mutex_lock(__m); 350c7e4239fSAsiri Rathnayake} 351c7e4239fSAsiri Rathnayake 35208e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 353c7e4239fSAsiri Rathnayake{ 35408e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 355c7e4239fSAsiri Rathnayake} 356c7e4239fSAsiri Rathnayake 357c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 358c7e4239fSAsiri Rathnayake{ 359c7e4239fSAsiri Rathnayake return pthread_mutex_unlock(__m); 360c7e4239fSAsiri Rathnayake} 361c7e4239fSAsiri Rathnayake 362c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 363c7e4239fSAsiri Rathnayake{ 364c7e4239fSAsiri Rathnayake return pthread_mutex_destroy(__m); 365c7e4239fSAsiri Rathnayake} 366c7e4239fSAsiri Rathnayake 367790e10f6SSaleem Abdulrasool// Condition Variable 368c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 369c7e4239fSAsiri Rathnayake{ 370c7e4239fSAsiri Rathnayake return pthread_cond_signal(__cv); 371c7e4239fSAsiri Rathnayake} 372c7e4239fSAsiri Rathnayake 373c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 374c7e4239fSAsiri Rathnayake{ 375c7e4239fSAsiri Rathnayake return pthread_cond_broadcast(__cv); 376c7e4239fSAsiri Rathnayake} 377c7e4239fSAsiri Rathnayake 378c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 379c7e4239fSAsiri Rathnayake{ 380c7e4239fSAsiri Rathnayake return pthread_cond_wait(__cv, __m); 381c7e4239fSAsiri Rathnayake} 382c7e4239fSAsiri Rathnayake 383790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 384cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts) 385c7e4239fSAsiri Rathnayake{ 386c7e4239fSAsiri Rathnayake return pthread_cond_timedwait(__cv, __m, __ts); 387c7e4239fSAsiri Rathnayake} 388c7e4239fSAsiri Rathnayake 389c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 390c7e4239fSAsiri Rathnayake{ 391c7e4239fSAsiri Rathnayake return pthread_cond_destroy(__cv); 392c7e4239fSAsiri Rathnayake} 393c7e4239fSAsiri Rathnayake 394205d7d3fSAsiri Rathnayake// Execute once 395205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 3964603460aSBruce Mitchener void (*init_routine)()) { 397205d7d3fSAsiri Rathnayake return pthread_once(flag, init_routine); 398205d7d3fSAsiri Rathnayake} 399205d7d3fSAsiri Rathnayake 400205d7d3fSAsiri Rathnayake// Thread id 401c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0 402c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 403c7e4239fSAsiri Rathnayake{ 404e6c89a49SZbigniew Sarbinowski return t1 == t2; 405c7e4239fSAsiri Rathnayake} 406c7e4239fSAsiri Rathnayake 407c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0 408c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 409c7e4239fSAsiri Rathnayake{ 410c7e4239fSAsiri Rathnayake return t1 < t2; 411c7e4239fSAsiri Rathnayake} 412c7e4239fSAsiri Rathnayake 413c7e4239fSAsiri Rathnayake// Thread 414af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 41548fcce1aSZbigniew Sarbinowski return __libcpp_thread_get_id(__t) == 0; 416af762e91SAsiri Rathnayake} 417af762e91SAsiri Rathnayake 418790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 419790e10f6SSaleem Abdulrasool void *__arg) 420c7e4239fSAsiri Rathnayake{ 421527a7fdfSBruce Mitchener return pthread_create(__t, nullptr, __func, __arg); 422c7e4239fSAsiri Rathnayake} 423c7e4239fSAsiri Rathnayake 424c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id() 425c7e4239fSAsiri Rathnayake{ 426e6c89a49SZbigniew Sarbinowski const __libcpp_thread_t thread = pthread_self(); 427e6c89a49SZbigniew Sarbinowski return __libcpp_thread_get_id(&thread); 428c7e4239fSAsiri Rathnayake} 429c7e4239fSAsiri Rathnayake 430c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 431c7e4239fSAsiri Rathnayake{ 432e6c89a49SZbigniew Sarbinowski#if defined(__MVS__) 433e6c89a49SZbigniew Sarbinowski return __t->__; 434e6c89a49SZbigniew Sarbinowski#else 435c7e4239fSAsiri Rathnayake return *__t; 436e6c89a49SZbigniew Sarbinowski#endif 437c7e4239fSAsiri Rathnayake} 438c7e4239fSAsiri Rathnayake 439c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t) 440c7e4239fSAsiri Rathnayake{ 441527a7fdfSBruce Mitchener return pthread_join(*__t, nullptr); 442c7e4239fSAsiri Rathnayake} 443c7e4239fSAsiri Rathnayake 444c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t) 445c7e4239fSAsiri Rathnayake{ 446c7e4239fSAsiri Rathnayake return pthread_detach(*__t); 447c7e4239fSAsiri Rathnayake} 448c7e4239fSAsiri Rathnayake 449c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield() 450c7e4239fSAsiri Rathnayake{ 451c7e4239fSAsiri Rathnayake sched_yield(); 452c7e4239fSAsiri Rathnayake} 453c7e4239fSAsiri Rathnayake 45454a987e1SAsiri Rathnayakevoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 45554a987e1SAsiri Rathnayake{ 456ab9aefeeSPetr Hosek __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); 45754a987e1SAsiri Rathnayake while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); 45854a987e1SAsiri Rathnayake} 45954a987e1SAsiri Rathnayake 460c7e4239fSAsiri Rathnayake// Thread local storage 4618c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 462c7e4239fSAsiri Rathnayake{ 463c7e4239fSAsiri Rathnayake return pthread_key_create(__key, __at_exit); 464c7e4239fSAsiri Rathnayake} 465c7e4239fSAsiri Rathnayake 4668c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key) 467c7e4239fSAsiri Rathnayake{ 468c7e4239fSAsiri Rathnayake return pthread_getspecific(__key); 469c7e4239fSAsiri Rathnayake} 470c7e4239fSAsiri Rathnayake 471205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 472c7e4239fSAsiri Rathnayake{ 473205d7d3fSAsiri Rathnayake return pthread_setspecific(__key, __p); 474c7e4239fSAsiri Rathnayake} 475c7e4239fSAsiri Rathnayake 476ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11) 477ab9aefeeSPetr Hosek 478ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 479ab9aefeeSPetr Hosek{ 4803481e5d7SPetr Hosek return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL; 481ab9aefeeSPetr Hosek} 482ab9aefeeSPetr Hosek 483ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 484ab9aefeeSPetr Hosek{ 485ab9aefeeSPetr Hosek return mtx_lock(__m) == thrd_success ? 0 : EINVAL; 486ab9aefeeSPetr Hosek} 487ab9aefeeSPetr Hosek 488ab9aefeeSPetr Hosekbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 489ab9aefeeSPetr Hosek{ 490ab9aefeeSPetr Hosek return mtx_trylock(__m) == thrd_success; 491ab9aefeeSPetr Hosek} 492ab9aefeeSPetr Hosek 493ebfadd82SColin Finckint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m) 494ab9aefeeSPetr Hosek{ 495ab9aefeeSPetr Hosek return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; 496ab9aefeeSPetr Hosek} 497ab9aefeeSPetr Hosek 498ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 499ab9aefeeSPetr Hosek{ 500ab9aefeeSPetr Hosek mtx_destroy(__m); 501ab9aefeeSPetr Hosek return 0; 502ab9aefeeSPetr Hosek} 503ab9aefeeSPetr Hosek 504ab9aefeeSPetr Hosekint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 505ab9aefeeSPetr Hosek{ 506ab9aefeeSPetr Hosek return mtx_lock(__m) == thrd_success ? 0 : EINVAL; 507ab9aefeeSPetr Hosek} 508ab9aefeeSPetr Hosek 509ab9aefeeSPetr Hosekbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 510ab9aefeeSPetr Hosek{ 511ab9aefeeSPetr Hosek return mtx_trylock(__m) == thrd_success; 512ab9aefeeSPetr Hosek} 513ab9aefeeSPetr Hosek 514ab9aefeeSPetr Hosekint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 515ab9aefeeSPetr Hosek{ 516ab9aefeeSPetr Hosek return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; 517ab9aefeeSPetr Hosek} 518ab9aefeeSPetr Hosek 519ab9aefeeSPetr Hosekint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 520ab9aefeeSPetr Hosek{ 521ab9aefeeSPetr Hosek mtx_destroy(__m); 522ab9aefeeSPetr Hosek return 0; 523ab9aefeeSPetr Hosek} 524ab9aefeeSPetr Hosek 525ab9aefeeSPetr Hosek// Condition Variable 526ab9aefeeSPetr Hosekint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 527ab9aefeeSPetr Hosek{ 528ab9aefeeSPetr Hosek return cnd_signal(__cv) == thrd_success ? 0 : EINVAL; 529ab9aefeeSPetr Hosek} 530ab9aefeeSPetr Hosek 531ab9aefeeSPetr Hosekint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 532ab9aefeeSPetr Hosek{ 533ab9aefeeSPetr Hosek return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL; 534ab9aefeeSPetr Hosek} 535ab9aefeeSPetr Hosek 536ab9aefeeSPetr Hosekint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 537ab9aefeeSPetr Hosek{ 538ab9aefeeSPetr Hosek return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL; 539ab9aefeeSPetr Hosek} 540ab9aefeeSPetr Hosek 541ab9aefeeSPetr Hosekint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 542ab9aefeeSPetr Hosek timespec *__ts) 543ab9aefeeSPetr Hosek{ 544ab9aefeeSPetr Hosek int __ec = cnd_timedwait(__cv, __m, __ts); 545ab9aefeeSPetr Hosek return __ec == thrd_timedout ? ETIMEDOUT : __ec; 546ab9aefeeSPetr Hosek} 547ab9aefeeSPetr Hosek 548ab9aefeeSPetr Hosekint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 549ab9aefeeSPetr Hosek{ 550ab9aefeeSPetr Hosek cnd_destroy(__cv); 551ab9aefeeSPetr Hosek return 0; 552ab9aefeeSPetr Hosek} 553ab9aefeeSPetr Hosek 554ab9aefeeSPetr Hosek// Execute once 555ab9aefeeSPetr Hosekint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 556ab9aefeeSPetr Hosek void (*init_routine)(void)) { 557ab9aefeeSPetr Hosek ::call_once(flag, init_routine); 558ab9aefeeSPetr Hosek return 0; 559ab9aefeeSPetr Hosek} 560ab9aefeeSPetr Hosek 561ab9aefeeSPetr Hosek// Thread id 562ab9aefeeSPetr Hosek// Returns non-zero if the thread ids are equal, otherwise 0 563ab9aefeeSPetr Hosekbool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 564ab9aefeeSPetr Hosek{ 565ab9aefeeSPetr Hosek return thrd_equal(t1, t2) != 0; 566ab9aefeeSPetr Hosek} 567ab9aefeeSPetr Hosek 568ab9aefeeSPetr Hosek// Returns non-zero if t1 < t2, otherwise 0 569ab9aefeeSPetr Hosekbool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 570ab9aefeeSPetr Hosek{ 571ab9aefeeSPetr Hosek return t1 < t2; 572ab9aefeeSPetr Hosek} 573ab9aefeeSPetr Hosek 574ab9aefeeSPetr Hosek// Thread 575ab9aefeeSPetr Hosekbool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 576e6c89a49SZbigniew Sarbinowski return __libcpp_thread_get_id(__t) == 0; 577ab9aefeeSPetr Hosek} 578ab9aefeeSPetr Hosek 579ab9aefeeSPetr Hosekint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 580ab9aefeeSPetr Hosek void *__arg) 581ab9aefeeSPetr Hosek{ 582ab9aefeeSPetr Hosek int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg); 583ab9aefeeSPetr Hosek return __ec == thrd_nomem ? ENOMEM : __ec; 584ab9aefeeSPetr Hosek} 585ab9aefeeSPetr Hosek 586ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_current_id() 587ab9aefeeSPetr Hosek{ 588ab9aefeeSPetr Hosek return thrd_current(); 589ab9aefeeSPetr Hosek} 590ab9aefeeSPetr Hosek 591ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 592ab9aefeeSPetr Hosek{ 593ab9aefeeSPetr Hosek return *__t; 594ab9aefeeSPetr Hosek} 595ab9aefeeSPetr Hosek 596ab9aefeeSPetr Hosekint __libcpp_thread_join(__libcpp_thread_t *__t) 597ab9aefeeSPetr Hosek{ 598ab9aefeeSPetr Hosek return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL; 599ab9aefeeSPetr Hosek} 600ab9aefeeSPetr Hosek 601ab9aefeeSPetr Hosekint __libcpp_thread_detach(__libcpp_thread_t *__t) 602ab9aefeeSPetr Hosek{ 603ab9aefeeSPetr Hosek return thrd_detach(*__t) == thrd_success ? 0 : EINVAL; 604ab9aefeeSPetr Hosek} 605ab9aefeeSPetr Hosek 606ab9aefeeSPetr Hosekvoid __libcpp_thread_yield() 607ab9aefeeSPetr Hosek{ 608ab9aefeeSPetr Hosek thrd_yield(); 609ab9aefeeSPetr Hosek} 610ab9aefeeSPetr Hosek 611ab9aefeeSPetr Hosekvoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 612ab9aefeeSPetr Hosek{ 613ab9aefeeSPetr Hosek __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); 614ab9aefeeSPetr Hosek thrd_sleep(&__ts, nullptr); 615ab9aefeeSPetr Hosek} 616ab9aefeeSPetr Hosek 617ab9aefeeSPetr Hosek// Thread local storage 618ab9aefeeSPetr Hosekint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 619ab9aefeeSPetr Hosek{ 620ab9aefeeSPetr Hosek return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL; 621ab9aefeeSPetr Hosek} 622ab9aefeeSPetr Hosek 623ab9aefeeSPetr Hosekvoid *__libcpp_tls_get(__libcpp_tls_key __key) 624ab9aefeeSPetr Hosek{ 625ab9aefeeSPetr Hosek return tss_get(__key); 626ab9aefeeSPetr Hosek} 627ab9aefeeSPetr Hosek 628ab9aefeeSPetr Hosekint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 629ab9aefeeSPetr Hosek{ 630ab9aefeeSPetr Hosek return tss_set(__key, __p) == thrd_success ? 0 : EINVAL; 631ab9aefeeSPetr Hosek} 632ab9aefeeSPetr Hosek 633ab9aefeeSPetr Hosek#endif 634ab9aefeeSPetr Hosek 635e3add3e5SMartin Storsjö 63600f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL 63700f6beaeSEric Fiselier 6382b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS thread; 6392b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS __thread_id; 6402b1d4254SMarshall Clow 6412b1d4254SMarshall Clownamespace this_thread 6422b1d4254SMarshall Clow{ 6432b1d4254SMarshall Clow 6442b1d4254SMarshall Clow_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; 6452b1d4254SMarshall Clow 646*d2b0df35SNikolas Klauser} // namespace this_thread 6472b1d4254SMarshall Clow 6482b1d4254SMarshall Clowtemplate<> struct hash<__thread_id>; 6492b1d4254SMarshall Clow 6502b1d4254SMarshall Clowclass _LIBCPP_TEMPLATE_VIS __thread_id 6512b1d4254SMarshall Clow{ 6522b1d4254SMarshall Clow // FIXME: pthread_t is a pointer on Darwin but a long on Linux. 6532b1d4254SMarshall Clow // NULL is the no-thread value on Darwin. Someone needs to check 6542b1d4254SMarshall Clow // on other platforms. We assume 0 works everywhere for now. 6552b1d4254SMarshall Clow __libcpp_thread_id __id_; 6562b1d4254SMarshall Clow 6572b1d4254SMarshall Clowpublic: 6582b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 6592b1d4254SMarshall Clow __thread_id() _NOEXCEPT : __id_(0) {} 6602b1d4254SMarshall Clow 6612b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6622b1d4254SMarshall Clow bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT 6632e80d01fSMarshall Clow { // don't pass id==0 to underlying routines 6642e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ == 0; 6652e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 6662e80d01fSMarshall Clow return __libcpp_thread_id_equal(__x.__id_, __y.__id_); 6672e80d01fSMarshall Clow } 6682b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6692b1d4254SMarshall Clow bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT 6702b1d4254SMarshall Clow {return !(__x == __y);} 6712b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6722b1d4254SMarshall Clow bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT 6732e80d01fSMarshall Clow { // id==0 is always less than any other thread_id 6742e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ != 0; 6752e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 6762e80d01fSMarshall Clow return __libcpp_thread_id_less(__x.__id_, __y.__id_); 6772e80d01fSMarshall Clow } 6782b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6792b1d4254SMarshall Clow bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT 6802b1d4254SMarshall Clow {return !(__y < __x);} 6812b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6822b1d4254SMarshall Clow bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT 6832b1d4254SMarshall Clow {return __y < __x ;} 6842b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 6852b1d4254SMarshall Clow bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT 6862b1d4254SMarshall Clow {return !(__x < __y);} 6872b1d4254SMarshall Clow 6882b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 6892e80d01fSMarshall Clow void __reset() { __id_ = 0; } 6902b1d4254SMarshall Clow 6912b1d4254SMarshall Clow template<class _CharT, class _Traits> 6922b1d4254SMarshall Clow friend 6932b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 6942b1d4254SMarshall Clow basic_ostream<_CharT, _Traits>& 6952b1d4254SMarshall Clow operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); 6962b1d4254SMarshall Clow 6972b1d4254SMarshall Clowprivate: 6982b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 6992b1d4254SMarshall Clow __thread_id(__libcpp_thread_id __id) : __id_(__id) {} 7002b1d4254SMarshall Clow 7012b1d4254SMarshall Clow friend __thread_id this_thread::get_id() _NOEXCEPT; 7022b1d4254SMarshall Clow friend class _LIBCPP_TYPE_VIS thread; 7032b1d4254SMarshall Clow friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; 7042b1d4254SMarshall Clow}; 7052b1d4254SMarshall Clow 7062b1d4254SMarshall Clownamespace this_thread 7072b1d4254SMarshall Clow{ 7082b1d4254SMarshall Clow 7092b1d4254SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY 7102b1d4254SMarshall Clow__thread_id 7112b1d4254SMarshall Clowget_id() _NOEXCEPT 7122b1d4254SMarshall Clow{ 7132b1d4254SMarshall Clow return __libcpp_thread_get_current_id(); 7142b1d4254SMarshall Clow} 7152b1d4254SMarshall Clow 716*d2b0df35SNikolas Klauser} // namespace this_thread 7172b1d4254SMarshall Clow 718696630eaSMarshall Clow#endif // !_LIBCPP_HAS_NO_THREADS 719696630eaSMarshall Clow 720c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD 721c7e4239fSAsiri Rathnayake 722a016efb1SEric Fiselier_LIBCPP_POP_MACROS 723a016efb1SEric Fiselier 724c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT 725