1c7e4239fSAsiri Rathnayake// -*- C++ -*- 2c7e4239fSAsiri Rathnayake//===----------------------------------------------------------------------===// 3c7e4239fSAsiri Rathnayake// 4c7e4239fSAsiri Rathnayake// The LLVM Compiler Infrastructure 5c7e4239fSAsiri Rathnayake// 6c7e4239fSAsiri Rathnayake// This file is dual licensed under the MIT and the University of Illinois Open 7c7e4239fSAsiri Rathnayake// Source Licenses. See LICENSE.TXT for details. 8c7e4239fSAsiri Rathnayake// 9c7e4239fSAsiri Rathnayake//===----------------------------------------------------------------------===// 10c7e4239fSAsiri Rathnayake 11c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_THREADING_SUPPORT 12c7e4239fSAsiri Rathnayake#define _LIBCPP_THREADING_SUPPORT 13c7e4239fSAsiri Rathnayake 14c7e4239fSAsiri Rathnayake#include <__config> 15c7e4239fSAsiri Rathnayake 16c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER 17c7e4239fSAsiri Rathnayake#pragma GCC system_header 18c7e4239fSAsiri Rathnayake#endif 19c7e4239fSAsiri Rathnayake 2000f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) 213cf2f7bcSAsiri Rathnayake# include <__external_threading> 2200f6beaeSEric Fiselier#elif !defined(_LIBCPP_HAS_NO_THREADS) 23790e10f6SSaleem Abdulrasool 2400f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 25c7e4239fSAsiri Rathnayake# include <pthread.h> 26c7e4239fSAsiri Rathnayake# include <sched.h> 276d7d0becSSaleem Abdulrasool#elif defined(_LIBCPP_HAS_THREAD_API_WIN32) 28f9e7bf3aSEric Fiselier#include <assert.h> 296d7d0becSSaleem Abdulrasool#include <Windows.h> 306d7d0becSSaleem Abdulrasool#include <process.h> 316d7d0becSSaleem Abdulrasool#include <fibersapi.h> 326d7d0becSSaleem Abdulrasool 336d7d0becSSaleem Abdulrasool#include <chrono> 34790e10f6SSaleem Abdulrasool#endif 35c7e4239fSAsiri Rathnayake 3600f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 3700f6beaeSEric Fiselier defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) 388c2bf45dSAsiri Rathnayake#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS 398c2bf45dSAsiri Rathnayake#else 408c2bf45dSAsiri Rathnayake#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY 418c2bf45dSAsiri Rathnayake#endif 428c2bf45dSAsiri Rathnayake 43*83dca5c3SDimitry Andric#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis) 44*83dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) 45*83dca5c3SDimitry Andric#else 46*83dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 47*83dca5c3SDimitry Andric#endif 48*83dca5c3SDimitry Andric 49c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD 50c7e4239fSAsiri Rathnayake 5100f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 52c7e4239fSAsiri Rathnayake// Mutex 53c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t; 548c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 55c7e4239fSAsiri Rathnayake 5658a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t; 5758a0dceeSSaleem Abdulrasool 58790e10f6SSaleem Abdulrasool// Condition Variable 59790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t; 60790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER 61790e10f6SSaleem Abdulrasool 62205d7d3fSAsiri Rathnayake// Execute once 63205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag; 64205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT 65205d7d3fSAsiri Rathnayake 66205d7d3fSAsiri Rathnayake// Thread id 67790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_id; 68790e10f6SSaleem Abdulrasool 69790e10f6SSaleem Abdulrasool// Thread 70af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 71af762e91SAsiri Rathnayake 72790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t; 73790e10f6SSaleem Abdulrasool 74790e10f6SSaleem Abdulrasool// Thrad Local Storage 75790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key; 766d7d0becSSaleem Abdulrasool 776d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC 786d7d0becSSaleem Abdulrasool#else 796d7d0becSSaleem Abdulrasool// Mutex 806d7d0becSSaleem Abdulrasooltypedef SRWLOCK __libcpp_mutex_t; 816d7d0becSSaleem Abdulrasool#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT 826d7d0becSSaleem Abdulrasool 836d7d0becSSaleem Abdulrasooltypedef CRITICAL_SECTION __libcpp_recursive_mutex_t; 846d7d0becSSaleem Abdulrasool 856d7d0becSSaleem Abdulrasool// Condition Variable 866d7d0becSSaleem Abdulrasooltypedef CONDITION_VARIABLE __libcpp_condvar_t; 876d7d0becSSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT 886d7d0becSSaleem Abdulrasool 896d7d0becSSaleem Abdulrasool// Execute Once 906d7d0becSSaleem Abdulrasooltypedef INIT_ONCE __libcpp_exec_once_flag; 916d7d0becSSaleem Abdulrasool#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT 926d7d0becSSaleem Abdulrasool 936d7d0becSSaleem Abdulrasool// Thread ID 946d7d0becSSaleem Abdulrasooltypedef DWORD __libcpp_thread_id; 956d7d0becSSaleem Abdulrasool 966d7d0becSSaleem Abdulrasool// Thread 97af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U 98af762e91SAsiri Rathnayake 996d7d0becSSaleem Abdulrasooltypedef HANDLE __libcpp_thread_t; 1006d7d0becSSaleem Abdulrasool 1016d7d0becSSaleem Abdulrasool// Thread Local Storage 1026d7d0becSSaleem Abdulrasooltypedef DWORD __libcpp_tls_key; 1036d7d0becSSaleem Abdulrasool 1046d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC WINAPI 105790e10f6SSaleem Abdulrasool#endif 106790e10f6SSaleem Abdulrasool 107790e10f6SSaleem Abdulrasool// Mutex 1088c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 10958a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); 11058a0dceeSSaleem Abdulrasool 111*83dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 11258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m); 11358a0dceeSSaleem Abdulrasool 114*83dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 11508e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m); 11658a0dceeSSaleem Abdulrasool 117*83dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 11858a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m); 11958a0dceeSSaleem Abdulrasool 12058a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY 12158a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m); 122790e10f6SSaleem Abdulrasool 123*83dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1248c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m); 125790e10f6SSaleem Abdulrasool 126*83dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 12708e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m); 128790e10f6SSaleem Abdulrasool 129*83dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1308c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m); 131790e10f6SSaleem Abdulrasool 1328c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1338c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m); 1348c2bf45dSAsiri Rathnayake 1358c2bf45dSAsiri Rathnayake// Condition variable 1368c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1378c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv); 138790e10f6SSaleem Abdulrasool 1398c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1408c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv); 141790e10f6SSaleem Abdulrasool 142*83dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 1438c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m); 144790e10f6SSaleem Abdulrasool 145*83dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS 146790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 147790e10f6SSaleem Abdulrasool timespec *__ts); 148790e10f6SSaleem Abdulrasool 1498c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1508c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); 1518c2bf45dSAsiri Rathnayake 152205d7d3fSAsiri Rathnayake// Execute once 153205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 154205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 155205d7d3fSAsiri Rathnayake void (*init_routine)(void)); 156205d7d3fSAsiri Rathnayake 157205d7d3fSAsiri Rathnayake// Thread id 1588c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1598c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); 160790e10f6SSaleem Abdulrasool 1618c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1628c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); 1638c2bf45dSAsiri Rathnayake 1648c2bf45dSAsiri Rathnayake// Thread 1658c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 166af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t); 167af762e91SAsiri Rathnayake 168af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 169790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 170790e10f6SSaleem Abdulrasool void *__arg); 171790e10f6SSaleem Abdulrasool 1728c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1738c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id(); 174790e10f6SSaleem Abdulrasool 1758c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1768c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); 177790e10f6SSaleem Abdulrasool 1788c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1798c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t); 180790e10f6SSaleem Abdulrasool 1818c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1828c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t); 183790e10f6SSaleem Abdulrasool 1848c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1858c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield(); 1868c2bf45dSAsiri Rathnayake 1878c2bf45dSAsiri Rathnayake// Thread local storage 1888c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1896d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key, 1906d7d0becSSaleem Abdulrasool void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)); 191790e10f6SSaleem Abdulrasool 1928c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 1938c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key); 194790e10f6SSaleem Abdulrasool 1958c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY 196205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p); 1978c2bf45dSAsiri Rathnayake 19800f6beaeSEric Fiselier#if !defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ 19900f6beaeSEric Fiselier defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) 20000f6beaeSEric Fiselier 20100f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) 2028c2bf45dSAsiri Rathnayake 20358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 204c7e4239fSAsiri Rathnayake{ 205c7e4239fSAsiri Rathnayake pthread_mutexattr_t attr; 206c7e4239fSAsiri Rathnayake int __ec = pthread_mutexattr_init(&attr); 207c7e4239fSAsiri Rathnayake if (__ec) 208790e10f6SSaleem Abdulrasool return __ec; 209790e10f6SSaleem Abdulrasool __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 210790e10f6SSaleem Abdulrasool if (__ec) { 211c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 212c7e4239fSAsiri Rathnayake return __ec; 213c7e4239fSAsiri Rathnayake } 214c7e4239fSAsiri Rathnayake __ec = pthread_mutex_init(__m, &attr); 215790e10f6SSaleem Abdulrasool if (__ec) { 216c7e4239fSAsiri Rathnayake pthread_mutexattr_destroy(&attr); 217c7e4239fSAsiri Rathnayake return __ec; 218c7e4239fSAsiri Rathnayake } 219c7e4239fSAsiri Rathnayake __ec = pthread_mutexattr_destroy(&attr); 220790e10f6SSaleem Abdulrasool if (__ec) { 221c7e4239fSAsiri Rathnayake pthread_mutex_destroy(__m); 222c7e4239fSAsiri Rathnayake return __ec; 223c7e4239fSAsiri Rathnayake } 224c7e4239fSAsiri Rathnayake return 0; 225c7e4239fSAsiri Rathnayake} 226c7e4239fSAsiri Rathnayake 22758a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 22858a0dceeSSaleem Abdulrasool{ 22958a0dceeSSaleem Abdulrasool return pthread_mutex_lock(__m); 23058a0dceeSSaleem Abdulrasool} 23158a0dceeSSaleem Abdulrasool 23208e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 23358a0dceeSSaleem Abdulrasool{ 23408e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 23558a0dceeSSaleem Abdulrasool} 23658a0dceeSSaleem Abdulrasool 23758a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m) 23858a0dceeSSaleem Abdulrasool{ 23958a0dceeSSaleem Abdulrasool return pthread_mutex_unlock(__m); 24058a0dceeSSaleem Abdulrasool} 24158a0dceeSSaleem Abdulrasool 24258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 24358a0dceeSSaleem Abdulrasool{ 24458a0dceeSSaleem Abdulrasool return pthread_mutex_destroy(__m); 24558a0dceeSSaleem Abdulrasool} 24658a0dceeSSaleem Abdulrasool 247c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 248c7e4239fSAsiri Rathnayake{ 249c7e4239fSAsiri Rathnayake return pthread_mutex_lock(__m); 250c7e4239fSAsiri Rathnayake} 251c7e4239fSAsiri Rathnayake 25208e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 253c7e4239fSAsiri Rathnayake{ 25408e1477cSEric Fiselier return pthread_mutex_trylock(__m) == 0; 255c7e4239fSAsiri Rathnayake} 256c7e4239fSAsiri Rathnayake 257c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 258c7e4239fSAsiri Rathnayake{ 259c7e4239fSAsiri Rathnayake return pthread_mutex_unlock(__m); 260c7e4239fSAsiri Rathnayake} 261c7e4239fSAsiri Rathnayake 262c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 263c7e4239fSAsiri Rathnayake{ 264c7e4239fSAsiri Rathnayake return pthread_mutex_destroy(__m); 265c7e4239fSAsiri Rathnayake} 266c7e4239fSAsiri Rathnayake 267790e10f6SSaleem Abdulrasool// Condition Variable 268c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 269c7e4239fSAsiri Rathnayake{ 270c7e4239fSAsiri Rathnayake return pthread_cond_signal(__cv); 271c7e4239fSAsiri Rathnayake} 272c7e4239fSAsiri Rathnayake 273c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 274c7e4239fSAsiri Rathnayake{ 275c7e4239fSAsiri Rathnayake return pthread_cond_broadcast(__cv); 276c7e4239fSAsiri Rathnayake} 277c7e4239fSAsiri Rathnayake 278c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 279c7e4239fSAsiri Rathnayake{ 280c7e4239fSAsiri Rathnayake return pthread_cond_wait(__cv, __m); 281c7e4239fSAsiri Rathnayake} 282c7e4239fSAsiri Rathnayake 283790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 284790e10f6SSaleem Abdulrasool timespec *__ts) 285c7e4239fSAsiri Rathnayake{ 286c7e4239fSAsiri Rathnayake return pthread_cond_timedwait(__cv, __m, __ts); 287c7e4239fSAsiri Rathnayake} 288c7e4239fSAsiri Rathnayake 289c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 290c7e4239fSAsiri Rathnayake{ 291c7e4239fSAsiri Rathnayake return pthread_cond_destroy(__cv); 292c7e4239fSAsiri Rathnayake} 293c7e4239fSAsiri Rathnayake 294205d7d3fSAsiri Rathnayake// Execute once 295205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag, 296205d7d3fSAsiri Rathnayake void (*init_routine)(void)) { 297205d7d3fSAsiri Rathnayake return pthread_once(flag, init_routine); 298205d7d3fSAsiri Rathnayake} 299205d7d3fSAsiri Rathnayake 300205d7d3fSAsiri Rathnayake// Thread id 301c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0 302c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) 303c7e4239fSAsiri Rathnayake{ 304c7e4239fSAsiri Rathnayake return pthread_equal(t1, t2) != 0; 305c7e4239fSAsiri Rathnayake} 306c7e4239fSAsiri Rathnayake 307c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0 308c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) 309c7e4239fSAsiri Rathnayake{ 310c7e4239fSAsiri Rathnayake return t1 < t2; 311c7e4239fSAsiri Rathnayake} 312c7e4239fSAsiri Rathnayake 313c7e4239fSAsiri Rathnayake// Thread 314af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 315af762e91SAsiri Rathnayake return *__t == 0; 316af762e91SAsiri Rathnayake} 317af762e91SAsiri Rathnayake 318790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 319790e10f6SSaleem Abdulrasool void *__arg) 320c7e4239fSAsiri Rathnayake{ 321c7e4239fSAsiri Rathnayake return pthread_create(__t, 0, __func, __arg); 322c7e4239fSAsiri Rathnayake} 323c7e4239fSAsiri Rathnayake 324c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id() 325c7e4239fSAsiri Rathnayake{ 326c7e4239fSAsiri Rathnayake return pthread_self(); 327c7e4239fSAsiri Rathnayake} 328c7e4239fSAsiri Rathnayake 329c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 330c7e4239fSAsiri Rathnayake{ 331c7e4239fSAsiri Rathnayake return *__t; 332c7e4239fSAsiri Rathnayake} 333c7e4239fSAsiri Rathnayake 334c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t) 335c7e4239fSAsiri Rathnayake{ 336c7e4239fSAsiri Rathnayake return pthread_join(*__t, 0); 337c7e4239fSAsiri Rathnayake} 338c7e4239fSAsiri Rathnayake 339c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t) 340c7e4239fSAsiri Rathnayake{ 341c7e4239fSAsiri Rathnayake return pthread_detach(*__t); 342c7e4239fSAsiri Rathnayake} 343c7e4239fSAsiri Rathnayake 344c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield() 345c7e4239fSAsiri Rathnayake{ 346c7e4239fSAsiri Rathnayake sched_yield(); 347c7e4239fSAsiri Rathnayake} 348c7e4239fSAsiri Rathnayake 349c7e4239fSAsiri Rathnayake// Thread local storage 3508c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) 351c7e4239fSAsiri Rathnayake{ 352c7e4239fSAsiri Rathnayake return pthread_key_create(__key, __at_exit); 353c7e4239fSAsiri Rathnayake} 354c7e4239fSAsiri Rathnayake 3558c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key) 356c7e4239fSAsiri Rathnayake{ 357c7e4239fSAsiri Rathnayake return pthread_getspecific(__key); 358c7e4239fSAsiri Rathnayake} 359c7e4239fSAsiri Rathnayake 360205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 361c7e4239fSAsiri Rathnayake{ 362205d7d3fSAsiri Rathnayake return pthread_setspecific(__key, __p); 363c7e4239fSAsiri Rathnayake} 364c7e4239fSAsiri Rathnayake 3656d7d0becSSaleem Abdulrasool#elif defined(_LIBCPP_HAS_THREAD_API_WIN32) 3666d7d0becSSaleem Abdulrasool 3676d7d0becSSaleem Abdulrasool// Mutex 3686d7d0becSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) 3696d7d0becSSaleem Abdulrasool{ 3706d7d0becSSaleem Abdulrasool InitializeCriticalSection(__m); 3716d7d0becSSaleem Abdulrasool return 0; 3726d7d0becSSaleem Abdulrasool} 3736d7d0becSSaleem Abdulrasool 3746d7d0becSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) 3756d7d0becSSaleem Abdulrasool{ 3766d7d0becSSaleem Abdulrasool EnterCriticalSection(__m); 3776d7d0becSSaleem Abdulrasool return 0; 3786d7d0becSSaleem Abdulrasool} 3796d7d0becSSaleem Abdulrasool 38008e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) 3816d7d0becSSaleem Abdulrasool{ 38208e1477cSEric Fiselier return TryEnterCriticalSection(__m) != 0; 3836d7d0becSSaleem Abdulrasool} 3846d7d0becSSaleem Abdulrasool 3856d7d0becSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m) 3866d7d0becSSaleem Abdulrasool{ 3876d7d0becSSaleem Abdulrasool LeaveCriticalSection(__m); 3886d7d0becSSaleem Abdulrasool return 0; 3896d7d0becSSaleem Abdulrasool} 3906d7d0becSSaleem Abdulrasool 3916d7d0becSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) 3926d7d0becSSaleem Abdulrasool{ 3934ec493b2SSaleem Abdulrasool DeleteCriticalSection(__m); 3946d7d0becSSaleem Abdulrasool return 0; 3956d7d0becSSaleem Abdulrasool} 3966d7d0becSSaleem Abdulrasool 3976d7d0becSSaleem Abdulrasoolint __libcpp_mutex_lock(__libcpp_mutex_t *__m) 3986d7d0becSSaleem Abdulrasool{ 3996d7d0becSSaleem Abdulrasool AcquireSRWLockExclusive(__m); 4006d7d0becSSaleem Abdulrasool return 0; 4016d7d0becSSaleem Abdulrasool} 4026d7d0becSSaleem Abdulrasool 40308e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) 4046d7d0becSSaleem Abdulrasool{ 40508e1477cSEric Fiselier return TryAcquireSRWLockExclusive(__m) != 0; 4066d7d0becSSaleem Abdulrasool} 4076d7d0becSSaleem Abdulrasool 4086d7d0becSSaleem Abdulrasoolint __libcpp_mutex_unlock(__libcpp_mutex_t *__m) 4096d7d0becSSaleem Abdulrasool{ 4106d7d0becSSaleem Abdulrasool ReleaseSRWLockExclusive(__m); 4116d7d0becSSaleem Abdulrasool return 0; 4126d7d0becSSaleem Abdulrasool} 4136d7d0becSSaleem Abdulrasool 4146d7d0becSSaleem Abdulrasoolint __libcpp_mutex_destroy(__libcpp_mutex_t *__m) 4156d7d0becSSaleem Abdulrasool{ 4166d7d0becSSaleem Abdulrasool static_cast<void>(__m); 4176d7d0becSSaleem Abdulrasool return 0; 4186d7d0becSSaleem Abdulrasool} 4196d7d0becSSaleem Abdulrasool 4206d7d0becSSaleem Abdulrasool// Condition Variable 4216d7d0becSSaleem Abdulrasoolint __libcpp_condvar_signal(__libcpp_condvar_t *__cv) 4226d7d0becSSaleem Abdulrasool{ 4236d7d0becSSaleem Abdulrasool WakeConditionVariable(__cv); 4246d7d0becSSaleem Abdulrasool return 0; 4256d7d0becSSaleem Abdulrasool} 4266d7d0becSSaleem Abdulrasool 4276d7d0becSSaleem Abdulrasoolint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) 4286d7d0becSSaleem Abdulrasool{ 4296d7d0becSSaleem Abdulrasool WakeAllConditionVariable(__cv); 4306d7d0becSSaleem Abdulrasool return 0; 4316d7d0becSSaleem Abdulrasool} 4326d7d0becSSaleem Abdulrasool 4336d7d0becSSaleem Abdulrasoolint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) 4346d7d0becSSaleem Abdulrasool{ 4356d7d0becSSaleem Abdulrasool SleepConditionVariableSRW(__cv, __m, INFINITE, 0); 4366d7d0becSSaleem Abdulrasool return 0; 4376d7d0becSSaleem Abdulrasool} 4386d7d0becSSaleem Abdulrasool 4396d7d0becSSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, 4406d7d0becSSaleem Abdulrasool timespec *__ts) 4416d7d0becSSaleem Abdulrasool{ 4426d7d0becSSaleem Abdulrasool using namespace _VSTD::chrono; 4436d7d0becSSaleem Abdulrasool 4446d7d0becSSaleem Abdulrasool auto duration = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec); 4456d7d0becSSaleem Abdulrasool auto abstime = 4466d7d0becSSaleem Abdulrasool system_clock::time_point(duration_cast<system_clock::duration>(duration)); 4476d7d0becSSaleem Abdulrasool auto timeout_ms = duration_cast<milliseconds>(abstime - system_clock::now()); 4486d7d0becSSaleem Abdulrasool 4496d7d0becSSaleem Abdulrasool if (!SleepConditionVariableSRW(__cv, __m, 4506d7d0becSSaleem Abdulrasool timeout_ms.count() > 0 ? timeout_ms.count() 4516d7d0becSSaleem Abdulrasool : 0, 4526d7d0becSSaleem Abdulrasool 0)) 4536d7d0becSSaleem Abdulrasool return GetLastError(); 4546d7d0becSSaleem Abdulrasool return 0; 4556d7d0becSSaleem Abdulrasool} 4566d7d0becSSaleem Abdulrasool 4576d7d0becSSaleem Abdulrasoolint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) 4586d7d0becSSaleem Abdulrasool{ 4596d7d0becSSaleem Abdulrasool static_cast<void>(__cv); 4606d7d0becSSaleem Abdulrasool return 0; 4616d7d0becSSaleem Abdulrasool} 4626d7d0becSSaleem Abdulrasool 4636d7d0becSSaleem Abdulrasool// Execute Once 4646d7d0becSSaleem Abdulrasoolstatic inline _LIBCPP_ALWAYS_INLINE BOOL CALLBACK 4656d7d0becSSaleem Abdulrasool__libcpp_init_once_execute_once_thunk(PINIT_ONCE __init_once, PVOID __parameter, 4666d7d0becSSaleem Abdulrasool PVOID *__context) 4676d7d0becSSaleem Abdulrasool{ 4686d7d0becSSaleem Abdulrasool static_cast<void>(__init_once); 4696d7d0becSSaleem Abdulrasool static_cast<void>(__context); 4706d7d0becSSaleem Abdulrasool 4716d7d0becSSaleem Abdulrasool void (*init_routine)(void) = reinterpret_cast<void (*)(void)>(__parameter); 4726d7d0becSSaleem Abdulrasool init_routine(); 4736d7d0becSSaleem Abdulrasool return TRUE; 4746d7d0becSSaleem Abdulrasool} 4756d7d0becSSaleem Abdulrasool 4766d7d0becSSaleem Abdulrasoolint __libcpp_execute_once(__libcpp_exec_once_flag *__flag, 4776d7d0becSSaleem Abdulrasool void (*__init_routine)(void)) 4786d7d0becSSaleem Abdulrasool{ 4796d7d0becSSaleem Abdulrasool if (!InitOnceExecuteOnce(__flag, __libcpp_init_once_execute_once_thunk, 4806d7d0becSSaleem Abdulrasool reinterpret_cast<void *>(__init_routine), NULL)) 4816d7d0becSSaleem Abdulrasool return GetLastError(); 4826d7d0becSSaleem Abdulrasool return 0; 4836d7d0becSSaleem Abdulrasool} 4846d7d0becSSaleem Abdulrasool 4856d7d0becSSaleem Abdulrasool// Thread ID 4866d7d0becSSaleem Abdulrasoolbool __libcpp_thread_id_equal(__libcpp_thread_id __lhs, 4876d7d0becSSaleem Abdulrasool __libcpp_thread_id __rhs) 4886d7d0becSSaleem Abdulrasool{ 4896d7d0becSSaleem Abdulrasool return __lhs == __rhs; 4906d7d0becSSaleem Abdulrasool} 4916d7d0becSSaleem Abdulrasool 4926d7d0becSSaleem Abdulrasoolbool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs) 4936d7d0becSSaleem Abdulrasool{ 4946d7d0becSSaleem Abdulrasool return __lhs < __rhs; 4956d7d0becSSaleem Abdulrasool} 4966d7d0becSSaleem Abdulrasool 4976d7d0becSSaleem Abdulrasool// Thread 4986d7d0becSSaleem Abdulrasoolstruct __libcpp_beginthreadex_thunk_data 4996d7d0becSSaleem Abdulrasool{ 5006d7d0becSSaleem Abdulrasool void *(*__func)(void *); 5016d7d0becSSaleem Abdulrasool void *__arg; 5026d7d0becSSaleem Abdulrasool}; 5036d7d0becSSaleem Abdulrasool 504d75a9d25SEric Fiselierstatic inline _LIBCPP_ALWAYS_INLINE unsigned WINAPI 5056f38b6abSEric Fiselier__libcpp_beginthreadex_thunk(void *__raw_data) 5066d7d0becSSaleem Abdulrasool{ 5076f38b6abSEric Fiselier auto *__data = 5086f38b6abSEric Fiselier static_cast<__libcpp_beginthreadex_thunk_data *>(__raw_data); 5096f38b6abSEric Fiselier auto *__func = __data->__func; 5106f38b6abSEric Fiselier void *__arg = __data->__arg; 5116f38b6abSEric Fiselier delete __data; 512d75a9d25SEric Fiselier return static_cast<unsigned>(reinterpret_cast<uintptr_t>(__func(__arg))); 5136d7d0becSSaleem Abdulrasool} 5146d7d0becSSaleem Abdulrasool 515af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { 516af762e91SAsiri Rathnayake return *__t == 0; 517af762e91SAsiri Rathnayake} 518af762e91SAsiri Rathnayake 5196d7d0becSSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), 5206d7d0becSSaleem Abdulrasool void *__arg) 5216d7d0becSSaleem Abdulrasool{ 5226f38b6abSEric Fiselier auto *__data = new __libcpp_beginthreadex_thunk_data; 5236f38b6abSEric Fiselier __data->__func = __func; 5246f38b6abSEric Fiselier __data->__arg = __arg; 5256d7d0becSSaleem Abdulrasool 526d75a9d25SEric Fiselier *__t = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, 527d75a9d25SEric Fiselier __libcpp_beginthreadex_thunk, 528d75a9d25SEric Fiselier __data, 0, nullptr)); 529d75a9d25SEric Fiselier 5306d7d0becSSaleem Abdulrasool if (*__t) 5316d7d0becSSaleem Abdulrasool return 0; 5326d7d0becSSaleem Abdulrasool return GetLastError(); 5336d7d0becSSaleem Abdulrasool} 5346d7d0becSSaleem Abdulrasool 5356d7d0becSSaleem Abdulrasool__libcpp_thread_id __libcpp_thread_get_current_id() 5366d7d0becSSaleem Abdulrasool{ 5376d7d0becSSaleem Abdulrasool return GetCurrentThreadId(); 5386d7d0becSSaleem Abdulrasool} 5396d7d0becSSaleem Abdulrasool 5406d7d0becSSaleem Abdulrasool__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) 5416d7d0becSSaleem Abdulrasool{ 5426d7d0becSSaleem Abdulrasool return GetThreadId(*__t); 5436d7d0becSSaleem Abdulrasool} 5446d7d0becSSaleem Abdulrasool 5456d7d0becSSaleem Abdulrasoolint __libcpp_thread_join(__libcpp_thread_t *__t) 5466d7d0becSSaleem Abdulrasool{ 5476d7d0becSSaleem Abdulrasool if (WaitForSingleObjectEx(*__t, INFINITE, FALSE) == WAIT_FAILED) 5486d7d0becSSaleem Abdulrasool return GetLastError(); 5496d7d0becSSaleem Abdulrasool if (!CloseHandle(*__t)) 5506d7d0becSSaleem Abdulrasool return GetLastError(); 5516d7d0becSSaleem Abdulrasool return 0; 5526d7d0becSSaleem Abdulrasool} 5536d7d0becSSaleem Abdulrasool 5546d7d0becSSaleem Abdulrasoolint __libcpp_thread_detach(__libcpp_thread_t *__t) 5556d7d0becSSaleem Abdulrasool{ 5566d7d0becSSaleem Abdulrasool if (!CloseHandle(*__t)) 5576d7d0becSSaleem Abdulrasool return GetLastError(); 5586d7d0becSSaleem Abdulrasool return 0; 5596d7d0becSSaleem Abdulrasool} 5606d7d0becSSaleem Abdulrasool 5616d7d0becSSaleem Abdulrasoolvoid __libcpp_thread_yield() 5626d7d0becSSaleem Abdulrasool{ 5636d7d0becSSaleem Abdulrasool SwitchToThread(); 5646d7d0becSSaleem Abdulrasool} 5656d7d0becSSaleem Abdulrasool 5666d7d0becSSaleem Abdulrasool// Thread Local Storage 5676d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key, 5686d7d0becSSaleem Abdulrasool void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*)) 5696d7d0becSSaleem Abdulrasool{ 5706d7d0becSSaleem Abdulrasool *__key = FlsAlloc(__at_exit); 5716d7d0becSSaleem Abdulrasool if (*__key == FLS_OUT_OF_INDEXES) 5726d7d0becSSaleem Abdulrasool return GetLastError(); 5736d7d0becSSaleem Abdulrasool return 0; 5746d7d0becSSaleem Abdulrasool} 5756d7d0becSSaleem Abdulrasool 5766d7d0becSSaleem Abdulrasoolvoid *__libcpp_tls_get(__libcpp_tls_key __key) 5776d7d0becSSaleem Abdulrasool{ 5786d7d0becSSaleem Abdulrasool return FlsGetValue(__key); 5796d7d0becSSaleem Abdulrasool} 5806d7d0becSSaleem Abdulrasool 5816d7d0becSSaleem Abdulrasoolint __libcpp_tls_set(__libcpp_tls_key __key, void *__p) 5826d7d0becSSaleem Abdulrasool{ 5836d7d0becSSaleem Abdulrasool if (!FlsSetValue(__key, __p)) 5846d7d0becSSaleem Abdulrasool return GetLastError(); 5856d7d0becSSaleem Abdulrasool return 0; 5866d7d0becSSaleem Abdulrasool} 5876d7d0becSSaleem Abdulrasool 588790e10f6SSaleem Abdulrasool#endif // _LIBCPP_HAS_THREAD_API_PTHREAD 589c7e4239fSAsiri Rathnayake 59000f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL 59100f6beaeSEric Fiselier 592c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD 593c7e4239fSAsiri Rathnayake 59400f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_NO_THREADS 595c7e4239fSAsiri Rathnayake 596c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT 597