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)
28*f9e7bf3aSEric 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
43c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD
44c7e4239fSAsiri Rathnayake
4500f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
46c7e4239fSAsiri Rathnayake// Mutex
47c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t;
488c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
49c7e4239fSAsiri Rathnayake
5058a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t;
5158a0dceeSSaleem Abdulrasool
52790e10f6SSaleem Abdulrasool// Condition Variable
53790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t;
54790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
55790e10f6SSaleem Abdulrasool
56205d7d3fSAsiri Rathnayake// Execute once
57205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag;
58205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
59205d7d3fSAsiri Rathnayake
60205d7d3fSAsiri Rathnayake// Thread id
61790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_id;
62790e10f6SSaleem Abdulrasool
63790e10f6SSaleem Abdulrasool// Thread
64af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U
65af762e91SAsiri Rathnayake
66790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t;
67790e10f6SSaleem Abdulrasool
68790e10f6SSaleem Abdulrasool// Thrad Local Storage
69790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key;
706d7d0becSSaleem Abdulrasool
716d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC
726d7d0becSSaleem Abdulrasool#else
736d7d0becSSaleem Abdulrasool// Mutex
746d7d0becSSaleem Abdulrasooltypedef SRWLOCK __libcpp_mutex_t;
756d7d0becSSaleem Abdulrasool#define _LIBCPP_MUTEX_INITIALIZER SRWLOCK_INIT
766d7d0becSSaleem Abdulrasool
776d7d0becSSaleem Abdulrasooltypedef CRITICAL_SECTION __libcpp_recursive_mutex_t;
786d7d0becSSaleem Abdulrasool
796d7d0becSSaleem Abdulrasool// Condition Variable
806d7d0becSSaleem Abdulrasooltypedef CONDITION_VARIABLE __libcpp_condvar_t;
816d7d0becSSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER CONDITION_VARIABLE_INIT
826d7d0becSSaleem Abdulrasool
836d7d0becSSaleem Abdulrasool// Execute Once
846d7d0becSSaleem Abdulrasooltypedef INIT_ONCE __libcpp_exec_once_flag;
856d7d0becSSaleem Abdulrasool#define _LIBCPP_EXEC_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
866d7d0becSSaleem Abdulrasool
876d7d0becSSaleem Abdulrasool// Thread ID
886d7d0becSSaleem Abdulrasooltypedef DWORD __libcpp_thread_id;
896d7d0becSSaleem Abdulrasool
906d7d0becSSaleem Abdulrasool// Thread
91af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U
92af762e91SAsiri Rathnayake
936d7d0becSSaleem Abdulrasooltypedef HANDLE __libcpp_thread_t;
946d7d0becSSaleem Abdulrasool
956d7d0becSSaleem Abdulrasool// Thread Local Storage
966d7d0becSSaleem Abdulrasooltypedef DWORD __libcpp_tls_key;
976d7d0becSSaleem Abdulrasool
986d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC WINAPI
99790e10f6SSaleem Abdulrasool#endif
100790e10f6SSaleem Abdulrasool
101790e10f6SSaleem Abdulrasool// Mutex
1028c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
10358a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
10458a0dceeSSaleem Abdulrasool
10558a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY
10658a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
10758a0dceeSSaleem Abdulrasool
10858a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY
10908e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
11058a0dceeSSaleem Abdulrasool
11158a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY
11258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
11358a0dceeSSaleem Abdulrasool
11458a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY
11558a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
116790e10f6SSaleem Abdulrasool
1178c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1188c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m);
119790e10f6SSaleem Abdulrasool
1208c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
12108e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
122790e10f6SSaleem Abdulrasool
1238c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1248c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
125790e10f6SSaleem Abdulrasool
1268c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1278c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
1288c2bf45dSAsiri Rathnayake
1298c2bf45dSAsiri Rathnayake// Condition variable
1308c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1318c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
132790e10f6SSaleem Abdulrasool
1338c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1348c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
135790e10f6SSaleem Abdulrasool
1368c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1378c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
138790e10f6SSaleem Abdulrasool
1398c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
140790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
141790e10f6SSaleem Abdulrasool                               timespec *__ts);
142790e10f6SSaleem Abdulrasool
1438c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1448c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
1458c2bf45dSAsiri Rathnayake
146205d7d3fSAsiri Rathnayake// Execute once
147205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
148205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
149205d7d3fSAsiri Rathnayake                          void (*init_routine)(void));
150205d7d3fSAsiri Rathnayake
151205d7d3fSAsiri Rathnayake// Thread id
152205d7d3fSAsiri Rathnayake#if defined(__APPLE__) && !defined(__arm__)
153205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
154205d7d3fSAsiri Rathnayakemach_port_t __libcpp_thread_get_port();
155205d7d3fSAsiri Rathnayake#endif
156205d7d3fSAsiri Rathnayake
1578c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1588c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
159790e10f6SSaleem Abdulrasool
1608c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1618c2bf45dSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
1628c2bf45dSAsiri Rathnayake
1638c2bf45dSAsiri Rathnayake// Thread
1648c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
165af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
166af762e91SAsiri Rathnayake
167af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
168790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
169790e10f6SSaleem Abdulrasool                           void *__arg);
170790e10f6SSaleem Abdulrasool
1718c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1728c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id();
173790e10f6SSaleem Abdulrasool
1748c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1758c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
176790e10f6SSaleem Abdulrasool
1778c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1788c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t);
179790e10f6SSaleem Abdulrasool
1808c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1818c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t);
182790e10f6SSaleem Abdulrasool
1838c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1848c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield();
1858c2bf45dSAsiri Rathnayake
1868c2bf45dSAsiri Rathnayake// Thread local storage
1878c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1886d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key,
1896d7d0becSSaleem Abdulrasool                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
190790e10f6SSaleem Abdulrasool
1918c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1928c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key);
193790e10f6SSaleem Abdulrasool
1948c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
195205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
1968c2bf45dSAsiri Rathnayake
19700f6beaeSEric Fiselier#if !defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
19800f6beaeSEric Fiselier    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)
19900f6beaeSEric Fiselier
20000f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
2018c2bf45dSAsiri Rathnayake
20258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
203c7e4239fSAsiri Rathnayake{
204c7e4239fSAsiri Rathnayake  pthread_mutexattr_t attr;
205c7e4239fSAsiri Rathnayake  int __ec = pthread_mutexattr_init(&attr);
206c7e4239fSAsiri Rathnayake  if (__ec)
207790e10f6SSaleem Abdulrasool    return __ec;
208790e10f6SSaleem Abdulrasool  __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
209790e10f6SSaleem Abdulrasool  if (__ec) {
210c7e4239fSAsiri Rathnayake    pthread_mutexattr_destroy(&attr);
211c7e4239fSAsiri Rathnayake    return __ec;
212c7e4239fSAsiri Rathnayake  }
213c7e4239fSAsiri Rathnayake  __ec = pthread_mutex_init(__m, &attr);
214790e10f6SSaleem Abdulrasool  if (__ec) {
215c7e4239fSAsiri Rathnayake    pthread_mutexattr_destroy(&attr);
216c7e4239fSAsiri Rathnayake    return __ec;
217c7e4239fSAsiri Rathnayake  }
218c7e4239fSAsiri Rathnayake  __ec = pthread_mutexattr_destroy(&attr);
219790e10f6SSaleem Abdulrasool  if (__ec) {
220c7e4239fSAsiri Rathnayake    pthread_mutex_destroy(__m);
221c7e4239fSAsiri Rathnayake    return __ec;
222c7e4239fSAsiri Rathnayake  }
223c7e4239fSAsiri Rathnayake  return 0;
224c7e4239fSAsiri Rathnayake}
225c7e4239fSAsiri Rathnayake
22658a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
22758a0dceeSSaleem Abdulrasool{
22858a0dceeSSaleem Abdulrasool  return pthread_mutex_lock(__m);
22958a0dceeSSaleem Abdulrasool}
23058a0dceeSSaleem Abdulrasool
23108e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
23258a0dceeSSaleem Abdulrasool{
23308e1477cSEric Fiselier  return pthread_mutex_trylock(__m) == 0;
23458a0dceeSSaleem Abdulrasool}
23558a0dceeSSaleem Abdulrasool
23658a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
23758a0dceeSSaleem Abdulrasool{
23858a0dceeSSaleem Abdulrasool  return pthread_mutex_unlock(__m);
23958a0dceeSSaleem Abdulrasool}
24058a0dceeSSaleem Abdulrasool
24158a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
24258a0dceeSSaleem Abdulrasool{
24358a0dceeSSaleem Abdulrasool  return pthread_mutex_destroy(__m);
24458a0dceeSSaleem Abdulrasool}
24558a0dceeSSaleem Abdulrasool
246c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m)
247c7e4239fSAsiri Rathnayake{
248c7e4239fSAsiri Rathnayake  return pthread_mutex_lock(__m);
249c7e4239fSAsiri Rathnayake}
250c7e4239fSAsiri Rathnayake
25108e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
252c7e4239fSAsiri Rathnayake{
25308e1477cSEric Fiselier  return pthread_mutex_trylock(__m) == 0;
254c7e4239fSAsiri Rathnayake}
255c7e4239fSAsiri Rathnayake
256c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
257c7e4239fSAsiri Rathnayake{
258c7e4239fSAsiri Rathnayake  return pthread_mutex_unlock(__m);
259c7e4239fSAsiri Rathnayake}
260c7e4239fSAsiri Rathnayake
261c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
262c7e4239fSAsiri Rathnayake{
263c7e4239fSAsiri Rathnayake  return pthread_mutex_destroy(__m);
264c7e4239fSAsiri Rathnayake}
265c7e4239fSAsiri Rathnayake
266790e10f6SSaleem Abdulrasool// Condition Variable
267c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
268c7e4239fSAsiri Rathnayake{
269c7e4239fSAsiri Rathnayake  return pthread_cond_signal(__cv);
270c7e4239fSAsiri Rathnayake}
271c7e4239fSAsiri Rathnayake
272c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
273c7e4239fSAsiri Rathnayake{
274c7e4239fSAsiri Rathnayake  return pthread_cond_broadcast(__cv);
275c7e4239fSAsiri Rathnayake}
276c7e4239fSAsiri Rathnayake
277c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
278c7e4239fSAsiri Rathnayake{
279c7e4239fSAsiri Rathnayake  return pthread_cond_wait(__cv, __m);
280c7e4239fSAsiri Rathnayake}
281c7e4239fSAsiri Rathnayake
282790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
283790e10f6SSaleem Abdulrasool                               timespec *__ts)
284c7e4239fSAsiri Rathnayake{
285c7e4239fSAsiri Rathnayake  return pthread_cond_timedwait(__cv, __m, __ts);
286c7e4239fSAsiri Rathnayake}
287c7e4239fSAsiri Rathnayake
288c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
289c7e4239fSAsiri Rathnayake{
290c7e4239fSAsiri Rathnayake  return pthread_cond_destroy(__cv);
291c7e4239fSAsiri Rathnayake}
292c7e4239fSAsiri Rathnayake
293205d7d3fSAsiri Rathnayake// Execute once
294205d7d3fSAsiri Rathnayakeint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
295205d7d3fSAsiri Rathnayake                          void (*init_routine)(void)) {
296205d7d3fSAsiri Rathnayake  return pthread_once(flag, init_routine);
297205d7d3fSAsiri Rathnayake}
298205d7d3fSAsiri Rathnayake
299205d7d3fSAsiri Rathnayake// Thread id
300205d7d3fSAsiri Rathnayake#if defined(__APPLE__) && !defined(__arm__)
301205d7d3fSAsiri Rathnayakemach_port_t __libcpp_thread_get_port() {
302205d7d3fSAsiri Rathnayake    return pthread_mach_thread_np(pthread_self());
303205d7d3fSAsiri Rathnayake}
304205d7d3fSAsiri Rathnayake#endif
305205d7d3fSAsiri Rathnayake
306c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0
307c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
308c7e4239fSAsiri Rathnayake{
309c7e4239fSAsiri Rathnayake  return pthread_equal(t1, t2) != 0;
310c7e4239fSAsiri Rathnayake}
311c7e4239fSAsiri Rathnayake
312c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0
313c7e4239fSAsiri Rathnayakebool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
314c7e4239fSAsiri Rathnayake{
315c7e4239fSAsiri Rathnayake  return t1 < t2;
316c7e4239fSAsiri Rathnayake}
317c7e4239fSAsiri Rathnayake
318c7e4239fSAsiri Rathnayake// Thread
319af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
320af762e91SAsiri Rathnayake  return *__t == 0;
321af762e91SAsiri Rathnayake}
322af762e91SAsiri Rathnayake
323790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
324790e10f6SSaleem Abdulrasool                           void *__arg)
325c7e4239fSAsiri Rathnayake{
326c7e4239fSAsiri Rathnayake  return pthread_create(__t, 0, __func, __arg);
327c7e4239fSAsiri Rathnayake}
328c7e4239fSAsiri Rathnayake
329c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id()
330c7e4239fSAsiri Rathnayake{
331c7e4239fSAsiri Rathnayake  return pthread_self();
332c7e4239fSAsiri Rathnayake}
333c7e4239fSAsiri Rathnayake
334c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
335c7e4239fSAsiri Rathnayake{
336c7e4239fSAsiri Rathnayake  return *__t;
337c7e4239fSAsiri Rathnayake}
338c7e4239fSAsiri Rathnayake
339c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t)
340c7e4239fSAsiri Rathnayake{
341c7e4239fSAsiri Rathnayake  return pthread_join(*__t, 0);
342c7e4239fSAsiri Rathnayake}
343c7e4239fSAsiri Rathnayake
344c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t)
345c7e4239fSAsiri Rathnayake{
346c7e4239fSAsiri Rathnayake  return pthread_detach(*__t);
347c7e4239fSAsiri Rathnayake}
348c7e4239fSAsiri Rathnayake
349c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield()
350c7e4239fSAsiri Rathnayake{
351c7e4239fSAsiri Rathnayake  sched_yield();
352c7e4239fSAsiri Rathnayake}
353c7e4239fSAsiri Rathnayake
354c7e4239fSAsiri Rathnayake// Thread local storage
3558c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
356c7e4239fSAsiri Rathnayake{
357c7e4239fSAsiri Rathnayake  return pthread_key_create(__key, __at_exit);
358c7e4239fSAsiri Rathnayake}
359c7e4239fSAsiri Rathnayake
3608c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key)
361c7e4239fSAsiri Rathnayake{
362c7e4239fSAsiri Rathnayake  return pthread_getspecific(__key);
363c7e4239fSAsiri Rathnayake}
364c7e4239fSAsiri Rathnayake
365205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
366c7e4239fSAsiri Rathnayake{
367205d7d3fSAsiri Rathnayake    return pthread_setspecific(__key, __p);
368c7e4239fSAsiri Rathnayake}
369c7e4239fSAsiri Rathnayake
3706d7d0becSSaleem Abdulrasool#elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
3716d7d0becSSaleem Abdulrasool
3726d7d0becSSaleem Abdulrasool// Mutex
3736d7d0becSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
3746d7d0becSSaleem Abdulrasool{
3756d7d0becSSaleem Abdulrasool  InitializeCriticalSection(__m);
3766d7d0becSSaleem Abdulrasool  return 0;
3776d7d0becSSaleem Abdulrasool}
3786d7d0becSSaleem Abdulrasool
3796d7d0becSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
3806d7d0becSSaleem Abdulrasool{
3816d7d0becSSaleem Abdulrasool  EnterCriticalSection(__m);
3826d7d0becSSaleem Abdulrasool  return 0;
3836d7d0becSSaleem Abdulrasool}
3846d7d0becSSaleem Abdulrasool
38508e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
3866d7d0becSSaleem Abdulrasool{
38708e1477cSEric Fiselier  return TryEnterCriticalSection(__m) != 0;
3886d7d0becSSaleem Abdulrasool}
3896d7d0becSSaleem Abdulrasool
3906d7d0becSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
3916d7d0becSSaleem Abdulrasool{
3926d7d0becSSaleem Abdulrasool  LeaveCriticalSection(__m);
3936d7d0becSSaleem Abdulrasool  return 0;
3946d7d0becSSaleem Abdulrasool}
3956d7d0becSSaleem Abdulrasool
3966d7d0becSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
3976d7d0becSSaleem Abdulrasool{
3984ec493b2SSaleem Abdulrasool  DeleteCriticalSection(__m);
3996d7d0becSSaleem Abdulrasool  return 0;
4006d7d0becSSaleem Abdulrasool}
4016d7d0becSSaleem Abdulrasool
4026d7d0becSSaleem Abdulrasoolint __libcpp_mutex_lock(__libcpp_mutex_t *__m)
4036d7d0becSSaleem Abdulrasool{
4046d7d0becSSaleem Abdulrasool  AcquireSRWLockExclusive(__m);
4056d7d0becSSaleem Abdulrasool  return 0;
4066d7d0becSSaleem Abdulrasool}
4076d7d0becSSaleem Abdulrasool
40808e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
4096d7d0becSSaleem Abdulrasool{
41008e1477cSEric Fiselier  return TryAcquireSRWLockExclusive(__m) != 0;
4116d7d0becSSaleem Abdulrasool}
4126d7d0becSSaleem Abdulrasool
4136d7d0becSSaleem Abdulrasoolint __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
4146d7d0becSSaleem Abdulrasool{
4156d7d0becSSaleem Abdulrasool  ReleaseSRWLockExclusive(__m);
4166d7d0becSSaleem Abdulrasool  return 0;
4176d7d0becSSaleem Abdulrasool}
4186d7d0becSSaleem Abdulrasool
4196d7d0becSSaleem Abdulrasoolint __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
4206d7d0becSSaleem Abdulrasool{
4216d7d0becSSaleem Abdulrasool  static_cast<void>(__m);
4226d7d0becSSaleem Abdulrasool  return 0;
4236d7d0becSSaleem Abdulrasool}
4246d7d0becSSaleem Abdulrasool
4256d7d0becSSaleem Abdulrasool// Condition Variable
4266d7d0becSSaleem Abdulrasoolint __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
4276d7d0becSSaleem Abdulrasool{
4286d7d0becSSaleem Abdulrasool  WakeConditionVariable(__cv);
4296d7d0becSSaleem Abdulrasool  return 0;
4306d7d0becSSaleem Abdulrasool}
4316d7d0becSSaleem Abdulrasool
4326d7d0becSSaleem Abdulrasoolint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
4336d7d0becSSaleem Abdulrasool{
4346d7d0becSSaleem Abdulrasool  WakeAllConditionVariable(__cv);
4356d7d0becSSaleem Abdulrasool  return 0;
4366d7d0becSSaleem Abdulrasool}
4376d7d0becSSaleem Abdulrasool
4386d7d0becSSaleem Abdulrasoolint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
4396d7d0becSSaleem Abdulrasool{
4406d7d0becSSaleem Abdulrasool  SleepConditionVariableSRW(__cv, __m, INFINITE, 0);
4416d7d0becSSaleem Abdulrasool  return 0;
4426d7d0becSSaleem Abdulrasool}
4436d7d0becSSaleem Abdulrasool
4446d7d0becSSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
4456d7d0becSSaleem Abdulrasool                               timespec *__ts)
4466d7d0becSSaleem Abdulrasool{
4476d7d0becSSaleem Abdulrasool  using namespace _VSTD::chrono;
4486d7d0becSSaleem Abdulrasool
4496d7d0becSSaleem Abdulrasool  auto duration = seconds(__ts->tv_sec) + nanoseconds(__ts->tv_nsec);
4506d7d0becSSaleem Abdulrasool  auto abstime =
4516d7d0becSSaleem Abdulrasool      system_clock::time_point(duration_cast<system_clock::duration>(duration));
4526d7d0becSSaleem Abdulrasool  auto timeout_ms = duration_cast<milliseconds>(abstime - system_clock::now());
4536d7d0becSSaleem Abdulrasool
4546d7d0becSSaleem Abdulrasool  if (!SleepConditionVariableSRW(__cv, __m,
4556d7d0becSSaleem Abdulrasool                                 timeout_ms.count() > 0 ? timeout_ms.count()
4566d7d0becSSaleem Abdulrasool                                                        : 0,
4576d7d0becSSaleem Abdulrasool                                 0))
4586d7d0becSSaleem Abdulrasool    return GetLastError();
4596d7d0becSSaleem Abdulrasool  return 0;
4606d7d0becSSaleem Abdulrasool}
4616d7d0becSSaleem Abdulrasool
4626d7d0becSSaleem Abdulrasoolint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
4636d7d0becSSaleem Abdulrasool{
4646d7d0becSSaleem Abdulrasool  static_cast<void>(__cv);
4656d7d0becSSaleem Abdulrasool  return 0;
4666d7d0becSSaleem Abdulrasool}
4676d7d0becSSaleem Abdulrasool
4686d7d0becSSaleem Abdulrasool// Execute Once
4696d7d0becSSaleem Abdulrasoolstatic inline _LIBCPP_ALWAYS_INLINE BOOL CALLBACK
4706d7d0becSSaleem Abdulrasool__libcpp_init_once_execute_once_thunk(PINIT_ONCE __init_once, PVOID __parameter,
4716d7d0becSSaleem Abdulrasool                                      PVOID *__context)
4726d7d0becSSaleem Abdulrasool{
4736d7d0becSSaleem Abdulrasool  static_cast<void>(__init_once);
4746d7d0becSSaleem Abdulrasool  static_cast<void>(__context);
4756d7d0becSSaleem Abdulrasool
4766d7d0becSSaleem Abdulrasool  void (*init_routine)(void) = reinterpret_cast<void (*)(void)>(__parameter);
4776d7d0becSSaleem Abdulrasool  init_routine();
4786d7d0becSSaleem Abdulrasool  return TRUE;
4796d7d0becSSaleem Abdulrasool}
4806d7d0becSSaleem Abdulrasool
4816d7d0becSSaleem Abdulrasoolint __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
4826d7d0becSSaleem Abdulrasool                          void (*__init_routine)(void))
4836d7d0becSSaleem Abdulrasool{
4846d7d0becSSaleem Abdulrasool  if (!InitOnceExecuteOnce(__flag, __libcpp_init_once_execute_once_thunk,
4856d7d0becSSaleem Abdulrasool                           reinterpret_cast<void *>(__init_routine), NULL))
4866d7d0becSSaleem Abdulrasool    return GetLastError();
4876d7d0becSSaleem Abdulrasool  return 0;
4886d7d0becSSaleem Abdulrasool}
4896d7d0becSSaleem Abdulrasool
4906d7d0becSSaleem Abdulrasool// Thread ID
4916d7d0becSSaleem Abdulrasoolbool __libcpp_thread_id_equal(__libcpp_thread_id __lhs,
4926d7d0becSSaleem Abdulrasool                              __libcpp_thread_id __rhs)
4936d7d0becSSaleem Abdulrasool{
4946d7d0becSSaleem Abdulrasool  return __lhs == __rhs;
4956d7d0becSSaleem Abdulrasool}
4966d7d0becSSaleem Abdulrasool
4976d7d0becSSaleem Abdulrasoolbool __libcpp_thread_id_less(__libcpp_thread_id __lhs, __libcpp_thread_id __rhs)
4986d7d0becSSaleem Abdulrasool{
4996d7d0becSSaleem Abdulrasool  return __lhs < __rhs;
5006d7d0becSSaleem Abdulrasool}
5016d7d0becSSaleem Abdulrasool
5026d7d0becSSaleem Abdulrasool// Thread
5036d7d0becSSaleem Abdulrasoolstruct __libcpp_beginthreadex_thunk_data
5046d7d0becSSaleem Abdulrasool{
5056d7d0becSSaleem Abdulrasool  void *(*__func)(void *);
5066d7d0becSSaleem Abdulrasool  void *__arg;
5076d7d0becSSaleem Abdulrasool};
5086d7d0becSSaleem Abdulrasool
509d75a9d25SEric Fiselierstatic inline _LIBCPP_ALWAYS_INLINE unsigned WINAPI
5106f38b6abSEric Fiselier__libcpp_beginthreadex_thunk(void *__raw_data)
5116d7d0becSSaleem Abdulrasool{
5126f38b6abSEric Fiselier  auto *__data =
5136f38b6abSEric Fiselier      static_cast<__libcpp_beginthreadex_thunk_data *>(__raw_data);
5146f38b6abSEric Fiselier  auto *__func = __data->__func;
5156f38b6abSEric Fiselier  void *__arg = __data->__arg;
5166f38b6abSEric Fiselier  delete __data;
517d75a9d25SEric Fiselier  return static_cast<unsigned>(reinterpret_cast<uintptr_t>(__func(__arg)));
5186d7d0becSSaleem Abdulrasool}
5196d7d0becSSaleem Abdulrasool
520af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
521af762e91SAsiri Rathnayake  return *__t == 0;
522af762e91SAsiri Rathnayake}
523af762e91SAsiri Rathnayake
5246d7d0becSSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
5256d7d0becSSaleem Abdulrasool                           void *__arg)
5266d7d0becSSaleem Abdulrasool{
5276f38b6abSEric Fiselier  auto *__data = new __libcpp_beginthreadex_thunk_data;
5286f38b6abSEric Fiselier  __data->__func = __func;
5296f38b6abSEric Fiselier  __data->__arg = __arg;
5306d7d0becSSaleem Abdulrasool
531d75a9d25SEric Fiselier  *__t = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0,
532d75a9d25SEric Fiselier                                                 __libcpp_beginthreadex_thunk,
533d75a9d25SEric Fiselier                                                 __data, 0, nullptr));
534d75a9d25SEric Fiselier
5356d7d0becSSaleem Abdulrasool  if (*__t)
5366d7d0becSSaleem Abdulrasool    return 0;
5376d7d0becSSaleem Abdulrasool  return GetLastError();
5386d7d0becSSaleem Abdulrasool}
5396d7d0becSSaleem Abdulrasool
5406d7d0becSSaleem Abdulrasool__libcpp_thread_id __libcpp_thread_get_current_id()
5416d7d0becSSaleem Abdulrasool{
5426d7d0becSSaleem Abdulrasool  return GetCurrentThreadId();
5436d7d0becSSaleem Abdulrasool}
5446d7d0becSSaleem Abdulrasool
5456d7d0becSSaleem Abdulrasool__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
5466d7d0becSSaleem Abdulrasool{
5476d7d0becSSaleem Abdulrasool  return GetThreadId(*__t);
5486d7d0becSSaleem Abdulrasool}
5496d7d0becSSaleem Abdulrasool
5506d7d0becSSaleem Abdulrasoolint __libcpp_thread_join(__libcpp_thread_t *__t)
5516d7d0becSSaleem Abdulrasool{
5526d7d0becSSaleem Abdulrasool  if (WaitForSingleObjectEx(*__t, INFINITE, FALSE) == WAIT_FAILED)
5536d7d0becSSaleem Abdulrasool    return GetLastError();
5546d7d0becSSaleem Abdulrasool  if (!CloseHandle(*__t))
5556d7d0becSSaleem Abdulrasool    return GetLastError();
5566d7d0becSSaleem Abdulrasool  return 0;
5576d7d0becSSaleem Abdulrasool}
5586d7d0becSSaleem Abdulrasool
5596d7d0becSSaleem Abdulrasoolint __libcpp_thread_detach(__libcpp_thread_t *__t)
5606d7d0becSSaleem Abdulrasool{
5616d7d0becSSaleem Abdulrasool  if (!CloseHandle(*__t))
5626d7d0becSSaleem Abdulrasool    return GetLastError();
5636d7d0becSSaleem Abdulrasool  return 0;
5646d7d0becSSaleem Abdulrasool}
5656d7d0becSSaleem Abdulrasool
5666d7d0becSSaleem Abdulrasoolvoid __libcpp_thread_yield()
5676d7d0becSSaleem Abdulrasool{
5686d7d0becSSaleem Abdulrasool  SwitchToThread();
5696d7d0becSSaleem Abdulrasool}
5706d7d0becSSaleem Abdulrasool
5716d7d0becSSaleem Abdulrasool// Thread Local Storage
5726d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key,
5736d7d0becSSaleem Abdulrasool                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*))
5746d7d0becSSaleem Abdulrasool{
5756d7d0becSSaleem Abdulrasool  *__key = FlsAlloc(__at_exit);
5766d7d0becSSaleem Abdulrasool  if (*__key == FLS_OUT_OF_INDEXES)
5776d7d0becSSaleem Abdulrasool    return GetLastError();
5786d7d0becSSaleem Abdulrasool  return 0;
5796d7d0becSSaleem Abdulrasool}
5806d7d0becSSaleem Abdulrasool
5816d7d0becSSaleem Abdulrasoolvoid *__libcpp_tls_get(__libcpp_tls_key __key)
5826d7d0becSSaleem Abdulrasool{
5836d7d0becSSaleem Abdulrasool  return FlsGetValue(__key);
5846d7d0becSSaleem Abdulrasool}
5856d7d0becSSaleem Abdulrasool
5866d7d0becSSaleem Abdulrasoolint __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
5876d7d0becSSaleem Abdulrasool{
5886d7d0becSSaleem Abdulrasool  if (!FlsSetValue(__key, __p))
5896d7d0becSSaleem Abdulrasool    return GetLastError();
5906d7d0becSSaleem Abdulrasool  return 0;
5916d7d0becSSaleem Abdulrasool}
5926d7d0becSSaleem Abdulrasool
593790e10f6SSaleem Abdulrasool#endif // _LIBCPP_HAS_THREAD_API_PTHREAD
594c7e4239fSAsiri Rathnayake
59500f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
59600f6beaeSEric Fiselier
597c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD
598c7e4239fSAsiri Rathnayake
59900f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_NO_THREADS
600c7e4239fSAsiri Rathnayake
601c7e4239fSAsiri Rathnayake#endif // _LIBCPP_THREADING_SUPPORT
602