mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-28 00:02:28 +00:00
Upgrade to 2022-era LLVM LIBCXX
This commit is contained in:
parent
2f4ca71f26
commit
8e68384e15
2078 changed files with 165657 additions and 65010 deletions
402
third_party/libcxx/__threading_support
vendored
402
third_party/libcxx/__threading_support
vendored
|
@ -7,29 +7,37 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP_THREADING_SUPPORT
|
||||
#define _LIBCPP_THREADING_SUPPORT
|
||||
#ifndef _LIBCPP___THREADING_SUPPORT
|
||||
#define _LIBCPP___THREADING_SUPPORT
|
||||
|
||||
#include "third_party/libcxx/__config"
|
||||
#include "third_party/libcxx/chrono"
|
||||
#include "third_party/libcxx/iosfwd"
|
||||
#include "libc/thread/thread2.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "third_party/libcxx/errno.h"
|
||||
#include <__availability>
|
||||
#include <__chrono/convert_to_timespec.h>
|
||||
#include <__chrono/duration.h>
|
||||
#include <__compare/ordering.h>
|
||||
#include <__config>
|
||||
#include <__fwd/hash.h>
|
||||
#include <__thread/poll_with_backoff.h>
|
||||
#include <errno.h>
|
||||
#include <iosfwd>
|
||||
#include <limits>
|
||||
|
||||
#ifdef __MVS__
|
||||
# include <__support/ibm/nanosleep.h>
|
||||
#endif
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
|
||||
#pragma GCC system_header
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
|
||||
//# include "third_party/libcxx/__external_threading"
|
||||
# include <__external_threading>
|
||||
#elif !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
#include "libc/sysv/consts/sched.h"
|
||||
# include <pthread.h>
|
||||
# include <sched.h>
|
||||
#elif defined(_LIBCPP_HAS_THREAD_API_C11)
|
||||
# include <threads.h>
|
||||
#endif
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
|
||||
|
@ -49,9 +57,6 @@
|
|||
typedef ::timespec __libcpp_timespec_t;
|
||||
#endif // !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include "third_party/libcxx/__undef_macros"
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
|
@ -72,16 +77,48 @@ typedef pthread_once_t __libcpp_exec_once_flag;
|
|||
#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
|
||||
|
||||
// Thread id
|
||||
typedef pthread_t __libcpp_thread_id;
|
||||
#if defined(__MVS__)
|
||||
typedef unsigned long long __libcpp_thread_id;
|
||||
#else
|
||||
typedef pthread_t __libcpp_thread_id;
|
||||
#endif
|
||||
|
||||
// Thread
|
||||
#define _LIBCPP_NULL_THREAD 0U
|
||||
|
||||
#define _LIBCPP_NULL_THREAD ((__libcpp_thread_t()))
|
||||
typedef pthread_t __libcpp_thread_t;
|
||||
|
||||
// Thread Local Storage
|
||||
typedef pthread_key_t __libcpp_tls_key;
|
||||
|
||||
#define _LIBCPP_TLS_DESTRUCTOR_CC
|
||||
#elif defined(_LIBCPP_HAS_THREAD_API_C11)
|
||||
// Mutex
|
||||
typedef mtx_t __libcpp_mutex_t;
|
||||
// mtx_t is a struct so using {} for initialization is valid.
|
||||
#define _LIBCPP_MUTEX_INITIALIZER {}
|
||||
|
||||
typedef mtx_t __libcpp_recursive_mutex_t;
|
||||
|
||||
// Condition Variable
|
||||
typedef cnd_t __libcpp_condvar_t;
|
||||
// cnd_t is a struct so using {} for initialization is valid.
|
||||
#define _LIBCPP_CONDVAR_INITIALIZER {}
|
||||
|
||||
// Execute once
|
||||
typedef once_flag __libcpp_exec_once_flag;
|
||||
#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT
|
||||
|
||||
// Thread id
|
||||
typedef thrd_t __libcpp_thread_id;
|
||||
|
||||
// Thread
|
||||
#define _LIBCPP_NULL_THREAD 0U
|
||||
|
||||
typedef thrd_t __libcpp_thread_t;
|
||||
|
||||
// Thread Local Storage
|
||||
typedef tss_t __libcpp_tls_key;
|
||||
|
||||
#define _LIBCPP_TLS_DESTRUCTOR_CC
|
||||
#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
|
||||
// Mutex
|
||||
|
@ -166,15 +203,15 @@ int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
|
|||
|
||||
// Execute once
|
||||
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
|
||||
void (*init_routine)());
|
||||
int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
|
||||
void (*__init_routine)());
|
||||
|
||||
// Thread id
|
||||
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
|
||||
bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
|
||||
|
||||
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
|
||||
bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2);
|
||||
|
||||
// Thread
|
||||
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||
|
@ -216,26 +253,27 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
|
|||
#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
|
||||
|
||||
#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
|
||||
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \
|
||||
defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
||||
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
|
||||
|
||||
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
int __ec = pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_t __attr;
|
||||
int __ec = pthread_mutexattr_init(&__attr);
|
||||
if (__ec)
|
||||
return __ec;
|
||||
__ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
__ec = pthread_mutexattr_settype(&__attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
if (__ec) {
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
pthread_mutexattr_destroy(&__attr);
|
||||
return __ec;
|
||||
}
|
||||
__ec = pthread_mutex_init(__m, &attr);
|
||||
__ec = pthread_mutex_init(__m, &__attr);
|
||||
if (__ec) {
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
pthread_mutexattr_destroy(&__attr);
|
||||
return __ec;
|
||||
}
|
||||
__ec = pthread_mutexattr_destroy(&attr);
|
||||
__ec = pthread_mutexattr_destroy(&__attr);
|
||||
if (__ec) {
|
||||
pthread_mutex_destroy(__m);
|
||||
return __ec;
|
||||
|
@ -253,7 +291,7 @@ bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
|
|||
return pthread_mutex_trylock(__m) == 0;
|
||||
}
|
||||
|
||||
int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m)
|
||||
int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return pthread_mutex_unlock(__m);
|
||||
}
|
||||
|
@ -311,48 +349,53 @@ int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
|
|||
}
|
||||
|
||||
// Execute once
|
||||
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
|
||||
void (*init_routine)()) {
|
||||
return pthread_once(flag, init_routine);
|
||||
int __libcpp_execute_once(__libcpp_exec_once_flag *__flag,
|
||||
void (*__init_routine)()) {
|
||||
return pthread_once(__flag, __init_routine);
|
||||
}
|
||||
|
||||
// Thread id
|
||||
// Returns non-zero if the thread ids are equal, otherwise 0
|
||||
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
|
||||
bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
|
||||
{
|
||||
return pthread_equal(t1, t2) != 0;
|
||||
return __t1 == __t2;
|
||||
}
|
||||
|
||||
// Returns non-zero if t1 < t2, otherwise 0
|
||||
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
|
||||
bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2)
|
||||
{
|
||||
return t1 < t2;
|
||||
return __t1 < __t2;
|
||||
}
|
||||
|
||||
// Thread
|
||||
bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
|
||||
return *__t == 0;
|
||||
return __libcpp_thread_get_id(__t) == 0;
|
||||
}
|
||||
|
||||
int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
|
||||
void *__arg)
|
||||
{
|
||||
return pthread_create(__t, 0, __func, __arg);
|
||||
return pthread_create(__t, nullptr, __func, __arg);
|
||||
}
|
||||
|
||||
__libcpp_thread_id __libcpp_thread_get_current_id()
|
||||
{
|
||||
return pthread_self();
|
||||
const __libcpp_thread_t __current_thread = pthread_self();
|
||||
return __libcpp_thread_get_id(&__current_thread);
|
||||
}
|
||||
|
||||
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
|
||||
{
|
||||
#if defined(__MVS__)
|
||||
return __t->__;
|
||||
#else
|
||||
return *__t;
|
||||
#endif
|
||||
}
|
||||
|
||||
int __libcpp_thread_join(__libcpp_thread_t *__t)
|
||||
{
|
||||
return pthread_join(*__t, 0);
|
||||
return pthread_join(*__t, nullptr);
|
||||
}
|
||||
|
||||
int __libcpp_thread_detach(__libcpp_thread_t *__t)
|
||||
|
@ -362,28 +405,12 @@ int __libcpp_thread_detach(__libcpp_thread_t *__t)
|
|||
|
||||
void __libcpp_thread_yield()
|
||||
{
|
||||
pthread_yield();
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
|
||||
{
|
||||
using namespace chrono;
|
||||
seconds __s = duration_cast<seconds>(__ns);
|
||||
__libcpp_timespec_t __ts;
|
||||
typedef decltype(__ts.tv_sec) ts_sec;
|
||||
_LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits<ts_sec>::max();
|
||||
|
||||
if (__s.count() < __ts_sec_max)
|
||||
{
|
||||
__ts.tv_sec = static_cast<ts_sec>(__s.count());
|
||||
__ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
|
||||
}
|
||||
else
|
||||
{
|
||||
__ts.tv_sec = __ts_sec_max;
|
||||
__ts.tv_nsec = 999999999; // (10^9 - 1)
|
||||
}
|
||||
|
||||
__libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
|
||||
while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
|
||||
}
|
||||
|
||||
|
@ -403,6 +430,166 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
|
|||
return pthread_setspecific(__key, __p);
|
||||
}
|
||||
|
||||
#elif defined(_LIBCPP_HAS_THREAD_API_C11)
|
||||
|
||||
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return mtx_trylock(__m) == thrd_success;
|
||||
}
|
||||
|
||||
int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m)
|
||||
{
|
||||
mtx_destroy(__m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __libcpp_mutex_lock(__libcpp_mutex_t *__m)
|
||||
{
|
||||
return mtx_lock(__m) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m)
|
||||
{
|
||||
return mtx_trylock(__m) == thrd_success;
|
||||
}
|
||||
|
||||
int __libcpp_mutex_unlock(__libcpp_mutex_t *__m)
|
||||
{
|
||||
return mtx_unlock(__m) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int __libcpp_mutex_destroy(__libcpp_mutex_t *__m)
|
||||
{
|
||||
mtx_destroy(__m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Condition Variable
|
||||
int __libcpp_condvar_signal(__libcpp_condvar_t *__cv)
|
||||
{
|
||||
return cnd_signal(__cv) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv)
|
||||
{
|
||||
return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m)
|
||||
{
|
||||
return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
|
||||
timespec *__ts)
|
||||
{
|
||||
int __ec = cnd_timedwait(__cv, __m, __ts);
|
||||
return __ec == thrd_timedout ? ETIMEDOUT : __ec;
|
||||
}
|
||||
|
||||
int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
|
||||
{
|
||||
cnd_destroy(__cv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Execute once
|
||||
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
|
||||
void (*init_routine)(void)) {
|
||||
::call_once(flag, init_routine);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Thread id
|
||||
// Returns non-zero if the thread ids are equal, otherwise 0
|
||||
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
|
||||
{
|
||||
return thrd_equal(t1, t2) != 0;
|
||||
}
|
||||
|
||||
// Returns non-zero if t1 < t2, otherwise 0
|
||||
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
|
||||
{
|
||||
return t1 < t2;
|
||||
}
|
||||
|
||||
// Thread
|
||||
bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) {
|
||||
return __libcpp_thread_get_id(__t) == 0;
|
||||
}
|
||||
|
||||
int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *),
|
||||
void *__arg)
|
||||
{
|
||||
int __ec = thrd_create(__t, reinterpret_cast<thrd_start_t>(__func), __arg);
|
||||
return __ec == thrd_nomem ? ENOMEM : __ec;
|
||||
}
|
||||
|
||||
__libcpp_thread_id __libcpp_thread_get_current_id()
|
||||
{
|
||||
return thrd_current();
|
||||
}
|
||||
|
||||
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t)
|
||||
{
|
||||
return *__t;
|
||||
}
|
||||
|
||||
int __libcpp_thread_join(__libcpp_thread_t *__t)
|
||||
{
|
||||
return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
int __libcpp_thread_detach(__libcpp_thread_t *__t)
|
||||
{
|
||||
return thrd_detach(*__t) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
void __libcpp_thread_yield()
|
||||
{
|
||||
thrd_yield();
|
||||
}
|
||||
|
||||
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
|
||||
{
|
||||
__libcpp_timespec_t __ts = _VSTD::__convert_to_timespec<__libcpp_timespec_t>(__ns);
|
||||
thrd_sleep(&__ts, nullptr);
|
||||
}
|
||||
|
||||
// Thread local storage
|
||||
int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
|
||||
{
|
||||
return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
void *__libcpp_tls_get(__libcpp_tls_key __key)
|
||||
{
|
||||
return tss_get(__key);
|
||||
}
|
||||
|
||||
int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
|
||||
{
|
||||
return tss_set(__key, __p) == thrd_success ? 0 : EINVAL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
|
||||
|
||||
class _LIBCPP_TYPE_VIS thread;
|
||||
|
@ -413,7 +600,7 @@ namespace this_thread
|
|||
|
||||
_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;
|
||||
|
||||
} // this_thread
|
||||
} // namespace this_thread
|
||||
|
||||
template<> struct hash<__thread_id>;
|
||||
|
||||
|
@ -424,40 +611,28 @@ class _LIBCPP_TEMPLATE_VIS __thread_id
|
|||
// on other platforms. We assume 0 works everywhere for now.
|
||||
__libcpp_thread_id __id_;
|
||||
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__thread_id() _NOEXCEPT : __id_(0) {}
|
||||
|
||||
friend _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
|
||||
{ // don't pass id==0 to underlying routines
|
||||
if (__x.__id_ == 0) return __y.__id_ == 0;
|
||||
if (__y.__id_ == 0) return false;
|
||||
return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
|
||||
}
|
||||
friend _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT
|
||||
{return !(__x == __y);}
|
||||
friend _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT
|
||||
static _LIBCPP_HIDE_FROM_ABI
|
||||
bool __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT
|
||||
{ // id==0 is always less than any other thread_id
|
||||
if (__x.__id_ == 0) return __y.__id_ != 0;
|
||||
if (__y.__id_ == 0) return false;
|
||||
return __libcpp_thread_id_less(__x.__id_, __y.__id_);
|
||||
}
|
||||
friend _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT
|
||||
{return !(__y < __x);}
|
||||
friend _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT
|
||||
{return __y < __x ;}
|
||||
friend _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT
|
||||
{return !(__x < __y);}
|
||||
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__thread_id() _NOEXCEPT : __id_(0) {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void __reset() { __id_ = 0; }
|
||||
|
||||
|
||||
friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
|
||||
#if _LIBCPP_STD_VER <= 17
|
||||
friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT;
|
||||
#else // _LIBCPP_STD_VER <= 17
|
||||
friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept;
|
||||
#endif // _LIBCPP_STD_VER <= 17
|
||||
|
||||
template<class _CharT, class _Traits>
|
||||
friend
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
|
@ -468,11 +643,52 @@ private:
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
__thread_id(__libcpp_thread_id __id) : __id_(__id) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend __libcpp_thread_id __get_underlying_id(const __thread_id __id) { return __id.__id_; }
|
||||
|
||||
friend __thread_id this_thread::get_id() _NOEXCEPT;
|
||||
friend class _LIBCPP_TYPE_VIS thread;
|
||||
friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
|
||||
};
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT {
|
||||
// Don't pass id==0 to underlying routines
|
||||
if (__x.__id_ == 0)
|
||||
return __y.__id_ == 0;
|
||||
if (__y.__id_ == 0)
|
||||
return false;
|
||||
return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER <= 17
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT {
|
||||
return !(__x == __y);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
|
||||
return __thread_id::__lt_impl(__x.__id_, __y.__id_);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }
|
||||
|
||||
#else // _LIBCPP_STD_VER <= 17
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept {
|
||||
if (__x == __y)
|
||||
return strong_ordering::equal;
|
||||
if (__thread_id::__lt_impl(__x, __y))
|
||||
return strong_ordering::less;
|
||||
return strong_ordering::greater;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER <= 17
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
|
||||
|
@ -483,12 +699,10 @@ get_id() _NOEXCEPT
|
|||
return __libcpp_thread_get_current_id();
|
||||
}
|
||||
|
||||
} // this_thread
|
||||
} // namespace this_thread
|
||||
|
||||
#endif // !_LIBCPP_HAS_NO_THREADS
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP_THREADING_SUPPORT
|
||||
#endif // _LIBCPP___THREADING_SUPPORT
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue