Release Cosmopolitan v3.6.0

This release is an atomic upgrade to GCC 14.1.0 with C23 and C++23
This commit is contained in:
Justine Tunney 2024-07-23 03:16:17 -07:00
parent 62ace3623a
commit 5660ec4741
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
1585 changed files with 117353 additions and 271644 deletions

80
third_party/libcxx/__thread/formatter.h vendored Normal file
View file

@ -0,0 +1,80 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___THREAD_FORMATTER_H
#define _LIBCPP___THREAD_FORMATTER_H
#include <__concepts/arithmetic.h>
#include <__config>
#include <__format/concepts.h>
#include <__format/format_parse_context.h>
#include <__format/formatter.h>
#include <__format/formatter_integral.h>
#include <__format/parser_std_format_spec.h>
#include <__thread/id.h>
#include <__type_traits/conditional.h>
#include <__type_traits/is_pointer.h>
#include <__type_traits/is_same.h>
#include <cstdint>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#if _LIBCPP_STD_VER >= 23
_LIBCPP_BEGIN_NAMESPACE_STD
# ifndef _LIBCPP_HAS_NO_THREADS
template <__fmt_char_type _CharT>
struct _LIBCPP_TEMPLATE_VIS formatter<__thread_id, _CharT> {
public:
template <class _ParseContext>
_LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
return __parser_.__parse(__ctx, __format_spec::__fields_fill_align_width);
}
template <class _FormatContext>
_LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(__thread_id __id, _FormatContext& __ctx) const {
// In __thread/support/pthread.h, __libcpp_thread_id is either a
// unsigned long long or a pthread_t.
//
// The type of pthread_t is left unspecified in POSIX so it can be any
// type. The most logical types are an integral or pointer.
// On Linux systems pthread_t is an unsigned long long.
// On Apple systems pthread_t is a pointer type.
//
// Note the output should match what the stream operator does. Since
// the ostream operator has been shipped years before this formatter
// was added to the Standard, this formatter does what the stream
// operator does. This may require platform specific changes.
using _Tp = decltype(__get_underlying_id(__id));
using _Cp = conditional_t<integral<_Tp>, _Tp, conditional_t<is_pointer_v<_Tp>, uintptr_t, void>>;
static_assert(!is_same_v<_Cp, void>, "unsupported thread::id type, please file a bug report");
__format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
if constexpr (is_pointer_v<_Tp>) {
__specs.__std_.__alternate_form_ = true;
__specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case;
}
return __formatter::__format_integer(reinterpret_cast<_Cp>(__get_underlying_id(__id)), __ctx, __specs);
}
__format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right};
};
# endif // !_LIBCPP_HAS_NO_THREADS
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 23
#endif // _LIBCPP___THREAD_FORMATTER_H

121
third_party/libcxx/__thread/id.h vendored Normal file
View file

@ -0,0 +1,121 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___THREAD_ID_H
#define _LIBCPP___THREAD_ID_H
#include <__compare/ordering.h>
#include <__config>
#include <__fwd/functional.h>
#include <__fwd/ostream.h>
#include <__thread/support.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_HAS_NO_THREADS
class _LIBCPP_EXPORTED_FROM_ABI __thread_id;
namespace this_thread {
_LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT;
} // namespace this_thread
template <>
struct hash<__thread_id>;
class _LIBCPP_TEMPLATE_VIS __thread_id {
// FIXME: pthread_t is a pointer on Darwin but a long on Linux.
// NULL is the no-thread value on Darwin. Someone needs to check
// on other platforms. We assume 0 works everywhere for now.
__libcpp_thread_id __id_;
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_);
}
public:
_LIBCPP_HIDE_FROM_ABI __thread_id() _NOEXCEPT : __id_(0) {}
_LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
private:
_LIBCPP_HIDE_FROM_ABI __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_EXPORTED_FROM_ABI 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 {
inline _LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT { return __libcpp_thread_get_current_id(); }
} // namespace this_thread
#endif // !_LIBCPP_HAS_NO_THREADS
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___THREAD_ID_H

