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 26cfdc7f0dSMikhail Maltsevtypedef ::timespec __libcpp_timespec_t; 27cfdc7f0dSMikhail Maltsev 2800f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 29c7e4239fSAsiri Rathnayake# include <pthread.h> 30c7e4239fSAsiri Rathnayake# include <sched.h> 31790e10f6SSaleem Abdulrasool#endif 32c7e4239fSAsiri Rathnayake 33a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS 34a016efb1SEric Fiselier#include <__undef_macros> 35a016efb1SEric Fiselier 362a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 372a129dc3SPeter Collingbourne defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \ 382a129dc3SPeter Collingbourne defined(_LIBCPP_HAS_THREAD_API_WIN32) 392a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS 402a129dc3SPeter Collingbourne#else 412a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY 422a129dc3SPeter Collingbourne#endif 432a129dc3SPeter Collingbourne 4483dca5c3SDimitry Andric#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis) 4583dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) 4683dca5c3SDimitry Andric#else 4783dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 4883dca5c3SDimitry Andric#endif 4983dca5c3SDimitry Andric 50c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD 51c7e4239fSAsiri Rathnayake 522a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 53c7e4239fSAsiri Rathnayake// Mutex 54c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t; 558c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 56c7e4239fSAsiri Rathnayake 5758a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t; 5858a0dceeSSaleem Abdulrasool 59790e10f6SSaleem Abdulrasool// Condition Variable 60790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t; 61790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER 62790e10f6SSaleem Abdulrasool 63205d7d3fSAsiri Rathnayake// Execute once 64205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag; 65205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT 66205d7d3fSAsiri Rathnayake 67205d7d3fSAsiri Rathnayake// Thread id 68790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_id; 69790e10f6SSaleem Abdulrasool 70790e10f6SSaleem Abdulrasool// Thread 71af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 72af762e91SAsiri Rathnayake 73790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t; 74790e10f6SSaleem Abdulrasool 75cac6d217SFangrui Song// Thread Local Storage 76790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key; 776d7d0becSSaleem Abdulrasool 786d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC 796d7d0becSSaleem Abdulrasool#else 80ac15ae6dSPeter Collingbourne// Mutex 81ac15ae6dSPeter Collingbournetypedef void* __libcpp_mutex_t; 82ac15ae6dSPeter Collingbourne#define _LIBCPP_MUTEX_INITIALIZER 0 83ac15ae6dSPeter Collingbourne 84ac15ae6dSPeter Collingbourne#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__) 85ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[6]; 86ac15ae6dSPeter Collingbourne#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__) 87ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[5]; 88ac15ae6dSPeter Collingbourne#else 89ac15ae6dSPeter Collingbourne# error Unsupported architecture 90ac15ae6dSPeter Collingbourne#endif 916d7d0becSSaleem Abdulrasool 926d7d0becSSaleem Abdulrasool// Condition Variable 93ac15ae6dSPeter Collingbournetypedef void* __libcpp_condvar_t; 94ac15ae6dSPeter Collingbourne#define _LIBCPP_CONDVAR_INITIALIZER 0 956d7d0becSSaleem Abdulrasool 966d7d0becSSaleem Abdulrasool// Execute Once 97ac15ae6dSPeter Collingbournetypedef void* __libcpp_exec_once_flag; 98ac15ae6dSPeter Collingbourne#define _LIBCPP_EXEC_ONCE_INITIALIZER 0 996d7d0becSSaleem Abdulrasool 1006d7d0becSSaleem Abdulrasool// Thread ID 101ac15ae6dSPeter Collingbournetypedef long __libcpp_thread_id; 1026d7d0becSSaleem Abdulrasool 1036d7d0becSSaleem Abdulrasool// Thread 104af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 105af762e91SAsiri Rathnayake 106ac15ae6dSPeter Collingbournetypedef void* __libcpp_thread_t; 1076d7d0becSSaleem Abdulrasool 1086d7d0becSSaleem Abdulrasool// Thread Local Storage 109ac15ae6dSPeter Collingbournetypedef long __libcpp_tls_key; 1106d7d0becSSaleem Abdulrasool 111ac15ae6dSPeter Collingbourne#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall 112790e10f6SSaleem Abdulrasool#endif 113790e10f6SSaleem Abdulrasool 114790e10f6SSaleem Abdulrasool// Mutex 1158c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 11658a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); 11758a0dceeSSaleem Abdulrasool 11883dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 11958a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m); 12058a0dceeSSaleem Abdulrasool 12183dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 12208e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m); 12358a0dceeSSaleem Abdulrasool 12483dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 12558a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m); 12658a0dceeSSaleem Abdulrasool 12758a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY 12858a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m); 129790e10f6SSaleem Abdulrasool 13083dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1318c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m); 132790e10f6SSaleem Abdulrasool 13383dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 13408e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m); 135790e10f6SSaleem Abdulrasool 13683dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1378c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m); 138790e10f6SSaleem Abdulrasool 1398c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1408c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m); 1418c2bf45dSAsiri Rathnayake 1428c2bf45dSAsiri Rathnayake// Condition variable 1438c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1448c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv); 145790e10f6SSaleem Abdulrasool 1468c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1478c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv); 148790e10f6SSaleem Abdulrasool 14983dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1508c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m); 151790e10f6SSaleem Abdulrasool 15283dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 153790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 154cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts); 155790e10f6SSaleem Abdulrasool 1568c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1578c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); 1588c2bf45dSAsiri Rathnayake 159205d7d3fSAsiri Rathnayake// Execute once 160205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 161205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 1624603460aSBruce Mitchener void (*init_routine)()); 163205d7d3fSAsiri Rathnayake 164205d7d3fSAsiri Rathnayake// Thread id 1658c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1668c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); 167790e10f6SSaleem Abdulrasool 1688c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1698c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); 1708c2bf45dSAsiri Rathnayake 1718c2bf45dSAsiri Rathnayake// Thread 1728c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 173af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t); 174af762e91SAsiri Rathnayake 175af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 176790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 177790e10f6SSaleem Abdulrasool void *__arg); 178790e10f6SSaleem Abdulrasool 1798c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1808c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id(); 181790e10f6SSaleem Abdulrasool 1828c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1838c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); 184790e10f6SSaleem Abdulrasool 1858c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1868c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t); 187790e10f6SSaleem Abdulrasool 1888c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1898c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t); 190790e10f6SSaleem Abdulrasool 1918c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1928c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield(); 1938c2bf45dSAsiri Rathnayake 19454a987e1SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1959e8a082dSJoerg Sonnenbergervoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns); 19654a987e1SAsiri Rathnayake 1978c2bf45dSAsiri Rathnayake// Thread local storage 1988c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1996d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key, 2006d7d0becSSaleem Abdulrasool void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)); 201790e10f6SSaleem Abdulrasool 2028c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 2038c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key); 204790e10f6SSaleem Abdulrasool 2058c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 206205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p); 2078c2bf45dSAsiri Rathnayake 208ac15ae6dSPeter Collingbourne#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 209ac15ae6dSPeter Collingbourne defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \ 210ac15ae6dSPeter Collingbourne defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 2118c2bf45dSAsiri Rathnayake 21258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 213c7e4239fSAsiri Rathnayake{ 214c7e4239fSAsiri Rathnayake pthread_mutexattr_t attr; 215c7e4239fSAsiri Rathnayake int __ec = pthread_mutexattr_init(&attr); 216c7e4239fSAsiri Rathnayake if (__ec) 217790e10f6SSaleem Abdulrasool return __ec; 218790e10f6SSaleem Abdulrasool __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 219790e10f6SSaleem Abdulrasool if (__ec) { 220c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 221c7e4239fSAsiri Rathnayake return __ec; 222c7e4239fSAsiri Rathnayake } 223c7e4239fSAsiri Rathnayake __ec = pthread_mutex_init(__m, &attr); 224790e10f6SSaleem Abdulrasool if (__ec) { 225c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 226c7e4239fSAsiri Rathnayake return __ec; 227c7e4239fSAsiri Rathnayake } 228c7e4239fSAsiri Rathnayake __ec = pthread_mutexattr_destroy(&attr); 229790e10f6SSaleem Abdulrasool if (__ec) { 230c7e4239fSAsiri Rathnayake pthread_mutex_destroy(__m); 231c7e4239fSAsiri Rathnayake return __ec; 232c7e4239fSAsiri Rathnayake } 233c7e4239fSAsiri Rathnayake return 0; 234c7e4239fSAsiri Rathnayake} 235c7e4239fSAsiri Rathnayake 23658a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 23758a0dceeSSaleem Abdulrasool{ 23858a0dceeSSaleem Abdulrasool return pthread_mutex_lock(__m); 23958a0dceeSSaleem Abdulrasool} 24058a0dceeSSaleem Abdulrasool 24108e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 24258a0dceeSSaleem Abdulrasool{ 24308e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 24458a0dceeSSaleem Abdulrasool} 24558a0dceeSSaleem Abdulrasool 24658a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m) 24758a0dceeSSaleem Abdulrasool{ 24858a0dceeSSaleem Abdulrasool return pthread_mutex_unlock(__m); 24958a0dceeSSaleem Abdulrasool} 25058a0dceeSSaleem Abdulrasool 25158a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 25258a0dceeSSaleem Abdulrasool{ 25358a0dceeSSaleem Abdulrasool return pthread_mutex_destroy(__m); 25458a0dceeSSaleem Abdulrasool} 25558a0dceeSSaleem Abdulrasool 256c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 257c7e4239fSAsiri Rathnayake{ 258c7e4239fSAsiri Rathnayake return pthread_mutex_lock(__m); 259c7e4239fSAsiri Rathnayake} 260c7e4239fSAsiri Rathnayake 26108e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 262c7e4239fSAsiri Rathnayake{ 26308e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 264c7e4239fSAsiri Rathnayake} 265c7e4239fSAsiri Rathnayake 266c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 267c7e4239fSAsiri Rathnayake{ 268c7e4239fSAsiri Rathnayake return pthread_mutex_unlock(__m); 269c7e4239fSAsiri Rathnayake} 270c7e4239fSAsiri Rathnayake 271c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 272c7e4239fSAsiri Rathnayake{ 273c7e4239fSAsiri Rathnayake return pthread_mutex_destroy(__m); 274c7e4239fSAsiri Rathnayake} 275c7e4239fSAsiri Rathnayake 276790e10f6SSaleem Abdulrasool// Condition Variable 277c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 278c7e4239fSAsiri Rathnayake{ 279c7e4239fSAsiri Rathnayake return pthread_cond_signal(__cv); 280c7e4239fSAsiri Rathnayake} 281c7e4239fSAsiri Rathnayake 282c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 283c7e4239fSAsiri Rathnayake{ 284c7e4239fSAsiri Rathnayake return pthread_cond_broadcast(__cv); 285c7e4239fSAsiri Rathnayake} 286c7e4239fSAsiri Rathnayake 287c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 288c7e4239fSAsiri Rathnayake{ 289c7e4239fSAsiri Rathnayake return pthread_cond_wait(__cv, __m); 290c7e4239fSAsiri Rathnayake} 291c7e4239fSAsiri Rathnayake 292790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 293cfdc7f0dSMikhail Maltsev __libcpp_timespec_t *__ts) 294c7e4239fSAsiri Rathnayake{ 295c7e4239fSAsiri Rathnayake return pthread_cond_timedwait(__cv, __m, __ts); 296c7e4239fSAsiri Rathnayake} 297c7e4239fSAsiri Rathnayake 298c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 299c7e4239fSAsiri Rathnayake{ 300c7e4239fSAsiri Rathnayake return pthread_cond_destroy(__cv); 301c7e4239fSAsiri Rathnayake} 302c7e4239fSAsiri Rathnayake 303205d7d3fSAsiri Rathnayake// Execute once 304205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 3054603460aSBruce Mitchener void (*init_routine)()) { 306205d7d3fSAsiri Rathnayake return pthread_once(flag, init_routine); 307205d7d3fSAsiri Rathnayake} 308205d7d3fSAsiri Rathnayake 309205d7d3fSAsiri Rathnayake// Thread id 310c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0 311c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 312c7e4239fSAsiri Rathnayake{ 313c7e4239fSAsiri Rathnayake return pthread_equal(t1, t2) != 0; 314c7e4239fSAsiri Rathnayake} 315c7e4239fSAsiri Rathnayake 316c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0 317c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 318c7e4239fSAsiri Rathnayake{ 319c7e4239fSAsiri Rathnayake return t1 < t2; 320c7e4239fSAsiri Rathnayake} 321c7e4239fSAsiri Rathnayake 322c7e4239fSAsiri Rathnayake// Thread 323af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 324af762e91SAsiri Rathnayake return *__t == 0; 325af762e91SAsiri Rathnayake} 326af762e91SAsiri Rathnayake 327790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 328790e10f6SSaleem Abdulrasool void *__arg) 329c7e4239fSAsiri Rathnayake{ 330c7e4239fSAsiri Rathnayake return pthread_create(__t, 0, __func, __arg); 331c7e4239fSAsiri Rathnayake} 332c7e4239fSAsiri Rathnayake 333c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id() 334c7e4239fSAsiri Rathnayake{ 335c7e4239fSAsiri Rathnayake return pthread_self(); 336c7e4239fSAsiri Rathnayake} 337c7e4239fSAsiri Rathnayake 338c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 339c7e4239fSAsiri Rathnayake{ 340c7e4239fSAsiri Rathnayake return *__t; 341c7e4239fSAsiri Rathnayake} 342c7e4239fSAsiri Rathnayake 343c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t) 344c7e4239fSAsiri Rathnayake{ 345c7e4239fSAsiri Rathnayake return pthread_join(*__t, 0); 346c7e4239fSAsiri Rathnayake} 347c7e4239fSAsiri Rathnayake 348c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t) 349c7e4239fSAsiri Rathnayake{ 350c7e4239fSAsiri Rathnayake return pthread_detach(*__t); 351c7e4239fSAsiri Rathnayake} 352c7e4239fSAsiri Rathnayake 353c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield() 354c7e4239fSAsiri Rathnayake{ 355c7e4239fSAsiri Rathnayake sched_yield(); 356c7e4239fSAsiri Rathnayake} 357c7e4239fSAsiri Rathnayake 35854a987e1SAsiri Rathnayakevoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) 35954a987e1SAsiri Rathnayake{ 36054a987e1SAsiri Rathnayake using namespace chrono; 36154a987e1SAsiri Rathnayake seconds __s = duration_cast<seconds>(__ns); 362cfdc7f0dSMikhail Maltsev __libcpp_timespec_t __ts; 36354a987e1SAsiri Rathnayake typedef decltype(__ts.tv_sec) ts_sec; 36454a987e1SAsiri Rathnayake _LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits<ts_sec>::max(); 36554a987e1SAsiri Rathnayake 36654a987e1SAsiri Rathnayake if (__s.count() < __ts_sec_max) 36754a987e1SAsiri Rathnayake { 36854a987e1SAsiri Rathnayake __ts.tv_sec = static_cast<ts_sec>(__s.count()); 36954a987e1SAsiri Rathnayake __ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count()); 37054a987e1SAsiri Rathnayake } 37154a987e1SAsiri Rathnayake else 37254a987e1SAsiri Rathnayake { 37354a987e1SAsiri Rathnayake __ts.tv_sec = __ts_sec_max; 37454a987e1SAsiri Rathnayake __ts.tv_nsec = 999999999; // (10^9 - 1) 37554a987e1SAsiri Rathnayake } 37654a987e1SAsiri Rathnayake 37754a987e1SAsiri Rathnayake while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); 37854a987e1SAsiri Rathnayake} 37954a987e1SAsiri Rathnayake 380c7e4239fSAsiri Rathnayake// Thread local storage 3818c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 382c7e4239fSAsiri Rathnayake{ 383c7e4239fSAsiri Rathnayake return pthread_key_create(__key, __at_exit); 384c7e4239fSAsiri Rathnayake} 385c7e4239fSAsiri Rathnayake 3868c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key) 387c7e4239fSAsiri Rathnayake{ 388c7e4239fSAsiri Rathnayake return pthread_getspecific(__key); 389c7e4239fSAsiri Rathnayake} 390c7e4239fSAsiri Rathnayake 391205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 392c7e4239fSAsiri Rathnayake{ 393205d7d3fSAsiri Rathnayake return pthread_setspecific(__key, __p); 394c7e4239fSAsiri Rathnayake} 395c7e4239fSAsiri Rathnayake 39600f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL 39700f6beaeSEric Fiselier 3982b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS thread; 3992b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS __thread_id; 4002b1d4254SMarshall Clow 4012b1d4254SMarshall Clownamespace this_thread 4022b1d4254SMarshall Clow{ 4032b1d4254SMarshall Clow 4042b1d4254SMarshall Clow_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; 4052b1d4254SMarshall Clow 4062b1d4254SMarshall Clow} // this_thread 4072b1d4254SMarshall Clow 4082b1d4254SMarshall Clowtemplate<> struct hash<__thread_id>; 4092b1d4254SMarshall Clow 4102b1d4254SMarshall Clowclass _LIBCPP_TEMPLATE_VIS __thread_id 4112b1d4254SMarshall Clow{ 4122b1d4254SMarshall Clow // FIXME: pthread_t is a pointer on Darwin but a long on Linux. 4132b1d4254SMarshall Clow // NULL is the no-thread value on Darwin. Someone needs to check 4142b1d4254SMarshall Clow // on other platforms. We assume 0 works everywhere for now. 4152b1d4254SMarshall Clow __libcpp_thread_id __id_; 4162b1d4254SMarshall Clow 4172b1d4254SMarshall Clowpublic: 4182b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 4192b1d4254SMarshall Clow __thread_id() _NOEXCEPT : __id_(0) {} 4202b1d4254SMarshall Clow 4212b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 4222b1d4254SMarshall Clow bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT 423*2e80d01fSMarshall Clow { // don't pass id==0 to underlying routines 424*2e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ == 0; 425*2e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 426*2e80d01fSMarshall Clow return __libcpp_thread_id_equal(__x.__id_, __y.__id_); 427*2e80d01fSMarshall Clow } 4282b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 4292b1d4254SMarshall Clow bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT 4302b1d4254SMarshall Clow {return !(__x == __y);} 4312b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 4322b1d4254SMarshall Clow bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT 433*2e80d01fSMarshall Clow { // id==0 is always less than any other thread_id 434*2e80d01fSMarshall Clow if (__x.__id_ == 0) return __y.__id_ != 0; 435*2e80d01fSMarshall Clow if (__y.__id_ == 0) return false; 436*2e80d01fSMarshall Clow return __libcpp_thread_id_less(__x.__id_, __y.__id_); 437*2e80d01fSMarshall Clow } 4382b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 4392b1d4254SMarshall Clow bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT 4402b1d4254SMarshall Clow {return !(__y < __x);} 4412b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 4422b1d4254SMarshall Clow bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT 4432b1d4254SMarshall Clow {return __y < __x ;} 4442b1d4254SMarshall Clow friend _LIBCPP_INLINE_VISIBILITY 4452b1d4254SMarshall Clow bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT 4462b1d4254SMarshall Clow {return !(__x < __y);} 4472b1d4254SMarshall Clow 4482b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 449*2e80d01fSMarshall Clow void __reset() { __id_ = 0; } 4502b1d4254SMarshall Clow 4512b1d4254SMarshall Clow template<class _CharT, class _Traits> 4522b1d4254SMarshall Clow friend 4532b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 4542b1d4254SMarshall Clow basic_ostream<_CharT, _Traits>& 4552b1d4254SMarshall Clow operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); 4562b1d4254SMarshall Clow 4572b1d4254SMarshall Clowprivate: 4582b1d4254SMarshall Clow _LIBCPP_INLINE_VISIBILITY 4592b1d4254SMarshall Clow __thread_id(__libcpp_thread_id __id) : __id_(__id) {} 4602b1d4254SMarshall Clow 4612b1d4254SMarshall Clow friend __thread_id this_thread::get_id() _NOEXCEPT; 4622b1d4254SMarshall Clow friend class _LIBCPP_TYPE_VIS thread; 4632b1d4254SMarshall Clow friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; 4642b1d4254SMarshall Clow}; 4652b1d4254SMarshall Clow 4662b1d4254SMarshall Clownamespace this_thread 4672b1d4254SMarshall Clow{ 4682b1d4254SMarshall Clow 4692b1d4254SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY 4702b1d4254SMarshall Clow__thread_id 4712b1d4254SMarshall Clowget_id() _NOEXCEPT 4722b1d4254SMarshall Clow{ 4732b1d4254SMarshall Clow return __libcpp_thread_get_current_id(); 4742b1d4254SMarshall Clow} 4752b1d4254SMarshall Clow 4762b1d4254SMarshall Clow} // this_thread 4772b1d4254SMarshall Clow 478c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD 479c7e4239fSAsiri Rathnayake 480a016efb1SEric Fiselier_LIBCPP_POP_MACROS 481a016efb1SEric Fiselier 48200f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_NO_THREADS 483c7e4239fSAsiri Rathnayake 484c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT 485