mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 07:18:30 +00:00
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:
parent
62ace3623a
commit
5660ec4741
1585 changed files with 117353 additions and 271644 deletions
52
third_party/libcxx/__atomic/aliases.h
vendored
52
third_party/libcxx/__atomic/aliases.h
vendored
|
@ -15,9 +15,9 @@
|
|||
#include <__atomic/is_always_lock_free.h>
|
||||
#include <__config>
|
||||
#include <__type_traits/conditional.h>
|
||||
#include <__type_traits/make_unsigned.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
|
@ -80,36 +80,30 @@ using atomic_ptrdiff_t = atomic<ptrdiff_t>;
|
|||
using atomic_intmax_t = atomic<intmax_t>;
|
||||
using atomic_uintmax_t = atomic<uintmax_t>;
|
||||
|
||||
// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
|
||||
// C++20 atomic_{signed,unsigned}_lock_free: prefer the contention type most highly, then the largest lock-free type
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
# if ATOMIC_LLONG_LOCK_FREE == 2
|
||||
using __largest_lock_free_type = long long;
|
||||
# elif ATOMIC_INT_LOCK_FREE == 2
|
||||
using __largest_lock_free_type = int;
|
||||
# elif ATOMIC_SHORT_LOCK_FREE == 2
|
||||
using __largest_lock_free_type = short;
|
||||
# elif ATOMIC_CHAR_LOCK_FREE == 2
|
||||
using __largest_lock_free_type = char;
|
||||
# else
|
||||
# define _LIBCPP_NO_LOCK_FREE_TYPES // There are no lockfree types (this can happen on unusual platforms)
|
||||
# endif
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
# define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value
|
||||
#else
|
||||
# define _LIBCPP_CONTENTION_LOCK_FREE false
|
||||
#endif
|
||||
# ifndef _LIBCPP_NO_LOCK_FREE_TYPES
|
||||
using __contention_t_or_largest =
|
||||
__conditional_t<__libcpp_is_always_lock_free<__cxx_contention_t>::__value,
|
||||
__cxx_contention_t,
|
||||
__largest_lock_free_type>;
|
||||
|
||||
#if ATOMIC_LLONG_LOCK_FREE == 2
|
||||
using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>;
|
||||
using __libcpp_unsigned_lock_free =
|
||||
__conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>;
|
||||
#elif ATOMIC_INT_LOCK_FREE == 2
|
||||
using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>;
|
||||
using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>;
|
||||
#elif ATOMIC_SHORT_LOCK_FREE == 2
|
||||
using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>;
|
||||
using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>;
|
||||
#elif ATOMIC_CHAR_LOCK_FREE == 2
|
||||
using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>;
|
||||
using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>;
|
||||
#else
|
||||
// No signed/unsigned lock-free types
|
||||
# define _LIBCPP_NO_LOCK_FREE_TYPES
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES)
|
||||
using atomic_signed_lock_free = atomic<__libcpp_signed_lock_free>;
|
||||
using atomic_unsigned_lock_free = atomic<__libcpp_unsigned_lock_free>;
|
||||
#endif
|
||||
using atomic_signed_lock_free = atomic<__contention_t_or_largest>;
|
||||
using atomic_unsigned_lock_free = atomic<make_unsigned_t<__contention_t_or_largest>>;
|
||||
# endif // !_LIBCPP_NO_LOCK_FREE_TYPES
|
||||
#endif // C++20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
|
778
third_party/libcxx/__atomic/atomic.h
vendored
778
third_party/libcxx/__atomic/atomic.h
vendored
File diff suppressed because it is too large
Load diff
343
third_party/libcxx/__atomic/atomic_base.h
vendored
343
third_party/libcxx/__atomic/atomic_base.h
vendored
|
@ -14,11 +14,10 @@
|
|||
#include <__atomic/cxx_atomic_impl.h>
|
||||
#include <__atomic/is_always_lock_free.h>
|
||||
#include <__atomic/memory_order.h>
|
||||
#include <__availability>
|
||||
#include <__config>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__type_traits/is_integral.h>
|
||||
#include <__type_traits/is_nothrow_default_constructible.h>
|
||||
#include <__type_traits/is_nothrow_constructible.h>
|
||||
#include <__type_traits/is_same.h>
|
||||
#include <version>
|
||||
|
||||
|
@ -29,202 +28,192 @@
|
|||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
|
||||
struct __atomic_base // false
|
||||
struct __atomic_base // false
|
||||
{
|
||||
mutable __cxx_atomic_impl<_Tp> __a_;
|
||||
mutable __cxx_atomic_impl<_Tp> __a_;
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
|
||||
static constexpr bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
|
||||
#endif
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
bool is_lock_free() const volatile _NOEXCEPT
|
||||
{return __cxx_atomic_is_lock_free(sizeof(_Tp));}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
bool is_lock_free() const _NOEXCEPT
|
||||
{return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
|
||||
_LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
|
||||
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
|
||||
std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
|
||||
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
|
||||
std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
|
||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
||||
return std::__cxx_atomic_load(std::addressof(__a_), __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
|
||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
||||
return std::__cxx_atomic_load(std::addressof(__a_), __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
operator _Tp() const volatile _NOEXCEPT {return load();}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
operator _Tp() const _NOEXCEPT {return load();}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
|
||||
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
|
||||
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
|
||||
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
|
||||
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool is_lock_free() const volatile _NOEXCEPT {
|
||||
return __cxx_atomic_is_lock_free(sizeof(__cxx_atomic_impl<_Tp>));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool is_lock_free() const _NOEXCEPT {
|
||||
return static_cast<__atomic_base const volatile*>(this)->is_lock_free();
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
|
||||
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
|
||||
std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
|
||||
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
|
||||
std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
|
||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
||||
return std::__cxx_atomic_load(std::addressof(__a_), __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
|
||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
|
||||
return std::__cxx_atomic_load(std::addressof(__a_), __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI operator _Tp() const volatile _NOEXCEPT { return load(); }
|
||||
_LIBCPP_HIDE_FROM_ABI operator _Tp() const _NOEXCEPT { return load(); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
|
||||
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
|
||||
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
|
||||
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
|
||||
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
|
||||
}
|
||||
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const
|
||||
volatile _NOEXCEPT {
|
||||
std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
||||
wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
|
||||
std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
|
||||
std::__cxx_atomic_notify_one(std::addressof(__a_));
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT {
|
||||
std::__cxx_atomic_notify_one(std::addressof(__a_));
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
|
||||
std::__cxx_atomic_notify_all(std::addressof(__a_));
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT {
|
||||
std::__cxx_atomic_notify_all(std::addressof(__a_));
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const
|
||||
volatile _NOEXCEPT {
|
||||
std::__atomic_wait(*this, __v, __m);
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
||||
wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
|
||||
std::__atomic_wait(*this, __v, __m);
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
|
||||
std::__atomic_notify_one(*this);
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
|
||||
std::__atomic_notify_all(*this);
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
__atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
|
||||
#else
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__atomic_base() _NOEXCEPT = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __atomic_base() _NOEXCEPT = default;
|
||||
#endif
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
|
||||
__atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
|
||||
|
||||
__atomic_base(const __atomic_base&) = delete;
|
||||
__atomic_base(const __atomic_base&) = delete;
|
||||
};
|
||||
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
template <class _Tp, bool __b>
|
||||
_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
|
||||
#endif
|
||||
|
||||
// atomic<Integral>
|
||||
|
||||
template <class _Tp>
|
||||
struct __atomic_base<_Tp, true>
|
||||
: public __atomic_base<_Tp, false>
|
||||
{
|
||||
using __base = __atomic_base<_Tp, false>;
|
||||
struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> {
|
||||
using __base = __atomic_base<_Tp, false>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
|
||||
__atomic_base() _NOEXCEPT = default;
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __atomic_base() _NOEXCEPT = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator++(int) volatile _NOEXCEPT { return fetch_add(_Tp(1)); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator++(int) _NOEXCEPT { return fetch_add(_Tp(1)); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator--(int) volatile _NOEXCEPT { return fetch_sub(_Tp(1)); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator--(int) _NOEXCEPT { return fetch_sub(_Tp(1)); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator++() volatile _NOEXCEPT { return fetch_add(_Tp(1)) + _Tp(1); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator++() _NOEXCEPT { return fetch_add(_Tp(1)) + _Tp(1); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator--() volatile _NOEXCEPT { return fetch_sub(_Tp(1)) - _Tp(1); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator--() _NOEXCEPT { return fetch_sub(_Tp(1)) - _Tp(1); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) volatile _NOEXCEPT { return fetch_add(__op) + __op; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) _NOEXCEPT { return fetch_add(__op) + __op; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) volatile _NOEXCEPT { return fetch_sub(__op) - __op; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) _NOEXCEPT { return fetch_sub(__op) - __op; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __op) volatile _NOEXCEPT { return fetch_and(__op) & __op; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __op) _NOEXCEPT { return fetch_and(__op) & __op; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __op) volatile _NOEXCEPT { return fetch_or(__op) | __op; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __op) _NOEXCEPT { return fetch_or(__op) | __op; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) volatile _NOEXCEPT { return fetch_xor(__op) ^ __op; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) _NOEXCEPT { return fetch_xor(__op) ^ __op; }
|
||||
};
|
||||
|
||||
// Here we need _IsIntegral because the default template argument is not enough
|
||||
// e.g __atomic_base<int> is __atomic_base<int, true>, which inherits from
|
||||
// __atomic_base<int, false> and the caller of the wait function is
|
||||
// __atomic_base<int, false>. So specializing __atomic_base<_Tp> does not work
|
||||
template <class _Tp, bool _IsIntegral>
|
||||
struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > {
|
||||
static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_base<_Tp, _IsIntegral>& __a, memory_order __order) {
|
||||
return __a.load(__order);
|
||||
}
|
||||
|
||||
static _LIBCPP_HIDE_FROM_ABI _Tp
|
||||
__atomic_load(const volatile __atomic_base<_Tp, _IsIntegral>& __this, memory_order __order) {
|
||||
return __this.load(__order);
|
||||
}
|
||||
|
||||
static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_Tp>*
|
||||
__atomic_contention_address(const __atomic_base<_Tp, _IsIntegral>& __a) {
|
||||
return std::addressof(__a.__a_);
|
||||
}
|
||||
|
||||
static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_Tp>*
|
||||
__atomic_contention_address(const volatile __atomic_base<_Tp, _IsIntegral>& __this) {
|
||||
return std::addressof(__this.__a_);
|
||||
}
|
||||
};
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
|
281
third_party/libcxx/__atomic/atomic_flag.h
vendored
281
third_party/libcxx/__atomic/atomic_flag.h
vendored
|
@ -15,7 +15,8 @@
|
|||
#include <__atomic/memory_order.h>
|
||||
#include <__chrono/duration.h>
|
||||
#include <__config>
|
||||
#include <__threading_support>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__thread/support.h>
|
||||
#include <cstdint>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
|
@ -24,205 +25,163 @@
|
|||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
struct atomic_flag
|
||||
{
|
||||
__cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
|
||||
struct atomic_flag {
|
||||
__cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
|
||||
{return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
|
||||
{return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
|
||||
_LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
|
||||
return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
|
||||
return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
|
||||
{return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
|
||||
{return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
|
||||
{__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
|
||||
{__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
|
||||
_LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
|
||||
__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT {
|
||||
__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);
|
||||
}
|
||||
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
|
||||
void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
|
||||
{__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
|
||||
void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
|
||||
{__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
|
||||
void notify_one() volatile _NOEXCEPT
|
||||
{__cxx_atomic_notify_one(&__a_);}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
|
||||
void notify_one() _NOEXCEPT
|
||||
{__cxx_atomic_notify_one(&__a_);}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
|
||||
void notify_all() volatile _NOEXCEPT
|
||||
{__cxx_atomic_notify_all(&__a_);}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
|
||||
void notify_all() _NOEXCEPT
|
||||
{__cxx_atomic_notify_all(&__a_);}
|
||||
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
||||
wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT {
|
||||
std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
|
||||
}
|
||||
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
||||
wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
|
||||
std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);
|
||||
}
|
||||
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
|
||||
std::__atomic_notify_one(*this);
|
||||
}
|
||||
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT {
|
||||
std::__atomic_notify_one(*this);
|
||||
}
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
|
||||
std::__atomic_notify_all(*this);
|
||||
}
|
||||
_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT {
|
||||
std::__atomic_notify_all(*this);
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr
|
||||
atomic_flag() _NOEXCEPT : __a_(false) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {}
|
||||
#else
|
||||
atomic_flag() _NOEXCEPT = default;
|
||||
atomic_flag() _NOEXCEPT = default;
|
||||
#endif
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
|
||||
atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
|
||||
|
||||
atomic_flag(const atomic_flag&) = delete;
|
||||
atomic_flag& operator=(const atomic_flag&) = delete;
|
||||
atomic_flag& operator=(const atomic_flag&) volatile = delete;
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
|
||||
|
||||
atomic_flag(const atomic_flag&) = delete;
|
||||
atomic_flag& operator=(const atomic_flag&) = delete;
|
||||
atomic_flag& operator=(const atomic_flag&) volatile = delete;
|
||||
};
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool
|
||||
atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
|
||||
{
|
||||
return __o->test();
|
||||
template <>
|
||||
struct __atomic_waitable_traits<atomic_flag> {
|
||||
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) {
|
||||
return std::__cxx_atomic_load(&__a.__a_, __order);
|
||||
}
|
||||
|
||||
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE
|
||||
__atomic_load(const volatile atomic_flag& __a, memory_order __order) {
|
||||
return std::__cxx_atomic_load(&__a.__a_, __order);
|
||||
}
|
||||
|
||||
static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
|
||||
__atomic_contention_address(const atomic_flag& __a) {
|
||||
return std::addressof(__a.__a_);
|
||||
}
|
||||
|
||||
static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>*
|
||||
__atomic_contention_address(const volatile atomic_flag& __a) {
|
||||
return std::addressof(__a.__a_);
|
||||
}
|
||||
};
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); }
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const atomic_flag* __o) _NOEXCEPT { return __o->test(); }
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool
|
||||
atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
|
||||
return __o->test(__m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool
|
||||
atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
|
||||
{
|
||||
return __o->test();
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT {
|
||||
return __o->test(__m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool
|
||||
atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->test(__m);
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT {
|
||||
return __o->test_and_set();
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool
|
||||
atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->test(__m);
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT { return __o->test_and_set(); }
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool
|
||||
atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
|
||||
return __o->test_and_set(__m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool
|
||||
atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
|
||||
{
|
||||
return __o->test_and_set();
|
||||
inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
|
||||
return __o->test_and_set(__m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool
|
||||
atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
|
||||
{
|
||||
return __o->test_and_set();
|
||||
inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); }
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); }
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT {
|
||||
__o->clear(__m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool
|
||||
atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->test_and_set(__m);
|
||||
inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT {
|
||||
__o->clear(__m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
bool
|
||||
atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->test_and_set(__m);
|
||||
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
||||
atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT {
|
||||
__o->wait(__v);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
void
|
||||
atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
|
||||
{
|
||||
__o->clear();
|
||||
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
||||
atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT {
|
||||
__o->wait(__v);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
void
|
||||
atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
|
||||
{
|
||||
__o->clear();
|
||||
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
||||
atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
|
||||
__o->wait(__v, __m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
void
|
||||
atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
__o->clear(__m);
|
||||
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
||||
atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT {
|
||||
__o->wait(__v, __m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
void
|
||||
atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
__o->clear(__m);
|
||||
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
||||
atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT {
|
||||
__o->notify_one();
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
|
||||
void
|
||||
atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
|
||||
{
|
||||
__o->wait(__v);
|
||||
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
||||
atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT {
|
||||
__o->notify_one();
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
|
||||
void
|
||||
atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
|
||||
{
|
||||
__o->wait(__v);
|
||||
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
||||
atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT {
|
||||
__o->notify_all();
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
|
||||
void
|
||||
atomic_flag_wait_explicit(const volatile atomic_flag* __o,
|
||||
bool __v, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
__o->wait(__v, __m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
|
||||
void
|
||||
atomic_flag_wait_explicit(const atomic_flag* __o,
|
||||
bool __v, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
__o->wait(__v, __m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
|
||||
void
|
||||
atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
|
||||
{
|
||||
__o->notify_one();
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
|
||||
void
|
||||
atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
|
||||
{
|
||||
__o->notify_one();
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
|
||||
void
|
||||
atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
|
||||
{
|
||||
__o->notify_all();
|
||||
}
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC
|
||||
void
|
||||
atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
|
||||
{
|
||||
__o->notify_all();
|
||||
inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void
|
||||
atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT {
|
||||
__o->notify_all();
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
|
6
third_party/libcxx/__atomic/atomic_init.h
vendored
6
third_party/libcxx/__atomic/atomic_init.h
vendored
|
@ -18,10 +18,8 @@
|
|||
#define ATOMIC_FLAG_INIT {false}
|
||||
#define ATOMIC_VAR_INIT(__v) {__v}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
|
||||
# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
|
||||
#if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
|
||||
# pragma clang deprecated(ATOMIC_VAR_INIT)
|
||||
# endif
|
||||
#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
|
||||
#endif
|
||||
|
||||
#endif // _LIBCPP___ATOMIC_ATOMIC_INIT_H
|
||||
|
|
52
third_party/libcxx/__atomic/atomic_lock_free.h
vendored
52
third_party/libcxx/__atomic/atomic_lock_free.h
vendored
|
@ -16,33 +16,33 @@
|
|||
#endif
|
||||
|
||||
#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
|
||||
# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
|
||||
# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
|
||||
#ifndef _LIBCPP_HAS_NO_CHAR8_T
|
||||
# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
|
||||
#endif
|
||||
# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
|
||||
# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
|
||||
# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
|
||||
# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
|
||||
# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
|
||||
# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
|
||||
# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
|
||||
# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
|
||||
# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
|
||||
# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
|
||||
# ifndef _LIBCPP_HAS_NO_CHAR8_T
|
||||
# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
|
||||
# endif
|
||||
# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
|
||||
# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
|
||||
# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
|
||||
# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
|
||||
# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
|
||||
# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
|
||||
# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
|
||||
# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
|
||||
#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
|
||||
# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
|
||||
# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
|
||||
#ifndef _LIBCPP_HAS_NO_CHAR8_T
|
||||
# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
|
||||
#endif
|
||||
# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
|
||||
# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
|
||||
# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
|
||||
# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
|
||||
# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
|
||||
# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
|
||||
# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
|
||||
# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
|
||||
# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
|
||||
# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
|
||||
# ifndef _LIBCPP_HAS_NO_CHAR8_T
|
||||
# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
|
||||
# endif
|
||||
# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
|
||||
# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
|
||||
# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
|
||||
# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
|
||||
# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
|
||||
# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
|
||||
# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
|
||||
# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
|
||||
#endif
|
||||
|
||||
#endif // _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H
|
||||
|
|
360
third_party/libcxx/__atomic/atomic_ref.h
vendored
Normal file
360
third_party/libcxx/__atomic/atomic_ref.h
vendored
Normal file
|
@ -0,0 +1,360 @@
|
|||
// -*- 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
|
||||
//
|
||||
// Kokkos v. 4.0
|
||||
// Copyright (2022) National Technology & Engineering
|
||||
// Solutions of Sandia, LLC (NTESS).
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
//===---------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___ATOMIC_ATOMIC_REF_H
|
||||
#define _LIBCPP___ATOMIC_ATOMIC_REF_H
|
||||
|
||||
#include <__assert>
|
||||
#include <__atomic/atomic_sync.h>
|
||||
#include <__atomic/check_memory_order.h>
|
||||
#include <__atomic/to_gcc_order.h>
|
||||
#include <__concepts/arithmetic.h>
|
||||
#include <__concepts/same_as.h>
|
||||
#include <__config>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__type_traits/has_unique_object_representation.h>
|
||||
#include <__type_traits/is_trivially_copyable.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
template <class _Tp>
|
||||
struct __atomic_ref_base {
|
||||
protected:
|
||||
_Tp* __ptr_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI __atomic_ref_base(_Tp& __obj) : __ptr_(std::addressof(__obj)) {}
|
||||
|
||||
private:
|
||||
_LIBCPP_HIDE_FROM_ABI static _Tp* __clear_padding(_Tp& __val) noexcept {
|
||||
_Tp* __ptr = std::addressof(__val);
|
||||
# if __has_builtin(__builtin_clear_padding)
|
||||
__builtin_clear_padding(__ptr);
|
||||
# endif
|
||||
return __ptr;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI static bool __compare_exchange(
|
||||
_Tp* __ptr, _Tp* __expected, _Tp* __desired, bool __is_weak, int __success, int __failure) noexcept {
|
||||
if constexpr (
|
||||
# if __has_builtin(__builtin_clear_padding)
|
||||
has_unique_object_representations_v<_Tp> || floating_point<_Tp>
|
||||
# else
|
||||
true // NOLINT(readability-simplify-boolean-expr)
|
||||
# endif
|
||||
) {
|
||||
return __atomic_compare_exchange(__ptr, __expected, __desired, __is_weak, __success, __failure);
|
||||
} else { // _Tp has padding bits and __builtin_clear_padding is available
|
||||
__clear_padding(*__desired);
|
||||
_Tp __copy = *__expected;
|
||||
__clear_padding(__copy);
|
||||
// The algorithm we use here is basically to perform `__atomic_compare_exchange` on the
|
||||
// values until it has either succeeded, or failed because the value representation of the
|
||||
// objects involved was different. This is why we loop around __atomic_compare_exchange:
|
||||
// we basically loop until its failure is caused by the value representation of the objects
|
||||
// being different, not only their object representation.
|
||||
while (true) {
|
||||
_Tp __prev = __copy;
|
||||
if (__atomic_compare_exchange(__ptr, std::addressof(__copy), __desired, __is_weak, __success, __failure)) {
|
||||
return true;
|
||||
}
|
||||
_Tp __curr = __copy;
|
||||
if (std::memcmp(__clear_padding(__prev), __clear_padding(__curr), sizeof(_Tp)) != 0) {
|
||||
// Value representation without padding bits do not compare equal ->
|
||||
// write the current content of *ptr into *expected
|
||||
std::memcpy(__expected, std::addressof(__copy), sizeof(_Tp));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
friend struct __atomic_waitable_traits<__atomic_ref_base<_Tp>>;
|
||||
|
||||
public:
|
||||
using value_type = _Tp;
|
||||
|
||||
static constexpr size_t required_alignment = alignof(_Tp);
|
||||
|
||||
// The __atomic_always_lock_free builtin takes into account the alignment of the pointer if provided,
|
||||
// so we create a fake pointer with a suitable alignment when querying it. Note that we are guaranteed
|
||||
// that the pointer is going to be aligned properly at runtime because that is a (checked) precondition
|
||||
// of atomic_ref's constructor.
|
||||
static constexpr bool is_always_lock_free =
|
||||
__atomic_always_lock_free(sizeof(_Tp), reinterpret_cast<void*>(-required_alignment));
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept { return __atomic_is_lock_free(sizeof(_Tp), __ptr_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI void store(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept
|
||||
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__order) {
|
||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
||||
__order == memory_order::relaxed || __order == memory_order::release || __order == memory_order::seq_cst,
|
||||
"atomic_ref: memory order argument to atomic store operation is invalid");
|
||||
__atomic_store(__ptr_, __clear_padding(__desired), std::__to_gcc_order(__order));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __desired) const noexcept {
|
||||
store(__desired);
|
||||
return __desired;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __order = memory_order::seq_cst) const noexcept
|
||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__order) {
|
||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
||||
__order == memory_order::relaxed || __order == memory_order::consume || __order == memory_order::acquire ||
|
||||
__order == memory_order::seq_cst,
|
||||
"atomic_ref: memory order argument to atomic load operation is invalid");
|
||||
alignas(_Tp) byte __mem[sizeof(_Tp)];
|
||||
auto* __ret = reinterpret_cast<_Tp*>(__mem);
|
||||
__atomic_load(__ptr_, __ret, std::__to_gcc_order(__order));
|
||||
return *__ret;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI operator _Tp() const noexcept { return load(); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept {
|
||||
alignas(_Tp) byte __mem[sizeof(_Tp)];
|
||||
auto* __ret = reinterpret_cast<_Tp*>(__mem);
|
||||
__atomic_exchange(__ptr_, __clear_padding(__desired), __ret, std::__to_gcc_order(__order));
|
||||
return *__ret;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_weak(_Tp& __expected, _Tp __desired, memory_order __success, memory_order __failure) const noexcept
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__success, __failure) {
|
||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
||||
__failure == memory_order::relaxed || __failure == memory_order::consume ||
|
||||
__failure == memory_order::acquire || __failure == memory_order::seq_cst,
|
||||
"atomic_ref: failure memory order argument to weak atomic compare-and-exchange operation is invalid");
|
||||
return __compare_exchange(
|
||||
__ptr_,
|
||||
std::addressof(__expected),
|
||||
std::addressof(__desired),
|
||||
true,
|
||||
std::__to_gcc_order(__success),
|
||||
std::__to_gcc_order(__failure));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_strong(_Tp& __expected, _Tp __desired, memory_order __success, memory_order __failure) const noexcept
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__success, __failure) {
|
||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
||||
__failure == memory_order::relaxed || __failure == memory_order::consume ||
|
||||
__failure == memory_order::acquire || __failure == memory_order::seq_cst,
|
||||
"atomic_ref: failure memory order argument to strong atomic compare-and-exchange operation is invalid");
|
||||
return __compare_exchange(
|
||||
__ptr_,
|
||||
std::addressof(__expected),
|
||||
std::addressof(__desired),
|
||||
false,
|
||||
std::__to_gcc_order(__success),
|
||||
std::__to_gcc_order(__failure));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_weak(_Tp& __expected, _Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept {
|
||||
return __compare_exchange(
|
||||
__ptr_,
|
||||
std::addressof(__expected),
|
||||
std::addressof(__desired),
|
||||
true,
|
||||
std::__to_gcc_order(__order),
|
||||
std::__to_gcc_failure_order(__order));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
compare_exchange_strong(_Tp& __expected, _Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept {
|
||||
return __compare_exchange(
|
||||
__ptr_,
|
||||
std::addressof(__expected),
|
||||
std::addressof(__desired),
|
||||
false,
|
||||
std::__to_gcc_order(__order),
|
||||
std::__to_gcc_failure_order(__order));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI void wait(_Tp __old, memory_order __order = memory_order::seq_cst) const noexcept
|
||||
_LIBCPP_CHECK_WAIT_MEMORY_ORDER(__order) {
|
||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
||||
__order == memory_order::relaxed || __order == memory_order::consume || __order == memory_order::acquire ||
|
||||
__order == memory_order::seq_cst,
|
||||
"atomic_ref: memory order argument to atomic wait operation is invalid");
|
||||
std::__atomic_wait(*this, __old, __order);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI void notify_one() const noexcept { std::__atomic_notify_one(*this); }
|
||||
_LIBCPP_HIDE_FROM_ABI void notify_all() const noexcept { std::__atomic_notify_all(*this); }
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __atomic_waitable_traits<__atomic_ref_base<_Tp>> {
|
||||
static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_ref_base<_Tp>& __a, memory_order __order) {
|
||||
return __a.load(__order);
|
||||
}
|
||||
static _LIBCPP_HIDE_FROM_ABI const _Tp* __atomic_contention_address(const __atomic_ref_base<_Tp>& __a) {
|
||||
return __a.__ptr_;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct atomic_ref : public __atomic_ref_base<_Tp> {
|
||||
static_assert(is_trivially_copyable_v<_Tp>, "std::atomic_ref<T> requires that 'T' be a trivially copyable type");
|
||||
|
||||
using __base = __atomic_ref_base<_Tp>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI explicit atomic_ref(_Tp& __obj) : __base(__obj) {
|
||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
||||
reinterpret_cast<uintptr_t>(std::addressof(__obj)) % __base::required_alignment == 0,
|
||||
"atomic_ref ctor: referenced object must be aligned to required_alignment");
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI atomic_ref(const atomic_ref&) noexcept = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __desired) const noexcept { return __base::operator=(__desired); }
|
||||
|
||||
atomic_ref& operator=(const atomic_ref&) = delete;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
requires(std::integral<_Tp> && !std::same_as<bool, _Tp>)
|
||||
struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> {
|
||||
using __base = __atomic_ref_base<_Tp>;
|
||||
|
||||
using difference_type = __base::value_type;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI explicit atomic_ref(_Tp& __obj) : __base(__obj) {
|
||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
||||
reinterpret_cast<uintptr_t>(std::addressof(__obj)) % __base::required_alignment == 0,
|
||||
"atomic_ref ctor: referenced object must be aligned to required_alignment");
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI atomic_ref(const atomic_ref&) noexcept = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __desired) const noexcept { return __base::operator=(__desired); }
|
||||
|
||||
atomic_ref& operator=(const atomic_ref&) = delete;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||
return __atomic_fetch_add(this->__ptr_, __arg, std::__to_gcc_order(__order));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||
return __atomic_fetch_sub(this->__ptr_, __arg, std::__to_gcc_order(__order));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||
return __atomic_fetch_and(this->__ptr_, __arg, std::__to_gcc_order(__order));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||
return __atomic_fetch_or(this->__ptr_, __arg, std::__to_gcc_order(__order));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||
return __atomic_fetch_xor(this->__ptr_, __arg, std::__to_gcc_order(__order));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator++(int) const noexcept { return fetch_add(_Tp(1)); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator--(int) const noexcept { return fetch_sub(_Tp(1)); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator++() const noexcept { return fetch_add(_Tp(1)) + _Tp(1); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator--() const noexcept { return fetch_sub(_Tp(1)) - _Tp(1); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __arg) const noexcept { return fetch_add(__arg) + __arg; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __arg) const noexcept { return fetch_sub(__arg) - __arg; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __arg) const noexcept { return fetch_and(__arg) & __arg; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __arg) const noexcept { return fetch_or(__arg) | __arg; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __arg) const noexcept { return fetch_xor(__arg) ^ __arg; }
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
requires std::floating_point<_Tp>
|
||||
struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> {
|
||||
using __base = __atomic_ref_base<_Tp>;
|
||||
|
||||
using difference_type = __base::value_type;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI explicit atomic_ref(_Tp& __obj) : __base(__obj) {
|
||||
_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(
|
||||
reinterpret_cast<uintptr_t>(std::addressof(__obj)) % __base::required_alignment == 0,
|
||||
"atomic_ref ctor: referenced object must be aligned to required_alignment");
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI atomic_ref(const atomic_ref&) noexcept = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __desired) const noexcept { return __base::operator=(__desired); }
|
||||
|
||||
atomic_ref& operator=(const atomic_ref&) = delete;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||
_Tp __old = this->load(memory_order_relaxed);
|
||||
_Tp __new = __old + __arg;
|
||||
while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) {
|
||||
__new = __old + __arg;
|
||||
}
|
||||
return __old;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||
_Tp __old = this->load(memory_order_relaxed);
|
||||
_Tp __new = __old - __arg;
|
||||
while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) {
|
||||
__new = __old - __arg;
|
||||
}
|
||||
return __old;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __arg) const noexcept { return fetch_add(__arg) + __arg; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __arg) const noexcept { return fetch_sub(__arg) - __arg; }
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct atomic_ref<_Tp*> : public __atomic_ref_base<_Tp*> {
|
||||
using __base = __atomic_ref_base<_Tp*>;
|
||||
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI explicit atomic_ref(_Tp*& __ptr) : __base(__ptr) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __desired) const noexcept { return __base::operator=(__desired); }
|
||||
|
||||
atomic_ref& operator=(const atomic_ref&) = delete;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||
return __atomic_fetch_add(this->__ptr_, __arg * sizeof(_Tp), std::__to_gcc_order(__order));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __arg, memory_order __order = memory_order_seq_cst) const noexcept {
|
||||
return __atomic_fetch_sub(this->__ptr_, __arg * sizeof(_Tp), std::__to_gcc_order(__order));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) const noexcept { return fetch_add(1); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) const noexcept { return fetch_sub(1); }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp* operator++() const noexcept { return fetch_add(1) + 1; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp* operator--() const noexcept { return fetch_sub(1) - 1; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __arg) const noexcept { return fetch_add(__arg) + __arg; }
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __arg) const noexcept { return fetch_sub(__arg) - __arg; }
|
||||
};
|
||||
|
||||
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(atomic_ref);
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP__ATOMIC_ATOMIC_REF_H
|
223
third_party/libcxx/__atomic/atomic_sync.h
vendored
223
third_party/libcxx/__atomic/atomic_sync.h
vendored
|
@ -12,13 +12,17 @@
|
|||
#include <__atomic/contention_t.h>
|
||||
#include <__atomic/cxx_atomic_impl.h>
|
||||
#include <__atomic/memory_order.h>
|
||||
#include <__availability>
|
||||
#include <__atomic/to_gcc_order.h>
|
||||
#include <__chrono/duration.h>
|
||||
#include <__config>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__thread/poll_with_backoff.h>
|
||||
#include <__threading_support>
|
||||
#include <__thread/support.h>
|
||||
#include <__type_traits/conjunction.h>
|
||||
#include <__type_traits/decay.h>
|
||||
#include <__type_traits/invoke.h>
|
||||
#include <__type_traits/void_t.h>
|
||||
#include <__utility/declval.h>
|
||||
#include <cstring>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
|
@ -27,84 +31,173 @@
|
|||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
// The customisation points to enable the following functions:
|
||||
// - __atomic_wait
|
||||
// - __atomic_wait_unless
|
||||
// - __atomic_notify_one
|
||||
// - __atomic_notify_all
|
||||
// Note that std::atomic<T>::wait was back-ported to C++03
|
||||
// The below implementations look ugly to support C++03
|
||||
template <class _Tp, class = void>
|
||||
struct __atomic_waitable_traits {
|
||||
template <class _AtomicWaitable>
|
||||
static void __atomic_load(_AtomicWaitable&&, memory_order) = delete;
|
||||
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
|
||||
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
|
||||
|
||||
template <class _Atp, class _Fn>
|
||||
struct __libcpp_atomic_wait_backoff_impl {
|
||||
_Atp* __a;
|
||||
_Fn __test_fn;
|
||||
_LIBCPP_AVAILABILITY_SYNC
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const
|
||||
{
|
||||
if(__elapsed > chrono::microseconds(64))
|
||||
{
|
||||
auto const __monitor = std::__libcpp_atomic_monitor(__a);
|
||||
if(__test_fn())
|
||||
return true;
|
||||
std::__libcpp_atomic_wait(__a, __monitor);
|
||||
}
|
||||
else if(__elapsed > chrono::microseconds(4))
|
||||
__libcpp_thread_yield();
|
||||
else
|
||||
{} // poll
|
||||
return false;
|
||||
}
|
||||
template <class _AtomicWaitable>
|
||||
static void __atomic_contention_address(_AtomicWaitable&&) = delete;
|
||||
};
|
||||
|
||||
template <class _Atp, class _Fn>
|
||||
_LIBCPP_AVAILABILITY_SYNC
|
||||
_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
|
||||
{
|
||||
__libcpp_atomic_wait_backoff_impl<_Atp, __decay_t<_Fn> > __backoff_fn = {__a, __test_fn};
|
||||
return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
|
||||
template <class _Tp, class = void>
|
||||
struct __atomic_waitable : false_type {};
|
||||
|
||||
template <class _Tp>
|
||||
struct __atomic_waitable< _Tp,
|
||||
__void_t<decltype(__atomic_waitable_traits<__decay_t<_Tp> >::__atomic_load(
|
||||
std::declval<const _Tp&>(), std::declval<memory_order>())),
|
||||
decltype(__atomic_waitable_traits<__decay_t<_Tp> >::__atomic_contention_address(
|
||||
std::declval<const _Tp&>()))> > : true_type {};
|
||||
|
||||
template <class _AtomicWaitable, class _Poll>
|
||||
struct __atomic_wait_poll_impl {
|
||||
const _AtomicWaitable& __a_;
|
||||
_Poll __poll_;
|
||||
memory_order __order_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator()() const {
|
||||
auto __current_val = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_load(__a_, __order_);
|
||||
return __poll_(__current_val);
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*) _NOEXCEPT;
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*) _NOEXCEPT;
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
|
||||
__libcpp_atomic_monitor(void const volatile*) _NOEXCEPT;
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
||||
__libcpp_atomic_wait(void const volatile*, __cxx_contention_t) _NOEXCEPT;
|
||||
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
||||
__cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
||||
__cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t
|
||||
__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*) _NOEXCEPT;
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void
|
||||
__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t) _NOEXCEPT;
|
||||
|
||||
template <class _AtomicWaitable, class _Poll>
|
||||
struct __atomic_wait_backoff_impl {
|
||||
const _AtomicWaitable& __a_;
|
||||
_Poll __poll_;
|
||||
memory_order __order_;
|
||||
|
||||
using __waitable_traits = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >;
|
||||
|
||||
_LIBCPP_AVAILABILITY_SYNC
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
__update_monitor_val_and_poll(__cxx_atomic_contention_t const volatile*, __cxx_contention_t& __monitor_val) const {
|
||||
// In case the contention type happens to be __cxx_atomic_contention_t, i.e. __cxx_atomic_impl<int64_t>,
|
||||
// the platform wait is directly monitoring the atomic value itself.
|
||||
// `__poll_` takes the current value of the atomic as an in-out argument
|
||||
// to potentially modify it. After it returns, `__monitor` has a value
|
||||
// which can be safely waited on by `std::__libcpp_atomic_wait` without any
|
||||
// ABA style issues.
|
||||
__monitor_val = __waitable_traits::__atomic_load(__a_, __order_);
|
||||
return __poll_(__monitor_val);
|
||||
}
|
||||
|
||||
_LIBCPP_AVAILABILITY_SYNC
|
||||
_LIBCPP_HIDE_FROM_ABI bool
|
||||
__update_monitor_val_and_poll(void const volatile* __contention_address, __cxx_contention_t& __monitor_val) const {
|
||||
// In case the contention type is anything else, platform wait is monitoring a __cxx_atomic_contention_t
|
||||
// from the global pool, the monitor comes from __libcpp_atomic_monitor
|
||||
__monitor_val = std::__libcpp_atomic_monitor(__contention_address);
|
||||
auto __current_val = __waitable_traits::__atomic_load(__a_, __order_);
|
||||
return __poll_(__current_val);
|
||||
}
|
||||
|
||||
_LIBCPP_AVAILABILITY_SYNC
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const {
|
||||
if (__elapsed > chrono::microseconds(64)) {
|
||||
auto __contention_address = __waitable_traits::__atomic_contention_address(__a_);
|
||||
__cxx_contention_t __monitor_val;
|
||||
if (__update_monitor_val_and_poll(__contention_address, __monitor_val))
|
||||
return true;
|
||||
std::__libcpp_atomic_wait(__contention_address, __monitor_val);
|
||||
} else if (__elapsed > chrono::microseconds(4))
|
||||
__libcpp_thread_yield();
|
||||
else {
|
||||
} // poll
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// The semantics of this function are similar to `atomic`'s
|
||||
// `.wait(T old, std::memory_order order)`, but instead of having a hardcoded
|
||||
// predicate (is the loaded value unequal to `old`?), the predicate function is
|
||||
// specified as an argument. The loaded value is given as an in-out argument to
|
||||
// the predicate. If the predicate function returns `true`,
|
||||
// `__atomic_wait_unless` will return. If the predicate function returns
|
||||
// `false`, it must set the argument to its current understanding of the atomic
|
||||
// value. The predicate function must not return `false` spuriously.
|
||||
template <class _AtomicWaitable, class _Poll>
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
||||
__atomic_wait_unless(const _AtomicWaitable& __a, _Poll&& __poll, memory_order __order) {
|
||||
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
|
||||
__atomic_wait_poll_impl<_AtomicWaitable, __decay_t<_Poll> > __poll_impl = {__a, __poll, __order};
|
||||
__atomic_wait_backoff_impl<_AtomicWaitable, __decay_t<_Poll> > __backoff_fn = {__a, __poll, __order};
|
||||
std::__libcpp_thread_poll_with_backoff(__poll_impl, __backoff_fn);
|
||||
}
|
||||
|
||||
template <class _AtomicWaitable>
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) {
|
||||
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
|
||||
std::__cxx_atomic_notify_one(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
|
||||
}
|
||||
|
||||
template <class _AtomicWaitable>
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) {
|
||||
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
|
||||
std::__cxx_atomic_notify_all(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a));
|
||||
}
|
||||
|
||||
#else // _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
|
||||
template <class _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
|
||||
template <class _Atp, class _Fn>
|
||||
_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
|
||||
{
|
||||
return std::__libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy());
|
||||
template <class _AtomicWaitable, class _Poll>
|
||||
_LIBCPP_HIDE_FROM_ABI void __atomic_wait_unless(const _AtomicWaitable& __a, _Poll&& __poll, memory_order __order) {
|
||||
__atomic_wait_poll_impl<_AtomicWaitable, __decay_t<_Poll> > __poll_fn = {__a, __poll, __order};
|
||||
std::__libcpp_thread_poll_with_backoff(__poll_fn, __spinning_backoff_policy());
|
||||
}
|
||||
|
||||
template <class _AtomicWaitable>
|
||||
_LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable&) {}
|
||||
|
||||
template <class _AtomicWaitable>
|
||||
_LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable&) {}
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
template <typename _Tp> _LIBCPP_HIDE_FROM_ABI
|
||||
bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
|
||||
return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0;
|
||||
template <typename _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
|
||||
return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0;
|
||||
}
|
||||
|
||||
template <class _Atp, class _Tp>
|
||||
struct __cxx_atomic_wait_test_fn_impl {
|
||||
_Atp* __a;
|
||||
_Tp __val;
|
||||
memory_order __order;
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator()() const
|
||||
{
|
||||
return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val);
|
||||
}
|
||||
template <class _Tp>
|
||||
struct __atomic_compare_unequal_to {
|
||||
_Tp __val_;
|
||||
_LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __arg) const {
|
||||
return !std::__cxx_nonatomic_compare_equal(__arg, __val_);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Atp, class _Tp>
|
||||
_LIBCPP_AVAILABILITY_SYNC
|
||||
_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
|
||||
{
|
||||
__cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
|
||||
return std::__cxx_atomic_wait(__a, __test_fn);
|
||||
template <class _AtomicWaitable, class _Up>
|
||||
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
|
||||
__atomic_wait(_AtomicWaitable& __a, _Up __val, memory_order __order) {
|
||||
static_assert(__atomic_waitable<_AtomicWaitable>::value, "");
|
||||
__atomic_compare_unequal_to<_Up> __nonatomic_equal = {__val};
|
||||
std::__atomic_wait_unless(__a, __nonatomic_equal, __order);
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
|
26
third_party/libcxx/__atomic/check_memory_order.h
vendored
26
third_party/libcxx/__atomic/check_memory_order.h
vendored
|
@ -15,20 +15,20 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
|
||||
_LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
|
||||
__m == memory_order_acquire || \
|
||||
__m == memory_order_acq_rel, \
|
||||
"memory order argument to atomic operation is invalid")
|
||||
#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
|
||||
_LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || __m == memory_order_acquire || __m == memory_order_acq_rel, \
|
||||
"memory order argument to atomic operation is invalid")
|
||||
|
||||
#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
|
||||
_LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
|
||||
__m == memory_order_acq_rel, \
|
||||
"memory order argument to atomic operation is invalid")
|
||||
#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
|
||||
_LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || __m == memory_order_acq_rel, \
|
||||
"memory order argument to atomic operation is invalid")
|
||||
|
||||
#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
|
||||
_LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
|
||||
__f == memory_order_acq_rel, \
|
||||
"memory order argument to atomic operation is invalid")
|
||||
#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
|
||||
_LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || __f == memory_order_acq_rel, \
|
||||
"memory order argument to atomic operation is invalid")
|
||||
|
||||
#define _LIBCPP_CHECK_WAIT_MEMORY_ORDER(__m) \
|
||||
_LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || __m == memory_order_acq_rel, \
|
||||
"memory order argument to atomic operation is invalid")
|
||||
|
||||
#endif // _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H
|
||||
|
|
4
third_party/libcxx/__atomic/contention_t.h
vendored
4
third_party/libcxx/__atomic/contention_t.h
vendored
|
@ -20,9 +20,9 @@
|
|||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
|
||||
using __cxx_contention_t = int32_t;
|
||||
using __cxx_contention_t = int32_t;
|
||||
#else
|
||||
using __cxx_contention_t = int64_t;
|
||||
using __cxx_contention_t = int64_t;
|
||||
#endif // __linux__ || (_AIX && !__64BIT__)
|
||||
|
||||
using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
|
||||
|
|
763
third_party/libcxx/__atomic/cxx_atomic_impl.h
vendored
763
third_party/libcxx/__atomic/cxx_atomic_impl.h
vendored
File diff suppressed because it is too large
Load diff
14
third_party/libcxx/__atomic/fence.h
vendored
14
third_party/libcxx/__atomic/fence.h
vendored
|
@ -19,19 +19,9 @@
|
|||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
void
|
||||
atomic_thread_fence(memory_order __m) _NOEXCEPT
|
||||
{
|
||||
__cxx_atomic_thread_fence(__m);
|
||||
}
|
||||
inline _LIBCPP_HIDE_FROM_ABI void atomic_thread_fence(memory_order __m) _NOEXCEPT { __cxx_atomic_thread_fence(__m); }
|
||||
|
||||
inline _LIBCPP_HIDE_FROM_ABI
|
||||
void
|
||||
atomic_signal_fence(memory_order __m) _NOEXCEPT
|
||||
{
|
||||
__cxx_atomic_signal_fence(__m);
|
||||
}
|
||||
inline _LIBCPP_HIDE_FROM_ABI void atomic_signal_fence(memory_order __m) _NOEXCEPT { __cxx_atomic_signal_fence(__m); }
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
template <class _Tp>
|
||||
struct __libcpp_is_always_lock_free {
|
||||
// __atomic_always_lock_free is available in all Standard modes
|
||||
static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0);
|
||||
static const bool __value = __atomic_always_lock_free(sizeof(_Tp), nullptr);
|
||||
};
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
|
|
@ -18,10 +18,8 @@
|
|||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
_Tp kill_dependency(_Tp __y) _NOEXCEPT
|
||||
{
|
||||
return __y;
|
||||
_LIBCPP_HIDE_FROM_ABI _Tp kill_dependency(_Tp __y) _NOEXCEPT {
|
||||
return __y;
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
|
13
third_party/libcxx/__atomic/memory_order.h
vendored
13
third_party/libcxx/__atomic/memory_order.h
vendored
|
@ -22,14 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
// Figure out what the underlying type for `memory_order` would be if it were
|
||||
// declared as an unscoped enum (accounting for -fshort-enums). Use this result
|
||||
// to pin the underlying type in C++20.
|
||||
enum __legacy_memory_order {
|
||||
__mo_relaxed,
|
||||
__mo_consume,
|
||||
__mo_acquire,
|
||||
__mo_release,
|
||||
__mo_acq_rel,
|
||||
__mo_seq_cst
|
||||
};
|
||||
enum __legacy_memory_order { __mo_relaxed, __mo_consume, __mo_acquire, __mo_release, __mo_acq_rel, __mo_seq_cst };
|
||||
|
||||
using __memory_order_underlying_t = underlying_type<__legacy_memory_order>::type;
|
||||
|
||||
|
@ -44,8 +37,8 @@ enum class memory_order : __memory_order_underlying_t {
|
|||
seq_cst = __mo_seq_cst
|
||||
};
|
||||
|
||||
static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
|
||||
"unexpected underlying type for std::memory_order");
|
||||
static_assert(is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value,
|
||||
"unexpected underlying type for std::memory_order");
|
||||
|
||||
inline constexpr auto memory_order_relaxed = memory_order::relaxed;
|
||||
inline constexpr auto memory_order_consume = memory_order::consume;
|
||||
|
|
54
third_party/libcxx/__atomic/to_gcc_order.h
vendored
Normal file
54
third_party/libcxx/__atomic/to_gcc_order.h
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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___ATOMIC_TO_GCC_ORDER_H
|
||||
#define _LIBCPP___ATOMIC_TO_GCC_ORDER_H
|
||||
|
||||
#include <__atomic/memory_order.h>
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if defined(__ATOMIC_RELAXED) && defined(__ATOMIC_CONSUME) && defined(__ATOMIC_ACQUIRE) && \
|
||||
defined(__ATOMIC_RELEASE) && defined(__ATOMIC_ACQ_REL) && defined(__ATOMIC_SEQ_CST)
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
|
||||
// Avoid switch statement to make this a constexpr.
|
||||
return __order == memory_order_relaxed
|
||||
? __ATOMIC_RELAXED
|
||||
: (__order == memory_order_acquire
|
||||
? __ATOMIC_ACQUIRE
|
||||
: (__order == memory_order_release
|
||||
? __ATOMIC_RELEASE
|
||||
: (__order == memory_order_seq_cst
|
||||
? __ATOMIC_SEQ_CST
|
||||
: (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_CONSUME))));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
|
||||
// Avoid switch statement to make this a constexpr.
|
||||
return __order == memory_order_relaxed
|
||||
? __ATOMIC_RELAXED
|
||||
: (__order == memory_order_acquire
|
||||
? __ATOMIC_ACQUIRE
|
||||
: (__order == memory_order_release
|
||||
? __ATOMIC_RELAXED
|
||||
: (__order == memory_order_seq_cst
|
||||
? __ATOMIC_SEQ_CST
|
||||
: (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE : __ATOMIC_CONSUME))));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___ATOMIC_TO_GCC_ORDER_H
|
Loading…
Add table
Add a link
Reference in a new issue