134
third_party/libcxx/__thread/jthread.h vendored Normal file
View file

@ -0,0 +1,134 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___THREAD_JTHREAD_H
#define _LIBCPP___THREAD_JTHREAD_H
#include <__config>
#include <__functional/invoke.h>
#include <__stop_token/stop_source.h>
#include <__stop_token/stop_token.h>
#include <__thread/support.h>
#include <__thread/thread.h>
#include <__type_traits/decay.h>
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_same.h>
#include <__type_traits/remove_cvref.h>
#include <__utility/forward.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
_LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_AVAILABILITY_SYNC jthread {
public:
// types
using id = thread::id;
using native_handle_type = thread::native_handle_type;
// [thread.jthread.cons], constructors, move, and assignment
_LIBCPP_HIDE_FROM_ABI jthread() noexcept : __stop_source_(std::nostopstate) {}
template <class _Fun, class... _Args>
_LIBCPP_HIDE_FROM_ABI explicit jthread(_Fun&& __fun, _Args&&... __args)
requires(!std::is_same_v<remove_cvref_t<_Fun>, jthread>)
: __stop_source_(),
__thread_(__init_thread(__stop_source_, std::forward<_Fun>(__fun), std::forward<_Args>(__args)...)) {
static_assert(is_constructible_v<decay_t<_Fun>, _Fun>);
static_assert((is_constructible_v<decay_t<_Args>, _Args> && ...));
static_assert(is_invocable_v<decay_t<_Fun>, decay_t<_Args>...> ||
is_invocable_v<decay_t<_Fun>, stop_token, decay_t<_Args>...>);
}
_LIBCPP_HIDE_FROM_ABI ~jthread() {
if (joinable()) {
request_stop();
join();
}
}
jthread(const jthread&) = delete;
_LIBCPP_HIDE_FROM_ABI jthread(jthread&&) noexcept = default;
jthread& operator=(const jthread&) = delete;
_LIBCPP_HIDE_FROM_ABI jthread& operator=(jthread&& __other) noexcept {
if (this != &__other) {
if (joinable()) {
request_stop();
join();
}
__stop_source_ = std::move(__other.__stop_source_);
__thread_ = std::move(__other.__thread_);
}
return *this;
}
// [thread.jthread.mem], members
_LIBCPP_HIDE_FROM_ABI void swap(jthread& __other) noexcept {
std::swap(__stop_source_, __other.__stop_source_);
std::swap(__thread_, __other.__thread_);
}
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool joinable() const noexcept { return get_id() != id(); }
_LIBCPP_HIDE_FROM_ABI void join() { __thread_.join(); }
_LIBCPP_HIDE_FROM_ABI void detach() { __thread_.detach(); }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI id get_id() const noexcept { return __thread_.get_id(); }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return __thread_.native_handle(); }
// [thread.jthread.stop], stop token handling
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI stop_source get_stop_source() noexcept { return __stop_source_; }
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI stop_token get_stop_token() const noexcept { return __stop_source_.get_token(); }
_LIBCPP_HIDE_FROM_ABI bool request_stop() noexcept { return __stop_source_.request_stop(); }
// [thread.jthread.special], specialized algorithms
_LIBCPP_HIDE_FROM_ABI friend void swap(jthread& __lhs, jthread& __rhs) noexcept { __lhs.swap(__rhs); }
// [thread.jthread.static], static members
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static unsigned int hardware_concurrency() noexcept {
return thread::hardware_concurrency();
}
private:
template <class _Fun, class... _Args>
_LIBCPP_HIDE_FROM_ABI static thread __init_thread(const stop_source& __ss, _Fun&& __fun, _Args&&... __args) {
if constexpr (is_invocable_v<decay_t<_Fun>, stop_token, decay_t<_Args>...>) {
return thread(std::forward<_Fun>(__fun), __ss.get_token(), std::forward<_Args>(__args)...);
} else {
return thread(std::forward<_Fun>(__fun), std::forward<_Args>(__args)...);
}
}
stop_source __stop_source_;
thread __thread_;
};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN)
_LIBCPP_POP_MACROS
#endif // _LIBCPP___THREAD_JTHREAD_H

