Upgrade to 2022-era LLVM LIBCXX

This commit is contained in:
Justine Tunney 2024-05-27 02:12:27 -07:00
parent 2f4ca71f26
commit 8e68384e15
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
2078 changed files with 165657 additions and 65010 deletions

View file

@ -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