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
10cc82a1b0SLouis Dionne#ifndef _LIBCPP___THREADING_SUPPORT
11cc82a1b0SLouis Dionne#define _LIBCPP___THREADING_SUPPORT
12c7e4239fSAsiri Rathnayake
132eadbc86SLouis Dionne#include <__availability>
14489637e6SNikolas Klauser#include <__chrono/convert_to_timespec.h>
15489637e6SNikolas Klauser#include <__chrono/duration.h>
16bfbd73f8SArthur O'Dwyer#include <__config>
1792832e48SLouis Dionne#include <__thread/poll_with_backoff.h>
1854a987e1SAsiri Rathnayake#include <errno.h>
19bfbd73f8SArthur O'Dwyer#include <iosfwd>
201773eec6SMartin Storsjö#include <limits>
21c7e4239fSAsiri Rathnayake
226a8099e0SZbigniew Sarbinowski#ifdef __MVS__
23b5175681SLouis Dionne# include <__support/ibm/nanosleep.h>
246a8099e0SZbigniew Sarbinowski#endif
256a8099e0SZbigniew Sarbinowski
26c7e4239fSAsiri Rathnayake#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
27c7e4239fSAsiri Rathnayake#  pragma GCC system_header
28c7e4239fSAsiri Rathnayake#endif
29c7e4239fSAsiri Rathnayake
3000f6beaeSEric Fiselier#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
313cf2f7bcSAsiri Rathnayake# include <__external_threading>
3200f6beaeSEric Fiselier#elif !defined(_LIBCPP_HAS_NO_THREADS)
33790e10f6SSaleem Abdulrasool
34db757ba7SLouis Dionne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
35db757ba7SLouis Dionne# include <pthread.h>
36db757ba7SLouis Dionne# include <sched.h>
37ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11)
38ab9aefeeSPetr Hosek# include <threads.h>
39790e10f6SSaleem Abdulrasool#endif
40c7e4239fSAsiri Rathnayake
412a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
422a129dc3SPeter Collingbourne    defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
432a129dc3SPeter Collingbourne    defined(_LIBCPP_HAS_THREAD_API_WIN32)
442a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
452a129dc3SPeter Collingbourne#else
462a129dc3SPeter Collingbourne#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
472a129dc3SPeter Collingbourne#endif
482a129dc3SPeter Collingbourne
4983dca5c3SDimitry Andric#if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis)
5083dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
5183dca5c3SDimitry Andric#else
5283dca5c3SDimitry Andric#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
5383dca5c3SDimitry Andric#endif
5483dca5c3SDimitry Andric
55696630eaSMarshall Clowtypedef ::timespec __libcpp_timespec_t;
56696630eaSMarshall Clow#endif // !defined(_LIBCPP_HAS_NO_THREADS)
57696630eaSMarshall Clow
58c7e4239fSAsiri Rathnayake_LIBCPP_BEGIN_NAMESPACE_STD
59c7e4239fSAsiri Rathnayake
60696630eaSMarshall Clow#if !defined(_LIBCPP_HAS_NO_THREADS)
61696630eaSMarshall Clow
622a129dc3SPeter Collingbourne#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
63c7e4239fSAsiri Rathnayake// Mutex
64c7e4239fSAsiri Rathnayaketypedef pthread_mutex_t __libcpp_mutex_t;
658c2bf45dSAsiri Rathnayake#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
66c7e4239fSAsiri Rathnayake
6758a0dceeSSaleem Abdulrasooltypedef pthread_mutex_t __libcpp_recursive_mutex_t;
6858a0dceeSSaleem Abdulrasool
69790e10f6SSaleem Abdulrasool// Condition Variable
70790e10f6SSaleem Abdulrasooltypedef pthread_cond_t __libcpp_condvar_t;
71790e10f6SSaleem Abdulrasool#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
72790e10f6SSaleem Abdulrasool
73205d7d3fSAsiri Rathnayake// Execute once
74205d7d3fSAsiri Rathnayaketypedef pthread_once_t __libcpp_exec_once_flag;
75205d7d3fSAsiri Rathnayake#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
76205d7d3fSAsiri Rathnayake
77205d7d3fSAsiri Rathnayake// Thread id
78e6c89a49SZbigniew Sarbinowski#if defined(__MVS__)
79e6c89a49SZbigniew Sarbinowski  typedef unsigned long long __libcpp_thread_id;
80e6c89a49SZbigniew Sarbinowski#else
81790e10f6SSaleem Abdulrasool  typedef pthread_t __libcpp_thread_id;
82e6c89a49SZbigniew Sarbinowski#endif
83790e10f6SSaleem Abdulrasool
84790e10f6SSaleem Abdulrasool// Thread
85e6c89a49SZbigniew Sarbinowski#define _LIBCPP_NULL_THREAD ((__libcpp_thread_t()))
86790e10f6SSaleem Abdulrasooltypedef pthread_t __libcpp_thread_t;
87790e10f6SSaleem Abdulrasool
88cac6d217SFangrui Song// Thread Local Storage
89790e10f6SSaleem Abdulrasooltypedef pthread_key_t __libcpp_tls_key;
906d7d0becSSaleem Abdulrasool
916d7d0becSSaleem Abdulrasool#define _LIBCPP_TLS_DESTRUCTOR_CC
92ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11)
93ab9aefeeSPetr Hosek// Mutex
94ab9aefeeSPetr Hosektypedef mtx_t __libcpp_mutex_t;
95ab9aefeeSPetr Hosek// mtx_t is a struct so using {} for initialization is valid.
96ab9aefeeSPetr Hosek#define _LIBCPP_MUTEX_INITIALIZER {}
97ab9aefeeSPetr Hosek
98ab9aefeeSPetr Hosektypedef mtx_t __libcpp_recursive_mutex_t;
99ab9aefeeSPetr Hosek
100ab9aefeeSPetr Hosek// Condition Variable
101ab9aefeeSPetr Hosektypedef cnd_t __libcpp_condvar_t;
102ab9aefeeSPetr Hosek// cnd_t is a struct so using {} for initialization is valid.
103ab9aefeeSPetr Hosek#define _LIBCPP_CONDVAR_INITIALIZER {}
104ab9aefeeSPetr Hosek
105ab9aefeeSPetr Hosek// Execute once
106ab9aefeeSPetr Hosektypedef once_flag __libcpp_exec_once_flag;
107ab9aefeeSPetr Hosek#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT
108ab9aefeeSPetr Hosek
109ab9aefeeSPetr Hosek// Thread id
110ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_id;
111ab9aefeeSPetr Hosek
112ab9aefeeSPetr Hosek// Thread
113ab9aefeeSPetr Hosek#define _LIBCPP_NULL_THREAD 0U
114ab9aefeeSPetr Hosek
115ab9aefeeSPetr Hosektypedef thrd_t __libcpp_thread_t;
116ab9aefeeSPetr Hosek
117ab9aefeeSPetr Hosek// Thread Local Storage
118ab9aefeeSPetr Hosektypedef tss_t __libcpp_tls_key;
119ab9aefeeSPetr Hosek
120ab9aefeeSPetr Hosek#define _LIBCPP_TLS_DESTRUCTOR_CC
121e2b200b7SDavid Spickett#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
122ac15ae6dSPeter Collingbourne// Mutex
123ac15ae6dSPeter Collingbournetypedef void* __libcpp_mutex_t;
124ac15ae6dSPeter Collingbourne#define _LIBCPP_MUTEX_INITIALIZER 0
125ac15ae6dSPeter Collingbourne
126ac15ae6dSPeter Collingbourne#if defined(_M_IX86) || defined(__i386__) || defined(_M_ARM) || defined(__arm__)
127ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[6];
128ac15ae6dSPeter Collingbourne#elif defined(_M_AMD64) || defined(__x86_64__) || defined(_M_ARM64) || defined(__aarch64__)
129ac15ae6dSPeter Collingbournetypedef void* __libcpp_recursive_mutex_t[5];
130ac15ae6dSPeter Collingbourne#else
131ac15ae6dSPeter Collingbourne# error Unsupported architecture
132ac15ae6dSPeter Collingbourne#endif
1336d7d0becSSaleem Abdulrasool
1346d7d0becSSaleem Abdulrasool// Condition Variable
135ac15ae6dSPeter Collingbournetypedef void* __libcpp_condvar_t;
136ac15ae6dSPeter Collingbourne#define _LIBCPP_CONDVAR_INITIALIZER 0
1376d7d0becSSaleem Abdulrasool
1386d7d0becSSaleem Abdulrasool// Execute Once
139ac15ae6dSPeter Collingbournetypedef void* __libcpp_exec_once_flag;
140ac15ae6dSPeter Collingbourne#define _LIBCPP_EXEC_ONCE_INITIALIZER 0
1416d7d0becSSaleem Abdulrasool
1426d7d0becSSaleem Abdulrasool// Thread ID
143ac15ae6dSPeter Collingbournetypedef long __libcpp_thread_id;
1446d7d0becSSaleem Abdulrasool
1456d7d0becSSaleem Abdulrasool// Thread
146af762e91SAsiri Rathnayake#define _LIBCPP_NULL_THREAD 0U
147af762e91SAsiri Rathnayake
148ac15ae6dSPeter Collingbournetypedef void* __libcpp_thread_t;
1496d7d0becSSaleem Abdulrasool
1506d7d0becSSaleem Abdulrasool// Thread Local Storage
151ac15ae6dSPeter Collingbournetypedef long __libcpp_tls_key;
1526d7d0becSSaleem Abdulrasool
153ac15ae6dSPeter Collingbourne#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
154e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
155790e10f6SSaleem Abdulrasool
156e2b200b7SDavid Spickett#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
157790e10f6SSaleem Abdulrasool// Mutex
1588c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
15958a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
16058a0dceeSSaleem Abdulrasool
16183dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
16258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m);
16358a0dceeSSaleem Abdulrasool
16483dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
16508e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m);
16658a0dceeSSaleem Abdulrasool
16783dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
16858a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m);
16958a0dceeSSaleem Abdulrasool
17058a0dceeSSaleem Abdulrasool_LIBCPP_THREAD_ABI_VISIBILITY
17158a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m);
172790e10f6SSaleem Abdulrasool
17383dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1748c2bf45dSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m);
175790e10f6SSaleem Abdulrasool
17683dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
17708e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m);
178790e10f6SSaleem Abdulrasool
17983dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1808c2bf45dSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m);
181790e10f6SSaleem Abdulrasool
1828c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1838c2bf45dSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m);
1848c2bf45dSAsiri Rathnayake
1858c2bf45dSAsiri Rathnayake// Condition variable
1868c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1878c2bf45dSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
188790e10f6SSaleem Abdulrasool
1898c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
1908c2bf45dSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
191790e10f6SSaleem Abdulrasool
19283dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
1938c2bf45dSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
194790e10f6SSaleem Abdulrasool
19583dca5c3SDimitry Andric_LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
196790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
197cfdc7f0dSMikhail Maltsev                               __libcpp_timespec_t *__ts);
198790e10f6SSaleem Abdulrasool
1998c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2008c2bf45dSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
2018c2bf45dSAsiri Rathnayake
202205d7d3fSAsiri Rathnayake// Execute once
203205d7d3fSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
204*b48c5010SNikolas Klauserint __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
205*b48c5010SNikolas Klauser                          void (*__init_routine)());
206205d7d3fSAsiri Rathnayake
207205d7d3fSAsiri Rathnayake// Thread id
2088c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
209*b48c5010SNikolas Klauserbool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
210790e10f6SSaleem Abdulrasool
2118c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
212*b48c5010SNikolas Klauserbool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
2138c2bf45dSAsiri Rathnayake
2148c2bf45dSAsiri Rathnayake// Thread
2158c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
216af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t);
217af762e91SAsiri Rathnayake
218af762e91SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
219790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
220790e10f6SSaleem Abdulrasool                           void *__arg);
221790e10f6SSaleem Abdulrasool
2228c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2238c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id();
224790e10f6SSaleem Abdulrasool
2258c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2268c2bf45dSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t);
227790e10f6SSaleem Abdulrasool
2288c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2298c2bf45dSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t);
230790e10f6SSaleem Abdulrasool
2318c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2328c2bf45dSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t);
233790e10f6SSaleem Abdulrasool
2348c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2358c2bf45dSAsiri Rathnayakevoid __libcpp_thread_yield();
2368c2bf45dSAsiri Rathnayake
23754a987e1SAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2389e8a082dSJoerg Sonnenbergervoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns);
23954a987e1SAsiri Rathnayake
2408c2bf45dSAsiri Rathnayake// Thread local storage
2418c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2426d7d0becSSaleem Abdulrasoolint __libcpp_tls_create(__libcpp_tls_key* __key,
2436d7d0becSSaleem Abdulrasool                        void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*));
244790e10f6SSaleem Abdulrasool
2458c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
2468c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key);
247790e10f6SSaleem Abdulrasool
2488c2bf45dSAsiri Rathnayake_LIBCPP_THREAD_ABI_VISIBILITY
249205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
2508c2bf45dSAsiri Rathnayake
251e2b200b7SDavid Spickett#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
252e2b200b7SDavid Spickett
2533411a1a9SDavid Nicuesa#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
2543411a1a9SDavid Nicuesa     defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
2553411a1a9SDavid Nicuesa
256ab9aefeeSPetr Hosek#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
2578c2bf45dSAsiri Rathnayake
25858a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
259c7e4239fSAsiri Rathnayake{
260c7e4239fSAsiri Rathnayake  pthread_mutexattr_t attr;
261c7e4239fSAsiri Rathnayake  int __ec = pthread_mutexattr_init(&attr);
262c7e4239fSAsiri Rathnayake  if (__ec)
263790e10f6SSaleem Abdulrasool    return __ec;
264790e10f6SSaleem Abdulrasool  __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
265790e10f6SSaleem Abdulrasool  if (__ec) {
266c7e4239fSAsiri Rathnayake    pthread_mutexattr_destroy(&attr);
267c7e4239fSAsiri Rathnayake    return __ec;
268c7e4239fSAsiri Rathnayake  }
269c7e4239fSAsiri Rathnayake  __ec = pthread_mutex_init(__m, &attr);
270790e10f6SSaleem Abdulrasool  if (__ec) {
271c7e4239fSAsiri Rathnayake    pthread_mutexattr_destroy(&attr);
272c7e4239fSAsiri Rathnayake    return __ec;
273c7e4239fSAsiri Rathnayake  }
274c7e4239fSAsiri Rathnayake  __ec = pthread_mutexattr_destroy(&attr);
275790e10f6SSaleem Abdulrasool  if (__ec) {
276c7e4239fSAsiri Rathnayake    pthread_mutex_destroy(__m);
277c7e4239fSAsiri Rathnayake    return __ec;
278c7e4239fSAsiri Rathnayake  }
279c7e4239fSAsiri Rathnayake  return 0;
280c7e4239fSAsiri Rathnayake}
281c7e4239fSAsiri Rathnayake
28258a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
28358a0dceeSSaleem Abdulrasool{
28458a0dceeSSaleem Abdulrasool  return pthread_mutex_lock(__m);
28558a0dceeSSaleem Abdulrasool}
28658a0dceeSSaleem Abdulrasool
28708e1477cSEric Fiselierbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
28858a0dceeSSaleem Abdulrasool{
28908e1477cSEric Fiselier  return pthread_mutex_trylock(__m) == 0;
29058a0dceeSSaleem Abdulrasool}
29158a0dceeSSaleem Abdulrasool
292ebfadd82SColin Finckint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
29358a0dceeSSaleem Abdulrasool{
29458a0dceeSSaleem Abdulrasool  return pthread_mutex_unlock(__m);
29558a0dceeSSaleem Abdulrasool}
29658a0dceeSSaleem Abdulrasool
29758a0dceeSSaleem Abdulrasoolint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
29858a0dceeSSaleem Abdulrasool{
29958a0dceeSSaleem Abdulrasool  return pthread_mutex_destroy(__m);
30058a0dceeSSaleem Abdulrasool}
30158a0dceeSSaleem Abdulrasool
302c7e4239fSAsiri Rathnayakeint __libcpp_mutex_lock(__libcpp_mutex_t *__m)
303c7e4239fSAsiri Rathnayake{
304c7e4239fSAsiri Rathnayake  return pthread_mutex_lock(__m);
305c7e4239fSAsiri Rathnayake}
306c7e4239fSAsiri Rathnayake
30708e1477cSEric Fiselierbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
308c7e4239fSAsiri Rathnayake{
30908e1477cSEric Fiselier  return pthread_mutex_trylock(__m) == 0;
310c7e4239fSAsiri Rathnayake}
311c7e4239fSAsiri Rathnayake
312c7e4239fSAsiri Rathnayakeint __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
313c7e4239fSAsiri Rathnayake{
314c7e4239fSAsiri Rathnayake  return pthread_mutex_unlock(__m);
315c7e4239fSAsiri Rathnayake}
316c7e4239fSAsiri Rathnayake
317c7e4239fSAsiri Rathnayakeint __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
318c7e4239fSAsiri Rathnayake{
319c7e4239fSAsiri Rathnayake  return pthread_mutex_destroy(__m);
320c7e4239fSAsiri Rathnayake}
321c7e4239fSAsiri Rathnayake
322790e10f6SSaleem Abdulrasool// Condition Variable
323c7e4239fSAsiri Rathnayakeint __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
324c7e4239fSAsiri Rathnayake{
325c7e4239fSAsiri Rathnayake  return pthread_cond_signal(__cv);
326c7e4239fSAsiri Rathnayake}
327c7e4239fSAsiri Rathnayake
328c7e4239fSAsiri Rathnayakeint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
329c7e4239fSAsiri Rathnayake{
330c7e4239fSAsiri Rathnayake  return pthread_cond_broadcast(__cv);
331c7e4239fSAsiri Rathnayake}
332c7e4239fSAsiri Rathnayake
333c7e4239fSAsiri Rathnayakeint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
334c7e4239fSAsiri Rathnayake{
335c7e4239fSAsiri Rathnayake  return pthread_cond_wait(__cv, __m);
336c7e4239fSAsiri Rathnayake}
337c7e4239fSAsiri Rathnayake
338790e10f6SSaleem Abdulrasoolint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
339cfdc7f0dSMikhail Maltsev                               __libcpp_timespec_t *__ts)
340c7e4239fSAsiri Rathnayake{
341c7e4239fSAsiri Rathnayake  return pthread_cond_timedwait(__cv, __m, __ts);
342c7e4239fSAsiri Rathnayake}
343c7e4239fSAsiri Rathnayake
344c7e4239fSAsiri Rathnayakeint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
345c7e4239fSAsiri Rathnayake{
346c7e4239fSAsiri Rathnayake  return pthread_cond_destroy(__cv);
347c7e4239fSAsiri Rathnayake}
348c7e4239fSAsiri Rathnayake
349205d7d3fSAsiri Rathnayake// Execute once
350*b48c5010SNikolas Klauserint __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
351*b48c5010SNikolas Klauser                          void (*__init_routine)()) {
352*b48c5010SNikolas Klauser  return pthread_once(__flag, __init_routine);
353205d7d3fSAsiri Rathnayake}
354205d7d3fSAsiri Rathnayake
355205d7d3fSAsiri Rathnayake// Thread id
356c7e4239fSAsiri Rathnayake// Returns non-zero if the thread ids are equal, otherwise 0
357*b48c5010SNikolas Klauserbool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
358c7e4239fSAsiri Rathnayake{
359*b48c5010SNikolas Klauser  return __t1 == __t2;
360c7e4239fSAsiri Rathnayake}
361c7e4239fSAsiri Rathnayake
362c7e4239fSAsiri Rathnayake// Returns non-zero if t1 < t2, otherwise 0
363*b48c5010SNikolas Klauserbool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
364c7e4239fSAsiri Rathnayake{
365*b48c5010SNikolas Klauser  return __t1 < __t2;
366c7e4239fSAsiri Rathnayake}
367c7e4239fSAsiri Rathnayake
368c7e4239fSAsiri Rathnayake// Thread
369af762e91SAsiri Rathnayakebool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
37048fcce1aSZbigniew Sarbinowski  return __libcpp_thread_get_id(__t) == 0;
371af762e91SAsiri Rathnayake}
372af762e91SAsiri Rathnayake
373790e10f6SSaleem Abdulrasoolint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
374790e10f6SSaleem Abdulrasool                           void *__arg)
375c7e4239fSAsiri Rathnayake{
376527a7fdfSBruce Mitchener  return pthread_create(__t, nullptr, __func, __arg);
377c7e4239fSAsiri Rathnayake}
378c7e4239fSAsiri Rathnayake
379c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_current_id()
380c7e4239fSAsiri Rathnayake{
381e6c89a49SZbigniew Sarbinowski  const __libcpp_thread_t thread = pthread_self();
382e6c89a49SZbigniew Sarbinowski  return __libcpp_thread_get_id(&thread);
383c7e4239fSAsiri Rathnayake}
384c7e4239fSAsiri Rathnayake
385c7e4239fSAsiri Rathnayake__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
386c7e4239fSAsiri Rathnayake{
387e6c89a49SZbigniew Sarbinowski#if defined(__MVS__)
388e6c89a49SZbigniew Sarbinowski  return __t->__;
389e6c89a49SZbigniew Sarbinowski#else
390c7e4239fSAsiri Rathnayake  return *__t;
391e6c89a49SZbigniew Sarbinowski#endif
392c7e4239fSAsiri Rathnayake}
393c7e4239fSAsiri Rathnayake
394c7e4239fSAsiri Rathnayakeint __libcpp_thread_join(__libcpp_thread_t *__t)
395c7e4239fSAsiri Rathnayake{
396527a7fdfSBruce Mitchener  return pthread_join(*__t, nullptr);
397c7e4239fSAsiri Rathnayake}
398c7e4239fSAsiri Rathnayake
399c7e4239fSAsiri Rathnayakeint __libcpp_thread_detach(__libcpp_thread_t *__t)
400c7e4239fSAsiri Rathnayake{
401c7e4239fSAsiri Rathnayake  return pthread_detach(*__t);
402c7e4239fSAsiri Rathnayake}
403c7e4239fSAsiri Rathnayake
404c7e4239fSAsiri Rathnayakevoid __libcpp_thread_yield()
405c7e4239fSAsiri Rathnayake{
406c7e4239fSAsiri Rathnayake  sched_yield();
407c7e4239fSAsiri Rathnayake}
408c7e4239fSAsiri Rathnayake
40954a987e1SAsiri Rathnayakevoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
41054a987e1SAsiri Rathnayake{
411df51be85SLouis Dionne   __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
41254a987e1SAsiri Rathnayake   while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
41354a987e1SAsiri Rathnayake}
41454a987e1SAsiri Rathnayake
415c7e4239fSAsiri Rathnayake// Thread local storage
4168c2bf45dSAsiri Rathnayakeint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
417c7e4239fSAsiri Rathnayake{
418c7e4239fSAsiri Rathnayake  return pthread_key_create(__key, __at_exit);
419c7e4239fSAsiri Rathnayake}
420c7e4239fSAsiri Rathnayake
4218c2bf45dSAsiri Rathnayakevoid *__libcpp_tls_get(__libcpp_tls_key __key)
422c7e4239fSAsiri Rathnayake{
423c7e4239fSAsiri Rathnayake  return pthread_getspecific(__key);
424c7e4239fSAsiri Rathnayake}
425c7e4239fSAsiri Rathnayake
426205d7d3fSAsiri Rathnayakeint __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
427c7e4239fSAsiri Rathnayake{
428205d7d3fSAsiri Rathnayake    return pthread_setspecific(__key, __p);
429c7e4239fSAsiri Rathnayake}
430c7e4239fSAsiri Rathnayake
431ab9aefeeSPetr Hosek#elif defined(_LIBCPP_HAS_THREAD_API_C11)
432ab9aefeeSPetr Hosek
433ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
434ab9aefeeSPetr Hosek{
4353481e5d7SPetr Hosek  return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
436ab9aefeeSPetr Hosek}
437ab9aefeeSPetr Hosek
438ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
439ab9aefeeSPetr Hosek{
440ab9aefeeSPetr Hosek  return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
441ab9aefeeSPetr Hosek}
442ab9aefeeSPetr Hosek
443ab9aefeeSPetr Hosekbool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
444ab9aefeeSPetr Hosek{
445ab9aefeeSPetr Hosek  return mtx_trylock(__m) == thrd_success;
446ab9aefeeSPetr Hosek}
447ab9aefeeSPetr Hosek
448ebfadd82SColin Finckint __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
449ab9aefeeSPetr Hosek{
450ab9aefeeSPetr Hosek  return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
451ab9aefeeSPetr Hosek}
452ab9aefeeSPetr Hosek
453ab9aefeeSPetr Hosekint __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
454ab9aefeeSPetr Hosek{
455ab9aefeeSPetr Hosek  mtx_destroy(__m);
456ab9aefeeSPetr Hosek  return 0;
457ab9aefeeSPetr Hosek}
458ab9aefeeSPetr Hosek
459ab9aefeeSPetr Hosekint __libcpp_mutex_lock(__libcpp_mutex_t *__m)
460ab9aefeeSPetr Hosek{
461ab9aefeeSPetr Hosek  return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
462ab9aefeeSPetr Hosek}
463ab9aefeeSPetr Hosek
464ab9aefeeSPetr Hosekbool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
465ab9aefeeSPetr Hosek{
466ab9aefeeSPetr Hosek  return mtx_trylock(__m) == thrd_success;
467ab9aefeeSPetr Hosek}
468ab9aefeeSPetr Hosek
469ab9aefeeSPetr Hosekint __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
470ab9aefeeSPetr Hosek{
471ab9aefeeSPetr Hosek  return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
472ab9aefeeSPetr Hosek}
473ab9aefeeSPetr Hosek
474ab9aefeeSPetr Hosekint __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
475ab9aefeeSPetr Hosek{
476ab9aefeeSPetr Hosek  mtx_destroy(__m);
477ab9aefeeSPetr Hosek  return 0;
478ab9aefeeSPetr Hosek}
479ab9aefeeSPetr Hosek
480ab9aefeeSPetr Hosek// Condition Variable
481ab9aefeeSPetr Hosekint __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
482ab9aefeeSPetr Hosek{
483ab9aefeeSPetr Hosek  return cnd_signal(__cv) == thrd_success ? 0 : EINVAL;
484ab9aefeeSPetr Hosek}
485ab9aefeeSPetr Hosek
486ab9aefeeSPetr Hosekint __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
487ab9aefeeSPetr Hosek{
488ab9aefeeSPetr Hosek  return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
489ab9aefeeSPetr Hosek}
490ab9aefeeSPetr Hosek
491ab9aefeeSPetr Hosekint __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
492ab9aefeeSPetr Hosek{
493ab9aefeeSPetr Hosek  return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
494ab9aefeeSPetr Hosek}
495ab9aefeeSPetr Hosek
496ab9aefeeSPetr Hosekint __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
497ab9aefeeSPetr Hosek                               timespec *__ts)
498ab9aefeeSPetr Hosek{
499ab9aefeeSPetr Hosek  int __ec = cnd_timedwait(__cv, __m, __ts);
500ab9aefeeSPetr Hosek  return __ec == thrd_timedout ? ETIMEDOUT : __ec;
501ab9aefeeSPetr Hosek}
502ab9aefeeSPetr Hosek
503ab9aefeeSPetr Hosekint __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
504ab9aefeeSPetr Hosek{
505ab9aefeeSPetr Hosek  cnd_destroy(__cv);
506ab9aefeeSPetr Hosek  return 0;
507ab9aefeeSPetr Hosek}
508ab9aefeeSPetr Hosek
509ab9aefeeSPetr Hosek// Execute once
510ab9aefeeSPetr Hosekint __libcpp_execute_once(__libcpp_exec_once_flag *flag,
511ab9aefeeSPetr Hosek                          void (*init_routine)(void)) {
512ab9aefeeSPetr Hosek  ::call_once(flag, init_routine);
513ab9aefeeSPetr Hosek  return 0;
514ab9aefeeSPetr Hosek}
515ab9aefeeSPetr Hosek
516ab9aefeeSPetr Hosek// Thread id
517ab9aefeeSPetr Hosek// Returns non-zero if the thread ids are equal, otherwise 0
518ab9aefeeSPetr Hosekbool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
519ab9aefeeSPetr Hosek{
520ab9aefeeSPetr Hosek  return thrd_equal(t1, t2) != 0;
521ab9aefeeSPetr Hosek}
522ab9aefeeSPetr Hosek
523ab9aefeeSPetr Hosek// Returns non-zero if t1 < t2, otherwise 0
524ab9aefeeSPetr Hosekbool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
525ab9aefeeSPetr Hosek{
526ab9aefeeSPetr Hosek  return t1 < t2;
527ab9aefeeSPetr Hosek}
528ab9aefeeSPetr Hosek
529ab9aefeeSPetr Hosek// Thread
530ab9aefeeSPetr Hosekbool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
531e6c89a49SZbigniew Sarbinowski  return __libcpp_thread_get_id(__t) == 0;
532ab9aefeeSPetr Hosek}
533ab9aefeeSPetr Hosek
534ab9aefeeSPetr Hosekint __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
535ab9aefeeSPetr Hosek                           void *__arg)
536ab9aefeeSPetr Hosek{
537ab9aefeeSPetr Hosek  int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg);
538ab9aefeeSPetr Hosek  return __ec == thrd_nomem ? ENOMEM : __ec;
539ab9aefeeSPetr Hosek}
540ab9aefeeSPetr Hosek
541ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_current_id()
542ab9aefeeSPetr Hosek{
543ab9aefeeSPetr Hosek  return thrd_current();
544ab9aefeeSPetr Hosek}
545ab9aefeeSPetr Hosek
546ab9aefeeSPetr Hosek__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
547ab9aefeeSPetr Hosek{
548ab9aefeeSPetr Hosek  return *__t;
549ab9aefeeSPetr Hosek}
550ab9aefeeSPetr Hosek
551ab9aefeeSPetr Hosekint __libcpp_thread_join(__libcpp_thread_t *__t)
552ab9aefeeSPetr Hosek{
553ab9aefeeSPetr Hosek  return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL;
554ab9aefeeSPetr Hosek}
555ab9aefeeSPetr Hosek
556ab9aefeeSPetr Hosekint __libcpp_thread_detach(__libcpp_thread_t *__t)
557ab9aefeeSPetr Hosek{
558ab9aefeeSPetr Hosek  return thrd_detach(*__t) == thrd_success ? 0 : EINVAL;
559ab9aefeeSPetr Hosek}
560ab9aefeeSPetr Hosek
561ab9aefeeSPetr Hosekvoid __libcpp_thread_yield()
562ab9aefeeSPetr Hosek{
563ab9aefeeSPetr Hosek  thrd_yield();
564ab9aefeeSPetr Hosek}
565ab9aefeeSPetr Hosek
566ab9aefeeSPetr Hosekvoid __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
567ab9aefeeSPetr Hosek{
568df51be85SLouis Dionne   __libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
569ab9aefeeSPetr Hosek  thrd_sleep(&__ts, nullptr);
570ab9aefeeSPetr Hosek}
571ab9aefeeSPetr Hosek
572ab9aefeeSPetr Hosek// Thread local storage
573ab9aefeeSPetr Hosekint __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
574ab9aefeeSPetr Hosek{
575ab9aefeeSPetr Hosek  return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
576ab9aefeeSPetr Hosek}
577ab9aefeeSPetr Hosek
578ab9aefeeSPetr Hosekvoid *__libcpp_tls_get(__libcpp_tls_key __key)
579ab9aefeeSPetr Hosek{
580ab9aefeeSPetr Hosek  return tss_get(__key);
581ab9aefeeSPetr Hosek}
582ab9aefeeSPetr Hosek
583ab9aefeeSPetr Hosekint __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
584ab9aefeeSPetr Hosek{
585ab9aefeeSPetr Hosek  return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
586ab9aefeeSPetr Hosek}
587ab9aefeeSPetr Hosek
588ab9aefeeSPetr Hosek#endif
589ab9aefeeSPetr Hosek
590e3add3e5SMartin Storsjö
59100f6beaeSEric Fiselier#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
59200f6beaeSEric Fiselier
5932b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS thread;
5942b1d4254SMarshall Clowclass _LIBCPP_TYPE_VIS __thread_id;
5952b1d4254SMarshall Clow
5962b1d4254SMarshall Clownamespace this_thread
5972b1d4254SMarshall Clow{
5982b1d4254SMarshall Clow
5992b1d4254SMarshall Clow_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
6002b1d4254SMarshall Clow
601d2b0df35SNikolas Klauser} // namespace this_thread
6022b1d4254SMarshall Clow
6032b1d4254SMarshall Clowtemplate<> struct hash<__thread_id>;
6042b1d4254SMarshall Clow
6052b1d4254SMarshall Clowclass _LIBCPP_TEMPLATE_VIS __thread_id
6062b1d4254SMarshall Clow{
6072b1d4254SMarshall Clow    // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
6082b1d4254SMarshall Clow    // NULL is the no-thread value on Darwin.  Someone needs to check
6092b1d4254SMarshall Clow    // on other platforms.  We assume 0 works everywhere for now.
6102b1d4254SMarshall Clow    __libcpp_thread_id __id_;
6112b1d4254SMarshall Clow
6122b1d4254SMarshall Clowpublic:
6132b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
6142b1d4254SMarshall Clow    __thread_id() _NOEXCEPT : __id_(0) {}
6152b1d4254SMarshall Clow
6162b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6172b1d4254SMarshall Clow        bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
6182e80d01fSMarshall Clow        { // don't pass id==0 to underlying routines
6192e80d01fSMarshall Clow        if (__x.__id_ == 0) return __y.__id_ == 0;
6202e80d01fSMarshall Clow        if (__y.__id_ == 0) return false;
6212e80d01fSMarshall Clow        return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
6222e80d01fSMarshall Clow        }
6232b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6242b1d4254SMarshall Clow        bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT
6252b1d4254SMarshall Clow        {return !(__x == __y);}
6262b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6272b1d4254SMarshall Clow        bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT
6282e80d01fSMarshall Clow        { // id==0 is always less than any other thread_id
6292e80d01fSMarshall Clow        if (__x.__id_ == 0) return __y.__id_ != 0;
6302e80d01fSMarshall Clow        if (__y.__id_ == 0) return false;
6312e80d01fSMarshall Clow        return  __libcpp_thread_id_less(__x.__id_, __y.__id_);
6322e80d01fSMarshall Clow        }
6332b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6342b1d4254SMarshall Clow        bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT
6352b1d4254SMarshall Clow        {return !(__y < __x);}
6362b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6372b1d4254SMarshall Clow        bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT
6382b1d4254SMarshall Clow        {return   __y < __x ;}
6392b1d4254SMarshall Clow    friend _LIBCPP_INLINE_VISIBILITY
6402b1d4254SMarshall Clow        bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
6412b1d4254SMarshall Clow        {return !(__x < __y);}
6422b1d4254SMarshall Clow
6432b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
6442e80d01fSMarshall Clow    void __reset() { __id_ = 0; }
6452b1d4254SMarshall Clow
6462b1d4254SMarshall Clow    template<class _CharT, class _Traits>
6472b1d4254SMarshall Clow    friend
6482b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
6492b1d4254SMarshall Clow    basic_ostream<_CharT, _Traits>&
6502b1d4254SMarshall Clow    operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
6512b1d4254SMarshall Clow
6522b1d4254SMarshall Clowprivate:
6532b1d4254SMarshall Clow    _LIBCPP_INLINE_VISIBILITY
6542b1d4254SMarshall Clow    __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
6552b1d4254SMarshall Clow
6562b1d4254SMarshall Clow    friend __thread_id this_thread::get_id() _NOEXCEPT;
6572b1d4254SMarshall Clow    friend class _LIBCPP_TYPE_VIS thread;
6582b1d4254SMarshall Clow    friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
6592b1d4254SMarshall Clow};
6602b1d4254SMarshall Clow
6612b1d4254SMarshall Clownamespace this_thread
6622b1d4254SMarshall Clow{
6632b1d4254SMarshall Clow
6642b1d4254SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
6652b1d4254SMarshall Clow__thread_id
6662b1d4254SMarshall Clowget_id() _NOEXCEPT
6672b1d4254SMarshall Clow{
6682b1d4254SMarshall Clow    return __libcpp_thread_get_current_id();
6692b1d4254SMarshall Clow}
6702b1d4254SMarshall Clow
671d2b0df35SNikolas Klauser} // namespace this_thread
6722b1d4254SMarshall Clow
673696630eaSMarshall Clow#endif // !_LIBCPP_HAS_NO_THREADS
674696630eaSMarshall Clow
675c7e4239fSAsiri Rathnayake_LIBCPP_END_NAMESPACE_STD
676c7e4239fSAsiri Rathnayake
677cc82a1b0SLouis Dionne#endif // _LIBCPP___THREADING_SUPPORT
678