View file

@ -10,7 +10,6 @@
#ifndef _LIBCPP___THREAD_POLL_WITH_BACKOFF_H
#define _LIBCPP___THREAD_POLL_WITH_BACKOFF_H
#include <__availability>
#include <__chrono/duration.h>
#include <__chrono/high_resolution_clock.h>
#include <__config>
@ -26,31 +25,31 @@ static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64;
// Polls a thread for a condition given by a predicate, and backs off based on a backoff policy
// before polling again.
//
// - __f is the "test function" that should return true if polling succeeded, and false if it failed.
// - __poll is the "test function" that should return true if polling succeeded, and false if it failed.
//
// - __bf is the "backoff policy", which is called with the duration since we started polling. It should
// - __backoff is the "backoff policy", which is called with the duration since we started polling. It should
// return false in order to resume polling, and true if polling should stop entirely for some reason.
// In general, backoff policies sleep for some time before returning control to the polling loop.
//
// - __max_elapsed is the maximum duration to try polling for. If the maximum duration is exceeded,
// the polling loop will return false to report a timeout.
template<class _Fn, class _BFn>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
bool __libcpp_thread_poll_with_backoff(_Fn&& __f, _BFn&& __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()) {
auto const __start = chrono::high_resolution_clock::now();
for (int __count = 0;;) {
if (__f())
return true; // _Fn completion means success
if (__count < __libcpp_polling_count) {
__count += 1;
continue;
}
chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start;
if (__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed)
return false; // timeout failure
if (__bf(__elapsed))
return false; // _BFn completion means failure
template <class _Poll, class _Backoff>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_poll_with_backoff(
_Poll&& __poll, _Backoff&& __backoff, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()) {
auto const __start = chrono::high_resolution_clock::now();
for (int __count = 0;;) {
if (__poll())
return true; // __poll completion means success
if (__count < __libcpp_polling_count) {
__count += 1;
continue;
}
chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start;
if (__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed)
return false; // timeout failure
if (__backoff(__elapsed))
return false; // __backoff completion means failure
}
}
// A trivial backoff policy that always immediately returns the control to
@ -60,10 +59,7 @@ bool __libcpp_thread_poll_with_backoff(_Fn&& __f, _BFn&& __bf, chrono::nanosecon
// so this should most likely only be used on single-threaded systems where there
// are no other threads to compete with.
struct __spinning_backoff_policy {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
bool operator()(chrono::nanoseconds const&) const {
return false;
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(chrono::nanoseconds const&) const { return false; }
};
_LIBCPP_END_NAMESPACE_STD

123
third_party/libcxx/__thread/support.h vendored Normal file
View file

@ -0,0 +1,123 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___THREAD_SUPPORT_H
#define _LIBCPP___THREAD_SUPPORT_H
#include <__config>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
# pragma GCC system_header
#endif
/*
//
// The library supports multiple implementations of the basic threading functionality.
// The following functionality must be provided by any implementation:
//
_LIBCPP_BEGIN_NAMESPACE_STD
using __libcpp_timespec_t = ...;
//
// Mutex
//
using __libcpp_mutex_t = ...;
#define _LIBCPP_MUTEX_INITIALIZER ...
using __libcpp_recursive_mutex_t = ...;
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t*);
_LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t*);
_LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t*);
_LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t*);
int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t*);
_LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_lock(__libcpp_mutex_t*);
_LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_mutex_trylock(__libcpp_mutex_t*);
_LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_unlock(__libcpp_mutex_t*);
int __libcpp_mutex_destroy(__libcpp_mutex_t*);
//
// Condition Variable
//
using __libcpp_condvar_t = ...;
#define _LIBCPP_CONDVAR_INITIALIZER ...
int __libcpp_condvar_signal(__libcpp_condvar_t*);
int __libcpp_condvar_broadcast(__libcpp_condvar_t*);
_LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_condvar_wait(__libcpp_condvar_t*, __libcpp_mutex_t*);
_LIBCPP_NO_THREAD_SAFETY_ANALYSIS
int __libcpp_condvar_timedwait(__libcpp_condvar_t*, __libcpp_mutex_t*, __libcpp_timespec_t*);
int __libcpp_condvar_destroy(__libcpp_condvar_t*);
//
// Execute once
//
using __libcpp_exec_once_flag = ...;
#define _LIBCPP_EXEC_ONCE_INITIALIZER ...
int __libcpp_execute_once(__libcpp_exec_once_flag*, void (*__init_routine)());
//
// Thread id
//
using __libcpp_thread_id = ...;
bool __libcpp_thread_id_equal(__libcpp_thread_id, __libcpp_thread_id);
bool __libcpp_thread_id_less(__libcpp_thread_id, __libcpp_thread_id);
//
// Thread
//
#define _LIBCPP_NULL_THREAD ...
using __libcpp_thread_t = ...;
bool __libcpp_thread_isnull(const __libcpp_thread_t*);
int __libcpp_thread_create(__libcpp_thread_t*, void* (*__func)(void*), void* __arg);
__libcpp_thread_id __libcpp_thread_get_current_id();
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t*);
int __libcpp_thread_join(__libcpp_thread_t*);
int __libcpp_thread_detach(__libcpp_thread_t*);
void __libcpp_thread_yield();
void __libcpp_thread_sleep_for(const chrono::nanoseconds&);
//
// Thread local storage
//
#define _LIBCPP_TLS_DESTRUCTOR_CC ...
using __libcpp_tls_key = ...;
int __libcpp_tls_create(__libcpp_tls_key*, void (*__at_exit)(void*));
void* __libcpp_tls_get(__libcpp_tls_key);
int __libcpp_tls_set(__libcpp_tls_key, void*);
_LIBCPP_END_NAMESPACE_STD
*/
#if !defined(_LIBCPP_HAS_NO_THREADS)
# if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
// # include <__thread/support/external.h>
# elif defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
# include <__thread/support/pthread.h>
# elif defined(_LIBCPP_HAS_THREAD_API_C11)
// # include <__thread/support/c11.h>
# elif defined(_LIBCPP_HAS_THREAD_API_WIN32)
// # include <__thread/support/windows.h>
# else
# error "No threading API was selected"
# endif
#endif // !_LIBCPP_HAS_NO_THREADS
#endif // _LIBCPP___THREAD_SUPPORT_H

View file

@ -0,0 +1,217 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___THREAD_SUPPORT_PTHREAD_H
#define _LIBCPP___THREAD_SUPPORT_PTHREAD_H
#include <__chrono/convert_to_timespec.h>
#include <__chrono/duration.h>
#include <__config>
#include <ctime>
#include <errno.h>
#include <pthread.h>
#include <sched.h>
// Some platforms require <bits/atomic_wide_counter.h> in order for
// PTHREAD_COND_INITIALIZER to be expanded. Normally that would come
// in via <pthread.h>, but it's a non-modular header on those platforms,
// so libc++'s <math.h> usually absorbs atomic_wide_counter.h into the
// module with <math.h> and makes atomic_wide_counter.h invisible.
// Include <math.h> here to work around that.
// This checks wheter a Clang module is built
#if __building_module(std)
# include <math.h>
#endif
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
using __libcpp_timespec_t = ::timespec;
//
// Mutex
//
typedef pthread_mutex_t __libcpp_mutex_t;
#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t __libcpp_recursive_mutex_t;
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t* __m) {
pthread_mutexattr_t __attr;
int __ec = pthread_mutexattr_init(&__attr);
if (__ec)
return __ec;
__ec = pthread_mutexattr_settype(&__attr, PTHREAD_MUTEX_RECURSIVE);
if (__ec) {
pthread_mutexattr_destroy(&__attr);
return __ec;
}
__ec = pthread_mutex_init(__m, &__attr);
if (__ec) {
pthread_mutexattr_destroy(&__attr);
return __ec;
}
__ec = pthread_mutexattr_destroy(&__attr);
if (__ec) {
pthread_mutex_destroy(__m);
return __ec;
}
return 0;
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
__libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t* __m) {
return pthread_mutex_lock(__m);
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool
__libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t* __m) {
return pthread_mutex_trylock(__m) == 0;
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
__libcpp_recursive_mutex_unlock(__libcpp_recursive_mutex_t* __m) {
return pthread_mutex_unlock(__m);
}
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t* __m) {
return pthread_mutex_destroy(__m);
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_lock(__libcpp_mutex_t* __m) {
return pthread_mutex_lock(__m);
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS bool __libcpp_mutex_trylock(__libcpp_mutex_t* __m) {
return pthread_mutex_trylock(__m) == 0;
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) {
return pthread_mutex_unlock(__m);
}
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_mutex_destroy(__libcpp_mutex_t* __m) { return pthread_mutex_destroy(__m); }
//
// Condition Variable
//
typedef pthread_cond_t __libcpp_condvar_t;
#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_signal(__libcpp_condvar_t* __cv) { return pthread_cond_signal(__cv); }
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv) {
return pthread_cond_broadcast(__cv);
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
__libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m) {
return pthread_cond_wait(__cv, __m);
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_THREAD_SAFETY_ANALYSIS int
__libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, __libcpp_timespec_t* __ts) {
return pthread_cond_timedwait(__cv, __m, __ts);
}
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv) {
return pthread_cond_destroy(__cv);
}
//
// Execute once
//
typedef pthread_once_t __libcpp_exec_once_flag;
#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_execute_once(__libcpp_exec_once_flag* __flag, void (*__init_routine)()) {
return pthread_once(__flag, __init_routine);
}
//
// Thread id
//
#if defined(__MVS__)
typedef unsigned long long __libcpp_thread_id;
#else
typedef pthread_t __libcpp_thread_id;
#endif
// Returns non-zero if the thread ids are equal, otherwise 0
inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_id_equal(__libcpp_thread_id __t1, __libcpp_thread_id __t2) {
return __t1 == __t2;
}
// Returns non-zero if t1 < t2, otherwise 0
inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_id_less(__libcpp_thread_id __t1, __libcpp_thread_id __t2) {
return __t1 < __t2;
}
//
// Thread
//
#define _LIBCPP_NULL_THREAD ((__libcpp_thread_t()))
typedef pthread_t __libcpp_thread_t;
inline _LIBCPP_HIDE_FROM_ABI __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t) {
#if defined(__MVS__)
return __t->__;
#else
return *__t;
#endif
}
inline _LIBCPP_HIDE_FROM_ABI bool __libcpp_thread_isnull(const __libcpp_thread_t* __t) {
return __libcpp_thread_get_id(__t) == 0;
}
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg) {
return pthread_create(__t, nullptr, __func, __arg);
}
inline _LIBCPP_HIDE_FROM_ABI __libcpp_thread_id __libcpp_thread_get_current_id() {
const __libcpp_thread_t __current_thread = pthread_self();
return __libcpp_thread_get_id(&__current_thread);
}
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_thread_join(__libcpp_thread_t* __t) { return pthread_join(*__t, nullptr); }
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_thread_detach(__libcpp_thread_t* __t) { return pthread_detach(*__t); }
inline _LIBCPP_HIDE_FROM_ABI void __libcpp_thread_yield() { sched_yield(); }
inline _LIBCPP_HIDE_FROM_ABI void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) {
__libcpp_timespec_t __ts = std::__convert_to_timespec<__libcpp_timespec_t>(__ns);
while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR)
;
}
//
// Thread local storage
//
#define _LIBCPP_TLS_DESTRUCTOR_CC /* nothing */
typedef pthread_key_t __libcpp_tls_key;
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*)) {
return pthread_key_create(__key, __at_exit);
}
inline _LIBCPP_HIDE_FROM_ABI void* __libcpp_tls_get(__libcpp_tls_key __key) { return pthread_getspecific(__key); }
inline _LIBCPP_HIDE_FROM_ABI int __libcpp_tls_set(__libcpp_tls_key __key, void* __p) {
return pthread_setspecific(__key, __p);
}
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___THREAD_SUPPORT_PTHREAD_H

