Index: libcxx/include/__config =================================================================== --- libcxx/include/__config +++ libcxx/include/__config @@ -38,6 +38,10 @@ # define _LIBCPP_ABI_VERSION 1 #endif +#ifndef __STDC_HOSTED__ +# define _LIBCPP_FREESTANDING +#endif + #ifndef _LIBCPP_STD_VER # if __cplusplus <= 201103L # define _LIBCPP_STD_VER 11 @@ -1220,9 +1224,13 @@ # define _LIBCPP_HAS_GCC_ATOMIC_IMP #endif -#if (!defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)) \ +#if (!defined(_LIBCPP_HAS_C_ATOMIC_IMP) && \ + !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \ + !defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP)) \ || defined(_LIBCPP_HAS_NO_THREADS) -#define _LIBCPP_HAS_NO_ATOMIC_HEADER +# define _LIBCPP_HAS_NO_ATOMIC_HEADER +#elif !defined(_LIBCPP_ATOMIC_FLAG_TYPE) +# define _LIBCPP_ATOMIC_FLAG_TYPE bool #endif #ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK Index: libcxx/include/atomic =================================================================== --- libcxx/include/atomic +++ libcxx/include/atomic @@ -552,7 +552,9 @@ #ifdef _LIBCPP_HAS_NO_THREADS #error is not supported on this single threaded system #endif -#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) +#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && \ + !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) && \ + !defined(_LIBCPP_HAS_EXTERNAL_ATOMIC_IMP) #error is not implemented #endif #ifdef kill_dependency @@ -583,10 +585,137 @@ memory_order_release, memory_order_acq_rel, memory_order_seq_cst } memory_order; +#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \ + (defined(_LIBCPP_FREESTANDING) && \ + defined(__cpp_lib_atomic_is_always_lock_free)) + +template _Tp const& __create(); +template _Tp& __use(); + +template() = __create<_Td>())> +static char __test_atomic_assignable(int); +template +static __two __test_atomic_assignable(...); +template +struct __can_assign { + static const bool value = + sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char); +}; + +template() == __create<_Td>())> +static char __test_atomic_comparable(int); +template +static __two __test_atomic_comparable(...); +template +struct __can_compare { + static const bool value = + sizeof(__test_atomic_comparable<_Tp, _Td>(1)) == sizeof(char); +}; + +template +_LIBCPP_INLINE_VISIBILITY +typename enable_if< + __can_assign::value>::type +__cxx_atomic_assign_volatile(volatile _Tp& __a_value, _Tp __val) { + __a_value = __val; +} +template +_LIBCPP_INLINE_VISIBILITY +typename enable_if< + __can_assign<_Tp, volatile _Tp>::value>::type +__cxx_atomic_assign_volatile(_Tp& __a_value, _Tp const volatile& __val) { + __a_value = __val; +} +template +_LIBCPP_INLINE_VISIBILITY +typename enable_if< + !__can_assign::value && + __can_assign< _Tp, _Tp>::value>::type +__cxx_atomic_assign_volatile(volatile _Tp& __a_value, _Tp __val) { + // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because + // the default operator= in an object is not volatile, a byte-by-byte copy + // is required. + volatile char* to = reinterpret_cast(&__a_value); + volatile char* end = to + sizeof(_Tp); + char* from = reinterpret_cast(&__val); + while (to != end) + *to++ = *from++; +} +template +_LIBCPP_INLINE_VISIBILITY +typename enable_if< + !__can_assign<_Tp, volatile _Tp>::value && + __can_assign<_Tp, _Tp>::value>::type +__cxx_atomic_assign_volatile(_Tp& __a_value, _Tp const volatile& __val) { + // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because + // the default operator= in an object is not volatile, a byte-by-byte copy + // is required. + char* to = reinterpret_cast(&__a_value); + char* end = to + sizeof(_Tp); + const volatile char* from = reinterpret_cast(&__val); + while (to != end) + *to++ = *from++; +} + +template +_LIBCPP_INLINE_VISIBILITY +typename enable_if< + __can_compare::value, + bool>::type +__cxx_atomic_compare_volatile(volatile _Tp& __a_value, _Tp __val) { + return __a_value == __val; +} +template +_LIBCPP_INLINE_VISIBILITY +typename enable_if< + __can_compare<_Tp, volatile _Tp>::value, + bool>::type +__cxx_atomic_compare_volatile(_Tp& __a_value, _Tp const volatile& __val) { + return __a_value == __val; +} +template +_LIBCPP_INLINE_VISIBILITY +typename enable_if< + !__can_compare::value && + __can_compare< _Tp, _Tp>::value, + bool>::type +__cxx_atomic_compare_volatile(volatile _Tp& __a_value, _Tp __val) { + // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because + // the default operator= in an object is not volatile, a byte-by-byte compare + // is required. + const volatile char* to = reinterpret_cast(&__a_value); + const volatile char* end = to + sizeof(_Tp); + const char* from = reinterpret_cast(&__val); + while (to != end) + if(*to++ != *from++) + return false; + return true; +} +template +_LIBCPP_INLINE_VISIBILITY +typename enable_if< + !__can_compare<_Tp, volatile _Tp>::value && + __can_compare<_Tp, _Tp>::value, + bool>::type +__cxx_atomic_compare_volatile(_Tp& __a_value, _Tp const volatile& __val) { + // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because + // the default operator= in an object is not volatile, a byte-by-byte compare + // is required. + const char* to = reinterpret_cast(&__a_value); + const char* end = to + sizeof(_Tp); + const volatile char* from = reinterpret_cast(&__val); + while (to != end) + if(*to++ != *from++) + return false; + return true; +} + +#endif + #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) -namespace __gcc_atomic { + template -struct __gcc_atomic_t { +struct __cxx_atomic_type { #if _GNUC_VER >= 501 static_assert(is_trivially_copyable<_Tp>::value, @@ -594,32 +723,15 @@ #endif _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_CXX03_LANG - __gcc_atomic_t() _NOEXCEPT = default; -#else - __gcc_atomic_t() _NOEXCEPT : __a_value() {} -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT + __cxx_atomic_type() _NOEXCEPT _LIBCPP_DEFAULT + _LIBCPP_CONSTEXPR explicit __cxx_atomic_type(_Tp value) _NOEXCEPT : __a_value(value) {} _Tp __a_value; }; -#define _Atomic(x) __gcc_atomic::__gcc_atomic_t - -template _Tp __create(); - -template -typename enable_if__a_value = __create<_Td>()), char>::type - __test_atomic_assignable(int); -template -__two __test_atomic_assignable(...); - -template -struct __can_assign { - static const bool value = - sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char); -}; +template +using __cxx_atomic_base_impl = __cxx_atomic_type<_Tp>; -static inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) { +_LIBCPP_INLINE_VISIBILITY 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: @@ -629,7 +741,7 @@ __ATOMIC_CONSUME)))); } -static inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) { +_LIBCPP_INLINE_VISIBILITY 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: @@ -639,133 +751,125 @@ __ATOMIC_CONSUME)))); } -} // namespace __gcc_atomic - template -static inline -typename enable_if< - __gcc_atomic::__can_assign::value>::type -__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) { - __a->__a_value = __val; -} - -template -static inline -typename enable_if< - !__gcc_atomic::__can_assign::value && - __gcc_atomic::__can_assign< _Atomic(_Tp)*, _Tp>::value>::type -__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) { - // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because - // the default operator= in an object is not volatile, a byte-by-byte copy - // is required. - volatile char* to = reinterpret_cast(&__a->__a_value); - volatile char* end = to + sizeof(_Tp); - char* from = reinterpret_cast(&__val); - while (to != end) { - *to++ = *from++; - } +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_init(volatile __cxx_atomic_type<_Tp>* __a, _Tp __val) { + __cxx_atomic_assign_volatile(__a->__a_value, __val); } template -static inline void __c11_atomic_init(_Atomic(_Tp)* __a, _Tp __val) { +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_init(__cxx_atomic_type<_Tp>* __a, _Tp __val) { __a->__a_value = __val; } -static inline void __c11_atomic_thread_fence(memory_order __order) { - __atomic_thread_fence(__gcc_atomic::__to_gcc_order(__order)); +_LIBCPP_INLINE_VISIBILITY inline +void __cxx_atomic_thread_fence(memory_order __order) { + __atomic_thread_fence(__to_gcc_order(__order)); } -static inline void __c11_atomic_signal_fence(memory_order __order) { - __atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order)); +_LIBCPP_INLINE_VISIBILITY inline +void __cxx_atomic_signal_fence(memory_order __order) { + __atomic_signal_fence(__to_gcc_order(__order)); } template -static inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a, _Tp __val, - memory_order __order) { - return __atomic_store(&__a->__a_value, &__val, - __gcc_atomic::__to_gcc_order(__order)); +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_store(volatile __cxx_atomic_type<_Tp>* __a, _Tp __val, + memory_order __order) { + __atomic_store(&__a->__a_value, &__val, + __to_gcc_order(__order)); } template -static inline void __c11_atomic_store(_Atomic(_Tp)* __a, _Tp __val, - memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_store(__cxx_atomic_type<_Tp>* __a, _Tp __val, + memory_order __order) { __atomic_store(&__a->__a_value, &__val, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } template -static inline _Tp __c11_atomic_load(const volatile _Atomic(_Tp)* __a, - memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_load(const volatile __cxx_atomic_type<_Tp>* __a, + memory_order __order) { _Tp __ret; __atomic_load(&__a->__a_value, &__ret, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); return __ret; } template -static inline _Tp __c11_atomic_load(const _Atomic(_Tp)* __a, memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_load(const __cxx_atomic_type<_Tp>* __a, memory_order __order) { _Tp __ret; __atomic_load(&__a->__a_value, &__ret, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); return __ret; } template -static inline _Tp __c11_atomic_exchange(volatile _Atomic(_Tp)* __a, - _Tp __value, memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_exchange(volatile __cxx_atomic_type<_Tp>* __a, + _Tp __value, memory_order __order) { _Tp __ret; __atomic_exchange(&__a->__a_value, &__value, &__ret, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); return __ret; } template -static inline _Tp __c11_atomic_exchange(_Atomic(_Tp)* __a, _Tp __value, - memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_exchange(__cxx_atomic_type<_Tp>* __a, _Tp __value, + memory_order __order) { _Tp __ret; __atomic_exchange(&__a->__a_value, &__value, &__ret, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); return __ret; } template -static inline bool __c11_atomic_compare_exchange_strong( - volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_strong( + volatile __cxx_atomic_type<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, false, - __gcc_atomic::__to_gcc_order(__success), - __gcc_atomic::__to_gcc_failure_order(__failure)); + __to_gcc_order(__success), + __to_gcc_failure_order(__failure)); } template -static inline bool __c11_atomic_compare_exchange_strong( - _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success, +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_strong( + __cxx_atomic_type<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, false, - __gcc_atomic::__to_gcc_order(__success), - __gcc_atomic::__to_gcc_failure_order(__failure)); + __to_gcc_order(__success), + __to_gcc_failure_order(__failure)); } template -static inline bool __c11_atomic_compare_exchange_weak( - volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_weak( + volatile __cxx_atomic_type<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, true, - __gcc_atomic::__to_gcc_order(__success), - __gcc_atomic::__to_gcc_failure_order(__failure)); + __to_gcc_order(__success), + __to_gcc_failure_order(__failure)); } template -static inline bool __c11_atomic_compare_exchange_weak( - _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success, +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_weak( + __cxx_atomic_type<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, true, - __gcc_atomic::__to_gcc_order(__success), - __gcc_atomic::__to_gcc_failure_order(__failure)); + __to_gcc_order(__success), + __to_gcc_failure_order(__failure)); } template @@ -782,80 +886,268 @@ struct __skip_amt<_Tp[n]> { }; template -static inline _Tp __c11_atomic_fetch_add(volatile _Atomic(_Tp)* __a, - _Td __delta, memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_type<_Tp>* __a, + _Td __delta, memory_order __order) { return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } template -static inline _Tp __c11_atomic_fetch_add(_Atomic(_Tp)* __a, _Td __delta, - memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_add(__cxx_atomic_type<_Tp>* __a, _Td __delta, + memory_order __order) { return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } template -static inline _Tp __c11_atomic_fetch_sub(volatile _Atomic(_Tp)* __a, - _Td __delta, memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_type<_Tp>* __a, + _Td __delta, memory_order __order) { return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } template -static inline _Tp __c11_atomic_fetch_sub(_Atomic(_Tp)* __a, _Td __delta, - memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_sub(__cxx_atomic_type<_Tp>* __a, _Td __delta, + memory_order __order) { return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } template -static inline _Tp __c11_atomic_fetch_and(volatile _Atomic(_Tp)* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_type<_Tp>* __a, + _Tp __pattern, memory_order __order) { return __atomic_fetch_and(&__a->__a_value, __pattern, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } template -static inline _Tp __c11_atomic_fetch_and(_Atomic(_Tp)* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_and(__cxx_atomic_type<_Tp>* __a, + _Tp __pattern, memory_order __order) { return __atomic_fetch_and(&__a->__a_value, __pattern, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } template -static inline _Tp __c11_atomic_fetch_or(volatile _Atomic(_Tp)* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_type<_Tp>* __a, + _Tp __pattern, memory_order __order) { return __atomic_fetch_or(&__a->__a_value, __pattern, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } template -static inline _Tp __c11_atomic_fetch_or(_Atomic(_Tp)* __a, _Tp __pattern, - memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_or(__cxx_atomic_type<_Tp>* __a, _Tp __pattern, + memory_order __order) { return __atomic_fetch_or(&__a->__a_value, __pattern, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } template -static inline _Tp __c11_atomic_fetch_xor(volatile _Atomic(_Tp)* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_type<_Tp>* __a, + _Tp __pattern, memory_order __order) { return __atomic_fetch_xor(&__a->__a_value, __pattern, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } template -static inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern, - memory_order __order) { +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_xor(__cxx_atomic_type<_Tp>* __a, _Tp __pattern, + memory_order __order) { return __atomic_fetch_xor(&__a->__a_value, __pattern, - __gcc_atomic::__to_gcc_order(__order)); + __to_gcc_order(__order)); } + +#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) + +#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP) + +template +struct __cxx_atomic_type { + +#if _GNUC_VER >= 501 + static_assert(is_trivially_copyable<_Tp>::value, + "std::atomic requires that 'Tp' be a trivially copyable type"); +#endif + + _LIBCPP_INLINE_VISIBILITY + __cxx_atomic_type() _NOEXCEPT _LIBCPP_DEFAULT + _LIBCPP_CONSTEXPR explicit __cxx_atomic_type(_Tp value) _NOEXCEPT + : __a_value(value) {} + _Atomic(_Tp) __a_value; +}; + +template +using __cxx_atomic_base_impl = __cxx_atomic_type<_Tp>; + +#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) + +_LIBCPP_INLINE_VISIBILITY inline +void __cxx_atomic_thread_fence(int __order) { + __c11_atomic_thread_fence(__order); +} + +_LIBCPP_INLINE_VISIBILITY inline +void __cxx_atomic_signal_fence(int __order) { + __c11_atomic_signal_fence(__order); +} + +template +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_init(__cxx_atomic_type<_Tp> volatile* __a, _Tp __val) { + __c11_atomic_init(&__a->__a_value, __val); +} +template +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_init(__cxx_atomic_type<_Tp> * __a, _Tp __val) { + __c11_atomic_init(&__a->__a_value, __val); +} + +template +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_store(__cxx_atomic_type<_Tp> volatile* __a, _Tp __val, int __order) { + __c11_atomic_store(&__a->__a_value, __val, __order); +} +template +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_store(__cxx_atomic_type<_Tp> * __a, _Tp __val, int __order) { + __c11_atomic_store(&__a->__a_value, __val, __order); +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_load(__cxx_atomic_type<_Tp> const volatile* __a, int __order) { + using __ptr_type = typename remove_const__a_value)>::type*; + return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), __order); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_load(__cxx_atomic_type<_Tp> const* __a, int __order) { + using __ptr_type = typename remove_const__a_value)>::type*; + return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), __order); +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_exchange(__cxx_atomic_type<_Tp> volatile* __a, _Tp __value, int __order) { + return __c11_atomic_exchange(&__a->__a_value, __value, __order); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_exchange(__cxx_atomic_type<_Tp> * __a, _Tp __value, int __order) { + return __c11_atomic_exchange(&__a->__a_value, __value, __order); +} + +template +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_type<_Tp> volatile* __a, _Tp* __expected, _Tp __value, int __success, int __failure) { + return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, __success, __failure); +} +template +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_type<_Tp> * __a, _Tp* __expected, _Tp __value, int __success, int __failure) { + return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, __success, __failure); +} + +template +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_type<_Tp> volatile* __a, _Tp* __expected, _Tp __value, int __success, int __failure) { + return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, __success, __failure); +} +template +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_type<_Tp> * __a, _Tp* __expected, _Tp __value, int __success, int __failure) { + return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, __success, __failure); +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_add(__cxx_atomic_type<_Tp> volatile* __a, _Tp __delta, int __order) { + return __c11_atomic_fetch_add(&__a->__a_value, __delta, __order); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_add(__cxx_atomic_type<_Tp> * __a, _Tp __delta, int __order) { + return __c11_atomic_fetch_add(&__a->__a_value, __delta, __order); +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp* __cxx_atomic_fetch_add(__cxx_atomic_type<_Tp*> volatile* __a, ptrdiff_t __delta, int __order) { + return __c11_atomic_fetch_add(&__a->__a_value, __delta, __order); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp* __cxx_atomic_fetch_add(__cxx_atomic_type<_Tp*> * __a, ptrdiff_t __delta, int __order) { + return __c11_atomic_fetch_add(&__a->__a_value, __delta, __order); +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_sub(__cxx_atomic_type<_Tp> volatile* __a, _Tp __delta, int __order) { + return __c11_atomic_fetch_sub(&__a->__a_value, __delta, __order); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_sub(__cxx_atomic_type<_Tp> * __a, _Tp __delta, int __order) { + return __c11_atomic_fetch_sub(&__a->__a_value, __delta, __order); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_type<_Tp*> volatile* __a, ptrdiff_t __delta, int __order) { + return __c11_atomic_fetch_sub(&__a->__a_value, __delta, __order); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_type<_Tp*> * __a, ptrdiff_t __delta, int __order) { + return __c11_atomic_fetch_sub(&__a->__a_value, __delta, __order); +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_and(__cxx_atomic_type<_Tp> volatile* __a, _Tp __pattern, int __order) { + return __c11_atomic_fetch_and(&__a->__a_value, __pattern, __order); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_and(__cxx_atomic_type<_Tp> * __a, _Tp __pattern, int __order) { + return __c11_atomic_fetch_and(&__a->__a_value, __pattern, __order); +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_or(__cxx_atomic_type<_Tp> volatile* __a, _Tp __pattern, int __order) { + return __c11_atomic_fetch_or(&__a->__a_value, __pattern, __order); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_or(__cxx_atomic_type<_Tp> * __a, _Tp __pattern, int __order) { + return __c11_atomic_fetch_or(&__a->__a_value, __pattern, __order); +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_xor(__cxx_atomic_type<_Tp> volatile* __a, _Tp __pattern, int __order) { + return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, __order); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_xor(__cxx_atomic_type<_Tp> * __a, _Tp __pattern, int __order) { + return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, __order); +} + #endif // _LIBCPP_HAS_GCC_ATOMIC_IMP template -inline _LIBCPP_INLINE_VISIBILITY -_Tp -kill_dependency(_Tp __y) _NOEXCEPT +_LIBCPP_INLINE_VISIBILITY +_Tp kill_dependency(_Tp __y) _NOEXCEPT { return __y; } @@ -871,7 +1163,7 @@ # 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 -#else +#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 # define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE @@ -884,12 +1176,308 @@ # define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE #endif +#if defined(_LIBCPP_FREESTANDING) && defined(__cpp_lib_atomic_is_always_lock_free) + +template +struct __cxx_atomic_lock_impl { + +#if _GNUC_VER >= 501 + static_assert(is_trivially_copyable<_Tp>::value, + "std::atomic requires that 'Tp' be a trivially copyable type"); +#endif + + _LIBCPP_INLINE_VISIBILITY + __cxx_atomic_lock_impl() _NOEXCEPT + : __a_value(), __a_lock(0) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit + __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT + : __a_value(value), __a_lock(0) {} + + _Tp __a_value; + mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock; + + _LIBCPP_INLINE_VISIBILITY _Tp reader() const volatile { + _Tp __old; + while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)); + __cxx_atomic_assign_volatile(__old, __a_value); + __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); + return __old; + } + _LIBCPP_INLINE_VISIBILITY _Tp reader() const { + _Tp __old; + while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)); + __old = __a_value; + __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); + return __old; + } + template + _LIBCPP_INLINE_VISIBILITY void writer(_Function && __f) volatile { + while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)); + __f(__a_value); + __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); + } + template + _LIBCPP_INLINE_VISIBILITY void writer(_Function && __f) { + while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)); + __f(__a_value); + __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); + } +}; + +template +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { + __cxx_atomic_assign_volatile(__a->__a_value, __val); +} +template +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { + __a->__a_value = __val; +} + +template +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { + __a->writer([&](_Tp volatile& __a_value){ + __cxx_atomic_assign_volatile(__a_value, __val); }); +} +template +_LIBCPP_INLINE_VISIBILITY +void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { + __a->writer([&](_Tp& __a_value){ + __a_value = __val; }); +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { + return __a->reader(); +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { + return __a->reader(); +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { + _Tp __old; + __a->writer([&](_Tp volatile& __a_value){ + __cxx_atomic_assign_volatile(__old, __a_value); + __cxx_atomic_assign_volatile(__a_value, __value); + }); + return __old; +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { + _Tp __old; + __a->writer([&](_Tp& __a_value){ + __old = __a_value; + __a_value = __value; + }); + return __old; +} + +template +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a, + _Tp* __expected, _Tp __value, memory_order, memory_order) { + bool __ret; + __a->writer([&](_Tp volatile& __a_value){ + __ret = __cxx_atomic_compare_volatile(__a_value, *__expected); + if(__ret) + __cxx_atomic_assign_volatile(__a_value, __value); + else + __cxx_atomic_assign_volatile(*__expected, __a_value); }); + return __ret; +} +template +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a, + _Tp* __expected, _Tp __value, memory_order, memory_order) { + bool __ret; + __a->writer([&](_Tp& __a_value){ + __ret = __a_value == *__expected; + if(__ret) + __a_value = __value; + else + *__expected = __a_value; }); + return __ret; +} + +template +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a, + _Tp* __expected, _Tp __value, memory_order, memory_order) { + bool __ret; + __a->writer([&](_Tp volatile& __a_value){ + __ret = __cxx_atomic_compare_volatile(__a_value, *__expected); + if(__ret) + __cxx_atomic_assign_volatile(__a_value, __value); + else + __cxx_atomic_assign_volatile(*__expected, __a_value); }); + return __ret; +} +template +_LIBCPP_INLINE_VISIBILITY +bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a, + _Tp* __expected, _Tp __value, memory_order, memory_order) { + bool __ret; + __a->writer([&](_Tp& __a_value){ + __ret = __a_value == *__expected; + if(__ret) + __a_value = __value; + else + *__expected = __a_value; }); + return __ret; +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a, + _Td __delta, memory_order) { + _Tp __old; + __a->writer([&](_Tp volatile& __a_value){ + __cxx_atomic_assign_volatile(__old, __a_value); + __cxx_atomic_assign_volatile(__a_value, _Tp(__old + __delta)); }); + return __old; +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a, + _Td __delta, memory_order) { + _Tp __old; + __a->writer([&](_Tp& __a_value){ + __old = __a_value; + __a_value += __delta; }); + return __old; +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a, + ptrdiff_t __delta, memory_order) { + _Tp* __old; + __a->writer([&](_Tp volatile& __a_value){ + __cxx_atomic_assign_volatile(__old, __a_value); + __cxx_atomic_assign_volatile(__a_value, __old + __delta); }); + return __old; +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a, + ptrdiff_t __delta, memory_order) { + _Tp* __old; + __a->writer([&](_Tp& __a_value){ + __old = __a_value; + __a_value += __delta; }); + return __old; +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a, + _Td __delta, memory_order) { + _Tp __old; + __a->writer([&](_Tp volatile& __a_value){ + __cxx_atomic_assign_volatile(__old, __a_value); + __cxx_atomic_assign_volatile(__a_value, _Tp(__old - __delta)); }); + return __old; +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a, + _Td __delta, memory_order) { + _Tp __old; + __a->writer([&](_Tp& __a_value){ + __old = __a_value; + __a_value -= __delta; }); + return __old; +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a, + _Tp __pattern, memory_order) { + _Tp __old; + __a->writer([&](_Tp volatile& __a_value){ + __cxx_atomic_assign_volatile(__old, __a_value); + __cxx_atomic_assign_volatile(__a_value, _Tp(__old & __pattern)); }); + return __old; +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a, + _Tp __pattern, memory_order) { + _Tp __old; + __a->writer([&](_Tp& __a_value){ + __old = __a_value; + __a_value &= __pattern; }); + return __old; +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a, + _Tp __pattern, memory_order) { + _Tp __old; + __a->writer([&](_Tp volatile& __a_value){ + __cxx_atomic_assign_volatile(__old, __a_value); + __cxx_atomic_assign_volatile(__a_value, _Tp(__old | __pattern)); }); + return __old; +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a, + _Tp __pattern, memory_order) { + _Tp __old; + __a->writer([&](_Tp& __a_value){ + __old = __a_value; + __a_value |= __pattern; }); + return __old; +} + +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a, + _Tp __pattern, memory_order) { + _Tp __old; + __a->writer([&](_Tp volatile& __a_value){ + __cxx_atomic_assign_volatile(__old, __a_value); + __cxx_atomic_assign_volatile(__a_value, _Tp(__old ^ __pattern)); }); + return __old; +} +template +_LIBCPP_INLINE_VISIBILITY +_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a, + _Tp __pattern, memory_order) { + _Tp __old; + __a->writer([&](_Tp& __a_value){ + __old = __a_value; + __a_value ^= __pattern; }); + return __old; +} + +template +using __cxx_atomic_impl = typename conditional<__atomic_always_lock_free(sizeof(_Tp), 0), + __cxx_atomic_base_impl<_Tp>, + __cxx_atomic_lock_impl<_Tp>>::type; + +#else + +template +using __cxx_atomic_impl = __cxx_atomic_base_impl<_Tp>; + +#endif //_LIBCPP_FREESTANDING && __cpp_lib_atomic_is_always_lock_free + // general atomic template ::value && !is_same<_Tp, bool>::value> struct __atomic_base // false { - mutable _Atomic(_Tp) __a_; + mutable __cxx_atomic_impl<_Tp> __a_; #if defined(__cpp_lib_atomic_is_always_lock_free) static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0); @@ -897,88 +1485,79 @@ _LIBCPP_INLINE_VISIBILITY bool is_lock_free() const volatile _NOEXCEPT - { -#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) - return __c11_atomic_is_lock_free(sizeof(_Tp)); -#else - return __atomic_is_lock_free(sizeof(_Tp), 0); -#endif - } + {return __cxx_atomic_is_lock_free(sizeof(_Tp));} _LIBCPP_INLINE_VISIBILITY bool is_lock_free() const _NOEXCEPT {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} _LIBCPP_INLINE_VISIBILITY void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) - {__c11_atomic_store(&__a_, __d, __m);} + {__cxx_atomic_store(&__a_, __d, __m);} _LIBCPP_INLINE_VISIBILITY void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) - {__c11_atomic_store(&__a_, __d, __m);} + {__cxx_atomic_store(&__a_, __d, __m);} _LIBCPP_INLINE_VISIBILITY _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) - {return __c11_atomic_load(&__a_, __m);} + {return __cxx_atomic_load(&__a_, __m);} _LIBCPP_INLINE_VISIBILITY _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) - {return __c11_atomic_load(&__a_, __m);} + {return __cxx_atomic_load(&__a_, __m);} _LIBCPP_INLINE_VISIBILITY operator _Tp() const volatile _NOEXCEPT {return load();} _LIBCPP_INLINE_VISIBILITY operator _Tp() const _NOEXCEPT {return load();} _LIBCPP_INLINE_VISIBILITY _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_exchange(&__a_, __d, __m);} + {return __cxx_atomic_exchange(&__a_, __d, __m);} _LIBCPP_INLINE_VISIBILITY _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_exchange(&__a_, __d, __m);} + {return __cxx_atomic_exchange(&__a_, __d, __m);} _LIBCPP_INLINE_VISIBILITY bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) - {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} + {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} _LIBCPP_INLINE_VISIBILITY bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) - {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} + {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} _LIBCPP_INLINE_VISIBILITY bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) - {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} + {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} _LIBCPP_INLINE_VISIBILITY bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) - {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} + {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} _LIBCPP_INLINE_VISIBILITY bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} + {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} _LIBCPP_INLINE_VISIBILITY bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} + {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} _LIBCPP_INLINE_VISIBILITY bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} + {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} _LIBCPP_INLINE_VISIBILITY bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} + {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_CXX03_LANG - __atomic_base() _NOEXCEPT = default; -#else - __atomic_base() _NOEXCEPT : __a_() {} -#endif // _LIBCPP_CXX03_LANG + __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} #ifndef _LIBCPP_CXX03_LANG __atomic_base(const __atomic_base&) = delete; __atomic_base& operator=(const __atomic_base&) = delete; @@ -999,7 +1578,7 @@ // atomic template -struct __atomic_base<_Tp, true> +struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> { typedef __atomic_base<_Tp, false> __base; @@ -1010,34 +1589,34 @@ _LIBCPP_INLINE_VISIBILITY _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} @@ -1119,17 +1698,17 @@ _LIBCPP_INLINE_VISIBILITY _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} + {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);} _LIBCPP_INLINE_VISIBILITY _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} @@ -1160,7 +1739,7 @@ // atomic_is_lock_free template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY bool atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT { @@ -1168,7 +1747,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY bool atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT { @@ -1178,25 +1757,25 @@ // atomic_init template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY void atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT { - __c11_atomic_init(&__o->__a_, __d); + __cxx_atomic_init(&__o->__a_, __d); } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY void atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT { - __c11_atomic_init(&__o->__a_, __d); + __cxx_atomic_init(&__o->__a_, __d); } // atomic_store template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY void atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT { @@ -1204,7 +1783,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY void atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT { @@ -1214,7 +1793,7 @@ // atomic_store_explicit template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY void atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) @@ -1223,7 +1802,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY void atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) @@ -1234,7 +1813,7 @@ // atomic_load template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT { @@ -1242,7 +1821,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp atomic_load(const atomic<_Tp>* __o) _NOEXCEPT { @@ -1252,7 +1831,7 @@ // atomic_load_explicit template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) @@ -1261,7 +1840,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) @@ -1272,7 +1851,7 @@ // atomic_exchange template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT { @@ -1280,7 +1859,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT { @@ -1290,7 +1869,7 @@ // atomic_exchange_explicit template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT { @@ -1298,7 +1877,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT { @@ -1308,7 +1887,7 @@ // atomic_compare_exchange_weak template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY bool atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT { @@ -1316,7 +1895,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY bool atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT { @@ -1326,7 +1905,7 @@ // atomic_compare_exchange_strong template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY bool atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT { @@ -1334,7 +1913,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY bool atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT { @@ -1344,7 +1923,7 @@ // atomic_compare_exchange_weak_explicit template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY bool atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d, @@ -1355,7 +1934,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY bool atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT @@ -1367,7 +1946,7 @@ // atomic_compare_exchange_strong_explicit template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY bool atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d, @@ -1378,7 +1957,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY bool atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d, @@ -1391,7 +1970,7 @@ // atomic_fetch_add template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1403,7 +1982,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1415,7 +1994,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp* atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT { @@ -1423,7 +2002,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp* atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT { @@ -1433,7 +2012,7 @@ // atomic_fetch_add_explicit template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1445,7 +2024,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1457,7 +2036,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp* atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT @@ -1466,7 +2045,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp* atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT { @@ -1476,7 +2055,7 @@ // atomic_fetch_sub template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1488,7 +2067,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1500,7 +2079,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp* atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT { @@ -1508,7 +2087,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp* atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT { @@ -1518,7 +2097,7 @@ // atomic_fetch_sub_explicit template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1530,7 +2109,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1542,7 +2121,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp* atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT @@ -1551,7 +2130,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _Tp* atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT { @@ -1561,7 +2140,7 @@ // atomic_fetch_and template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1573,7 +2152,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1587,7 +2166,7 @@ // atomic_fetch_and_explicit template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1599,7 +2178,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1613,7 +2192,7 @@ // atomic_fetch_or template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1625,7 +2204,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1639,7 +2218,7 @@ // atomic_fetch_or_explicit template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1651,7 +2230,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1665,7 +2244,7 @@ // atomic_fetch_xor template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1677,7 +2256,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1691,7 +2270,7 @@ // atomic_fetch_xor_explicit template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1703,7 +2282,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value && !is_same<_Tp, bool>::value, @@ -1718,27 +2297,23 @@ typedef struct atomic_flag { - _Atomic(bool) __a_; + __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; _LIBCPP_INLINE_VISIBILITY bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __c11_atomic_exchange(&__a_, true, __m);} + {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} _LIBCPP_INLINE_VISIBILITY bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __c11_atomic_exchange(&__a_, true, __m);} + {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} _LIBCPP_INLINE_VISIBILITY void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {__c11_atomic_store(&__a_, false, __m);} + {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} _LIBCPP_INLINE_VISIBILITY void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT - {__c11_atomic_store(&__a_, false, __m);} + {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_CXX03_LANG - atomic_flag() _NOEXCEPT = default; -#else - atomic_flag() _NOEXCEPT : __a_() {} -#endif // _LIBCPP_CXX03_LANG + atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION @@ -1817,14 +2392,14 @@ void atomic_thread_fence(memory_order __m) _NOEXCEPT { - __c11_atomic_thread_fence(__m); + __cxx_atomic_thread_fence(__m); } inline _LIBCPP_INLINE_VISIBILITY void atomic_signal_fence(memory_order __m) _NOEXCEPT { - __c11_atomic_signal_fence(__m); + __cxx_atomic_signal_fence(__m); } // Atomics for standard typedef types