View file

@ -0,0 +1,74 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___THREAD_THIS_THREAD_H
#define _LIBCPP___THREAD_THIS_THREAD_H
#include <__chrono/steady_clock.h>
#include <__chrono/time_point.h>
#include <__condition_variable/condition_variable.h>
#include <__config>
#include <__mutex/mutex.h>
#include <__mutex/unique_lock.h>
#include <__thread/support.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
namespace this_thread {
_LIBCPP_EXPORTED_FROM_ABI void sleep_for(const chrono::nanoseconds& __ns);
template <class _Rep, class _Period>
_LIBCPP_HIDE_FROM_ABI void sleep_for(const chrono::duration<_Rep, _Period>& __d) {
if (__d > chrono::duration<_Rep, _Period>::zero()) {
// The standard guarantees a 64bit signed integer resolution for nanoseconds,
// so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits>
// and issues with long double folding on PowerPC with GCC.
_LIBCPP_CONSTEXPR chrono::duration<long double> __max = chrono::duration<long double>(9223372036.0L);
chrono::nanoseconds __ns;
if (__d < __max) {
__ns = chrono::duration_cast<chrono::nanoseconds>(__d);
if (__ns < __d)
++__ns;
} else
__ns = chrono::nanoseconds::max();
this_thread::sleep_for(__ns);
}
}
template <class _Clock, class _Duration>
_LIBCPP_HIDE_FROM_ABI void sleep_until(const chrono::time_point<_Clock, _Duration>& __t) {
mutex __mut;
condition_variable __cv;
unique_lock<mutex> __lk(__mut);
while (_Clock::now() < __t)
__cv.wait_until(__lk, __t);
}
template <class _Duration>
inline _LIBCPP_HIDE_FROM_ABI void sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) {
this_thread::sleep_for(__t - chrono::steady_clock::now());
}
inline _LIBCPP_HIDE_FROM_ABI void yield() _NOEXCEPT { __libcpp_thread_yield(); }
} // namespace this_thread
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___THREAD_THIS_THREAD_H

258
third_party/libcxx/__thread/thread.h vendored Normal file
View file

@ -0,0 +1,258 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___THREAD_THREAD_H
#define _LIBCPP___THREAD_THREAD_H
#include <__condition_variable/condition_variable.h>
#include <__config>
#include <__exception/terminate.h>
#include <__functional/hash.h>
#include <__functional/unary_function.h>
#include <__memory/unique_ptr.h>
#include <__mutex/mutex.h>
#include <__system_error/system_error.h>
#include <__thread/id.h>
#include <__thread/support.h>
#include <__utility/forward.h>
#include <tuple>
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
# include <locale>
# include <sstream>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
class __thread_specific_ptr;
class _LIBCPP_EXPORTED_FROM_ABI __thread_struct;
class _LIBCPP_HIDDEN __thread_struct_imp;
class __assoc_sub_state;
_LIBCPP_EXPORTED_FROM_ABI __thread_specific_ptr<__thread_struct>& __thread_local_data();
class _LIBCPP_EXPORTED_FROM_ABI __thread_struct {
__thread_struct_imp* __p_;
__thread_struct(const __thread_struct&);
__thread_struct& operator=(const __thread_struct&);
public:
__thread_struct();
~__thread_struct();
void notify_all_at_thread_exit(condition_variable*, mutex*);
void __make_ready_at_thread_exit(__assoc_sub_state*);
};
template <class _Tp>
class __thread_specific_ptr {
__libcpp_tls_key __key_;
// Only __thread_local_data() may construct a __thread_specific_ptr
// and only with _Tp == __thread_struct.
static_assert(is_same<_Tp, __thread_struct>::value, "");
__thread_specific_ptr();
friend _LIBCPP_EXPORTED_FROM_ABI __thread_specific_ptr<__thread_struct>& __thread_local_data();
_LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*);
public:
typedef _Tp* pointer;
__thread_specific_ptr(const __thread_specific_ptr&) = delete;
__thread_specific_ptr& operator=(const __thread_specific_ptr&) = delete;
~__thread_specific_ptr();
_LIBCPP_HIDE_FROM_ABI pointer get() const { return static_cast<_Tp*>(__libcpp_tls_get(__key_)); }
_LIBCPP_HIDE_FROM_ABI pointer operator*() const { return *get(); }
_LIBCPP_HIDE_FROM_ABI pointer operator->() const { return get(); }
void set_pointer(pointer __p);
};
template <class _Tp>
void _LIBCPP_TLS_DESTRUCTOR_CC __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) {
delete static_cast<pointer>(__p);
}
template <class _Tp>
__thread_specific_ptr<_Tp>::__thread_specific_ptr() {
int __ec = __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit);
if (__ec)
__throw_system_error(__ec, "__thread_specific_ptr construction failed");
}
template <class _Tp>
__thread_specific_ptr<_Tp>::~__thread_specific_ptr() {
// __thread_specific_ptr is only created with a static storage duration
// so this destructor is only invoked during program termination. Invoking
// pthread_key_delete(__key_) may prevent other threads from deleting their
// thread local data. For this reason we leak the key.
}
template <class _Tp>
void __thread_specific_ptr<_Tp>::set_pointer(pointer __p) {
_LIBCPP_ASSERT_INTERNAL(get() == nullptr, "Attempting to overwrite thread local data");
std::__libcpp_tls_set(__key_, __p);
}
template <>
struct _LIBCPP_TEMPLATE_VIS hash<__thread_id> : public __unary_function<__thread_id, size_t> {
_LIBCPP_HIDE_FROM_ABI size_t operator()(__thread_id __v) const _NOEXCEPT {
return hash<__libcpp_thread_id>()(__v.__id_);
}
};
#ifndef _LIBCPP_HAS_NO_LOCALIZATION
template <class _CharT, class _Traits>
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) {
// [thread.thread.id]/9
// Effects: Inserts the text representation for charT of id into out.
//
// [thread.thread.id]/2
// The text representation for the character type charT of an
// object of type thread::id is an unspecified sequence of charT
// such that, for two objects of type thread::id x and y, if
// x == y is true, the thread::id objects have the same text
// representation, and if x != y is true, the thread::id objects
// have distinct text representations.
//
// Since various flags in the output stream can affect how the
// thread id is represented (e.g. numpunct or showbase), we
// use a temporary stream instead and just output the thread
// id representation as a string.
basic_ostringstream<_CharT, _Traits> __sstr;
__sstr.imbue(locale::classic());
__sstr << __id.__id_;
return __os << __sstr.str();
}
#endif // _LIBCPP_HAS_NO_LOCALIZATION
class _LIBCPP_EXPORTED_FROM_ABI thread {
__libcpp_thread_t __t_;
thread(const thread&);
thread& operator=(const thread&);
public:
typedef __thread_id id;
typedef __libcpp_thread_t native_handle_type;
_LIBCPP_HIDE_FROM_ABI thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
#ifndef _LIBCPP_CXX03_LANG
template <class _Fp, class... _Args, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value, int> = 0>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit thread(_Fp&& __f, _Args&&... __args);
#else // _LIBCPP_CXX03_LANG
template <class _Fp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit thread(_Fp __f);
#endif
~thread();
_LIBCPP_HIDE_FROM_ABI thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) { __t.__t_ = _LIBCPP_NULL_THREAD; }
_LIBCPP_HIDE_FROM_ABI thread& operator=(thread&& __t) _NOEXCEPT {
if (!__libcpp_thread_isnull(&__t_))
terminate();
__t_ = __t.__t_;
__t.__t_ = _LIBCPP_NULL_THREAD;
return *this;
}
_LIBCPP_HIDE_FROM_ABI void swap(thread& __t) _NOEXCEPT { std::swap(__t_, __t.__t_); }
_LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); }
void join();
void detach();
_LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); }
_LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }
static unsigned hardware_concurrency() _NOEXCEPT;
};
#ifndef _LIBCPP_CXX03_LANG
template <class _TSp, class _Fp, class... _Args, size_t... _Indices>
inline _LIBCPP_HIDE_FROM_ABI void __thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>) {
std::__invoke(std::move(std::get<1>(__t)), std::move(std::get<_Indices>(__t))...);
}
template <class _Fp>
_LIBCPP_HIDE_FROM_ABI void* __thread_proxy(void* __vp) {
// _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...>
unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
__thread_local_data().set_pointer(std::get<0>(*__p.get()).release());
typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index;
std::__thread_execute(*__p.get(), _Index());
return nullptr;
}
template <class _Fp, class... _Args, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value, int> >
thread::thread(_Fp&& __f, _Args&&... __args) {
typedef unique_ptr<__thread_struct> _TSPtr;
_TSPtr __tsp(new __thread_struct);
typedef tuple<_TSPtr, __decay_t<_Fp>, __decay_t<_Args>...> _Gp;
unique_ptr<_Gp> __p(new _Gp(std::move(__tsp), std::forward<_Fp>(__f), std::forward<_Args>(__args)...));
int __ec = std::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
if (__ec == 0)
__p.release();
else
__throw_system_error(__ec, "thread constructor failed");
}
#else // _LIBCPP_CXX03_LANG
template <class _Fp>
struct __thread_invoke_pair {
// This type is used to pass memory for thread local storage and a functor
// to a newly created thread because std::pair doesn't work with
// std::unique_ptr in C++03.
_LIBCPP_HIDE_FROM_ABI __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {}
unique_ptr<__thread_struct> __tsp_;
_Fp __fn_;
};
template <class _Fp>
_LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp) {
unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp));
__thread_local_data().set_pointer(__p->__tsp_.release());
(__p->__fn_)();
return nullptr;
}
template <class _Fp>
thread::thread(_Fp __f) {
typedef __thread_invoke_pair<_Fp> _InvokePair;
typedef unique_ptr<_InvokePair> _PairPtr;
_PairPtr __pp(new _InvokePair(__f));
int __ec = std::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
if (__ec == 0)
__pp.release();
else
__throw_system_error(__ec, "thread constructor failed");
}
#endif // _LIBCPP_CXX03_LANG
inline _LIBCPP_HIDE_FROM_ABI void swap(thread& __x, thread& __y) _NOEXCEPT { __x.swap(__y); }
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___THREAD_THREAD_H

View file

@ -15,27 +15,25 @@
#ifndef _LIBCPP_HAS_NO_THREADS
# include <__chrono/duration.h>
# include <__threading_support>
# include <__thread/support.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
# endif
_LIBCPP_BEGIN_NAMESPACE_STD
struct __libcpp_timed_backoff_policy {
_LIBCPP_INLINE_VISIBILITY
bool operator()(chrono::nanoseconds __elapsed) const
{
if(__elapsed > chrono::milliseconds(128))
__libcpp_thread_sleep_for(chrono::milliseconds(8));
else if(__elapsed > chrono::microseconds(64))
__libcpp_thread_sleep_for(__elapsed / 2);
else if(__elapsed > chrono::microseconds(4))
__libcpp_thread_yield();
else
{} // poll
return false;
_LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const {
if (__elapsed > chrono::milliseconds(128))
__libcpp_thread_sleep_for(chrono::milliseconds(8));
else if (__elapsed > chrono::microseconds(64))
__libcpp_thread_sleep_for(__elapsed / 2);
else if (__elapsed > chrono::microseconds(4))
__libcpp_thread_yield();
else {
} // poll
return false;
}
};