summaryrefslogtreecommitdiffstats
path: root/libcxx
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/include/atomic1204
-rw-r--r--libcxx/src/atomic.cpp23
-rw-r--r--libcxx/test/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp12
-rw-r--r--libcxx/test/atomics/atomics.flag/clear.pass.cpp12
4 files changed, 1173 insertions, 78 deletions
diff --git a/libcxx/include/atomic b/libcxx/include/atomic
index ee372fae361..edcfd2ed56a 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -2411,102 +2411,677 @@ void atomic_signal_fence(memory_order);
*/
#include <__config>
+#include <__mutex_base>
+#include <cstring>
#pragma GCC system_header
-// Begin "Intrinsics"
+_LIBCPP_BEGIN_NAMESPACE_STD
+typedef enum memory_order
+{
+ memory_order_relaxed, memory_order_consume, memory_order_acquire,
+ memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+} memory_order;
+
+template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
-bool
-__exchange_relaxed(volatile bool* __b)
+_Tp
+kill_dependency(_Tp __y)
{
- return __sync_lock_test_and_set(__b, true);
+ return __y;
}
-inline _LIBCPP_INLINE_VISIBILITY
-bool
-__exchange_consume(volatile bool* __b)
+_LIBCPP_VISIBLE
+mutex& __not_atomic_mut();
+
+// load
+
+template <class _Tp>
+_Tp
+__load_seq_cst(const volatile _Tp* __obj)
{
- return __sync_lock_test_and_set(__b, true);
+ unique_lock<mutex> _(__not_atomic_mut());
+ return *__obj;
}
+// load bool
+
inline _LIBCPP_INLINE_VISIBILITY
bool
-__exchange_acquire(volatile bool* __b)
+__choose_load_seq_cst(const volatile bool* __obj)
{
- return __sync_lock_test_and_set(__b, true);
+#if __has_feature(__atomic_load_seq_cst_b)
+ return __atomic_load_seq_cst(__obj);
+#else
+ return __load_seq_cst(__obj);
+#endif
}
inline _LIBCPP_INLINE_VISIBILITY
bool
-__exchange_release(volatile bool* __b)
+__choose_load_acquire(const volatile bool* __obj)
{
- __sync_synchronize();
- return __sync_lock_test_and_set(__b, true);
+#if __has_feature(__atomic_load_acquire_b)
+ return __atomic_load_acquire(__obj);
+#else
+ return __choose_load_seq_cst(__obj);
+#endif
}
inline _LIBCPP_INLINE_VISIBILITY
bool
-__exchange_acq_rel(volatile bool* __b)
+__choose_load_consume(const volatile bool* __obj)
{
- __sync_synchronize();
- return __sync_lock_test_and_set(__b, true);
+#if __has_feature(__atomic_load_consume_b)
+ return __atomic_load_consume(__obj);
+#else
+ return __choose_load_acquire(__obj);
+#endif
}
inline _LIBCPP_INLINE_VISIBILITY
bool
-__exchange_seq_cst(volatile bool* __b)
+__choose_load_relaxed(const volatile bool* __obj)
{
- __sync_synchronize();
- return __sync_lock_test_and_set(__b, true);
+#if __has_feature(__atomic_load_relaxed_b)
+ return __atomic_load_relaxed(__obj);
+#else
+ return __choose_load_consume(__obj);
+#endif
}
-inline _LIBCPP_INLINE_VISIBILITY
+// store
+
+template <class _Tp>
void
-__atomic_store_relaxed(volatile bool* __b, bool __x)
+__store_seq_cst(volatile _Tp* __obj, _Tp __desr)
{
- __sync_lock_test_and_set(__b, __x);
+ unique_lock<mutex> _(__not_atomic_mut());
+ *__obj = __desr;
}
+// store bool
+
inline _LIBCPP_INLINE_VISIBILITY
void
-__atomic_store_consume(volatile bool* __b, bool __x)
+__choose_store_seq_cst(volatile bool* __obj, bool __desr)
{
- __sync_lock_test_and_set(__b, __x);
+#if __has_feature(__atomic_store_seq_cst_b)
+ __atomic_store_seq_cst(__obj, __desr);
+#else
+ __store_seq_cst(__obj, __desr);
+#endif
}
inline _LIBCPP_INLINE_VISIBILITY
void
-__atomic_store_release(volatile bool* __b, bool __x)
+__choose_store_release(volatile bool* __obj, bool __desr)
{
- __sync_synchronize();
- __sync_lock_test_and_set(__b, __x);
+#if __has_feature(__atomic_store_release_b)
+ __atomic_store_release(__obj, __desr);
+#else
+ __choose_store_seq_cst(__obj, __desr);
+#endif
}
inline _LIBCPP_INLINE_VISIBILITY
void
-__atomic_store_seq_cst(volatile bool* __b, bool __x)
+__choose_store_relaxed(volatile bool* __obj, bool __desr)
{
- __sync_synchronize();
- __sync_lock_test_and_set(__b, __x);
+#if __has_feature(__atomic_store_relaxed_b)
+ __atomic_store_relaxed(__obj, __desr);
+#else
+ __choose_store_release(__obj, __desr);
+#endif
}
-// End "Intrinsics"
+// exchange
-_LIBCPP_BEGIN_NAMESPACE_STD
+template <class _Tp>
+_Tp
+__exchange_seq_cst(volatile _Tp* __obj, _Tp __desr)
+{
+ unique_lock<mutex> _(__not_atomic_mut());
+ _Tp __r = *__obj;
+ *__obj = __desr;
+ return __r;
+}
-typedef enum memory_order
+// exchange bool
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_exchange_seq_cst(volatile bool* __obj, bool __desr)
{
- memory_order_relaxed, memory_order_consume, memory_order_acquire,
- memory_order_release, memory_order_acq_rel, memory_order_seq_cst
-} memory_order;
+#if __has_feature(__atomic_exchange_seq_cst_b)
+ return __atomic_exchange_seq_cst(__obj, __desr);
+#else
+ return __exchange_seq_cst(__obj, __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_exchange_acq_rel(volatile bool* __obj, bool __desr)
+{
+#if __has_feature(__atomic_exchange_acq_rel_b)
+ return __atomic_exchange_acq_rel(__obj, __desr);
+#else
+ return __choose_exchange_seq_cst(__obj, __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_exchange_release(volatile bool* __obj, bool __desr)
+{
+#if __has_feature(__atomic_exchange_release_b)
+ return __atomic_exchange_release(__obj, __desr);
+#else
+ return __choose_exchange_acq_rel(__obj, __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_exchange_acquire(volatile bool* __obj, bool __desr)
+{
+#if __has_feature(__atomic_exchange_acquire_b)
+ return __atomic_exchange_acquire(__obj, __desr);
+#else
+ return __choose_exchange_release(__obj, __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_exchange_consume(volatile bool* __obj, bool __desr)
+{
+#if __has_feature(__atomic_exchange_consume_b)
+ return __atomic_exchange_consume(__obj, __desr);
+#else
+ return __choose_exchange_acquire(__obj, __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_exchange_relaxed(volatile bool* __obj, bool __desr)
+{
+#if __has_feature(__atomic_exchange_relaxed_b)
+ return __atomic_exchange_relaxed(__obj, __desr);
+#else
+ return __choose_exchange_consume(__obj, __desr);
+#endif
+}
+
+// compare_exchange_strong
template <class _Tp>
+bool
+__compare_exchange_strong_seq_cst_seq_cst(volatile _Tp* __obj, _Tp* __exp,
+ _Tp __desr)
+{
+ unique_lock<mutex> _(__not_atomic_mut());
+ if (_STD::memcmp(const_cast<_Tp*>(__obj), __exp, sizeof(_Tp)) == 0)
+ {
+ _STD::memcpy(const_cast<_Tp*>(__obj), &__desr, sizeof(_Tp));
+ return true;
+ }
+ _STD::memcpy(__exp, const_cast<_Tp*>(__obj), sizeof(_Tp));
+ return false;
+}
+
+// compare_exchange_strong bool
+
inline _LIBCPP_INLINE_VISIBILITY
-_Tp
-kill_dependency(_Tp __y)
+bool
+__choose_compare_exchange_strong_seq_cst_seq_cst(volatile bool* __obj,
+ bool* __exp, bool __desr)
{
- return __y;
+#if __has_feature(__atomic_compare_exchange_strong_seq_cst_seq_cst_b)
+ return __atomic_compare_exchange_strong_seq_cst_seq_cst(__obj, __exp,
+ __desr);
+#else
+ return __compare_exchange_strong_seq_cst_seq_cst(__obj, __exp, __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_seq_cst_acquire(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_seq_cst_acquire_b)
+ return __atomic_compare_exchange_strong_seq_cst_acquire(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_seq_cst_seq_cst(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_seq_cst_consume(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_seq_cst_consume_b)
+ return __atomic_compare_exchange_strong_seq_cst_consume(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_seq_cst_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_seq_cst_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_seq_cst_relaxed_b)
+ return __atomic_compare_exchange_strong_seq_cst_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_seq_cst_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_acq_rel_acquire(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_acq_rel_acquire_b)
+ return __atomic_compare_exchange_strong_acq_rel_acquire(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_seq_cst_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_acq_rel_consume(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_acq_rel_consume_b)
+ return __atomic_compare_exchange_strong_acq_rel_consume(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acq_rel_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_acq_rel_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_acq_rel_relaxed_b)
+ return __atomic_compare_exchange_strong_acq_rel_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acq_rel_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_release_acquire(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_release_acquire_b)
+ return __atomic_compare_exchange_strong_release_acquire(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acq_rel_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_release_consume(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_release_consume_b)
+ return __atomic_compare_exchange_strong_release_consume(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_release_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_release_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_release_relaxed_b)
+ return __atomic_compare_exchange_strong_release_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_release_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_acquire_acquire(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_acquire_acquire_b)
+ return __atomic_compare_exchange_strong_acquire_acquire(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_release_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_acquire_consume(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_acquire_consume_b)
+ return __atomic_compare_exchange_strong_acquire_consume(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acquire_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_acquire_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_acquire_relaxed_b)
+ return __atomic_compare_exchange_strong_acquire_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acquire_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_consume_consume(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_consume_consume_b)
+ return __atomic_compare_exchange_strong_consume_consume(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acquire_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_consume_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_consume_relaxed_b)
+ return __atomic_compare_exchange_strong_consume_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_consume_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_strong_relaxed_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_strong_relaxed_relaxed_b)
+ return __atomic_compare_exchange_strong_relaxed_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_consume_relaxed(__obj, __exp,
+ __desr);
+#endif
+}
+
+// compare_exchange_weak bool
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_seq_cst_seq_cst(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_seq_cst_seq_cst_b)
+ return __atomic_compare_exchange_weak_seq_cst_seq_cst(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_seq_cst_seq_cst(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_seq_cst_acquire(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_seq_cst_acquire_b)
+ return __atomic_compare_exchange_weak_seq_cst_acquire(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_seq_cst_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_seq_cst_consume(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_seq_cst_consume_b)
+ return __atomic_compare_exchange_weak_seq_cst_consume(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_seq_cst_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_seq_cst_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_seq_cst_relaxed_b)
+ return __atomic_compare_exchange_weak_seq_cst_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_seq_cst_relaxed(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_acq_rel_acquire(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_acq_rel_acquire_b)
+ return __atomic_compare_exchange_weak_acq_rel_acquire(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acq_rel_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_acq_rel_consume(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_acq_rel_consume_b)
+ return __atomic_compare_exchange_weak_acq_rel_consume(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acq_rel_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_acq_rel_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_acq_rel_relaxed_b)
+ return __atomic_compare_exchange_weak_acq_rel_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acq_rel_relaxed(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_release_acquire(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_release_acquire_b)
+ return __atomic_compare_exchange_weak_release_acquire(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_release_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_release_consume(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_release_consume_b)
+ return __atomic_compare_exchange_weak_release_consume(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_release_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_release_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_release_relaxed_b)
+ return __atomic_compare_exchange_weak_release_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_release_relaxed(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_acquire_acquire(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_acquire_acquire_b)
+ return __atomic_compare_exchange_weak_acquire_acquire(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acquire_acquire(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_acquire_consume(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_acquire_consume_b)
+ return __atomic_compare_exchange_weak_acquire_consume(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acquire_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_acquire_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_acquire_relaxed_b)
+ return __atomic_compare_exchange_weak_acquire_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_acquire_relaxed(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_consume_consume(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_consume_consume_b)
+ return __atomic_compare_exchange_weak_consume_consume(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_consume_consume(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_consume_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_consume_relaxed_b)
+ return __atomic_compare_exchange_weak_consume_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_consume_relaxed(__obj, __exp,
+ __desr);
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool
+__choose_compare_exchange_weak_relaxed_relaxed(volatile bool* __obj,
+ bool* __exp, bool __desr)
+{
+#if __has_feature(__atomic_compare_exchange_weak_relaxed_relaxed_b)
+ return __atomic_compare_exchange_weak_relaxed_relaxed(__obj, __exp,
+ __desr);
+#else
+ return __choose_compare_exchange_strong_relaxed_relaxed(__obj, __exp,
+ __desr);
+#endif
}
// flag type and operations
@@ -2576,7 +3151,7 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
atomic_flag_test_and_set(volatile atomic_flag* __f)
{
- return __exchange_seq_cst(&__f->__flg_);
+ return __choose_exchange_seq_cst(&__f->__flg_, true);
}
inline _LIBCPP_INLINE_VISIBILITY
@@ -2593,17 +3168,17 @@ atomic_flag_test_and_set_explicit(volatile atomic_flag* __f, memory_order __o)
switch (__o)
{
case memory_order_relaxed:
- return __exchange_relaxed(&__f->__flg_);
+ return __choose_exchange_relaxed(&__f->__flg_, true);
case memory_order_consume:
- return __exchange_consume(&__f->__flg_);
+ return __choose_exchange_consume(&__f->__flg_, true);
case memory_order_acquire:
- return __exchange_acquire(&__f->__flg_);
+ return __choose_exchange_acquire(&__f->__flg_, true);
case memory_order_release:
- return __exchange_release(&__f->__flg_);
+ return __choose_exchange_release(&__f->__flg_, true);
case memory_order_acq_rel:
- return __exchange_acq_rel(&__f->__flg_);
+ return __choose_exchange_acq_rel(&__f->__flg_, true);
case memory_order_seq_cst:
- return __exchange_seq_cst(&__f->__flg_);
+ return __choose_exchange_seq_cst(&__f->__flg_, true);
}
}
@@ -2611,14 +3186,15 @@ inline _LIBCPP_INLINE_VISIBILITY
bool
atomic_flag_test_and_set_explicit(atomic_flag* __f, memory_order __o)
{
- return atomic_flag_test_and_set_explicit(const_cast<volatile atomic_flag*>(__f), __o);
+ return atomic_flag_test_and_set_explicit(const_cast<volatile atomic_flag*>
+ (__f), __o);
}
inline _LIBCPP_INLINE_VISIBILITY
void
atomic_flag_clear(volatile atomic_flag* __f)
{
- return __atomic_store_seq_cst(&__f->__flg_, false);
+ return __choose_store_seq_cst(&__f->__flg_, false);
}
inline _LIBCPP_INLINE_VISIBILITY
@@ -2635,16 +3211,13 @@ atomic_flag_clear_explicit(volatile atomic_flag* __f, memory_order __o)
switch (__o)
{
case memory_order_relaxed:
- __atomic_store_relaxed(&__f->__flg_, false);
- break;
- case memory_order_consume:
- __atomic_store_consume(&__f->__flg_, false);
+ __choose_store_relaxed(&__f->__flg_, false);
break;
case memory_order_release:
- __atomic_store_release(&__f->__flg_, false);
+ __choose_store_release(&__f->__flg_, false);
break;
case memory_order_seq_cst:
- __atomic_store_seq_cst(&__f->__flg_, false);
+ __choose_store_seq_cst(&__f->__flg_, false);
break;
}
}
@@ -2657,6 +3230,529 @@ atomic_flag_clear_explicit(atomic_flag* __f, memory_order __o)
}
#define ATOMIC_FLAG_INIT {false}
+#define ATOMIC_VAR_INIT(__v) {__v}
+
+inline _LIBCPP_INLINE_VISIBILITY
+memory_order
+__translate_memory_order(memory_order __o)
+{
+ switch (__o)
+ {
+ case memory_order_acq_rel:
+ return memory_order_acquire;
+ case memory_order_release:
+ return memory_order_relaxed;
+ }
+ return __o;
+}
+
+// atomic_bool
+
+struct atomic_bool;
+
+bool atomic_is_lock_free(const volatile atomic_bool*);
+bool atomic_is_lock_free(const atomic_bool*);
+void atomic_init(volatile atomic_bool*, bool);
+void atomic_init(atomic_bool*, bool);
+void atomic_store(volatile atomic_bool*, bool);
+void atomic_store(atomic_bool*, bool);
+void atomic_store_explicit(volatile atomic_bool*, bool, memory_order);
+void atomic_store_explicit(atomic_bool*, bool, memory_order);
+bool atomic_load(const volatile atomic_bool*);
+bool atomic_load(const atomic_bool*);
+bool atomic_load_explicit(const volatile atomic_bool*, memory_order);
+bool atomic_load_explicit(const atomic_bool*, memory_order);
+bool atomic_exchange(volatile atomic_bool*, bool);
+bool atomic_exchange(atomic_bool*, bool);
+bool atomic_exchange_explicit(volatile atomic_bool*, bool, memory_order);
+bool atomic_exchange_explicit(atomic_bool*, bool, memory_order);
+bool atomic_compare_exchange_weak(volatile atomic_bool*, bool*, bool);
+bool atomic_compare_exchange_weak(atomic_bool*, bool*, bool);
+bool atomic_compare_exchange_strong(volatile atomic_bool*, bool*, bool);
+bool atomic_compare_exchange_strong(atomic_bool*, bool*, bool);
+bool atomic_compare_exchange_weak_explicit(volatile atomic_bool*, bool*, bool,
+ memory_order, memory_order);
+bool atomic_compare_exchange_weak_explicit(atomic_bool*, bool*, bool,
+ memory_order, memory_order);
+bool atomic_compare_exchange_strong_explicit(volatile atomic_bool*, bool*, bool,
+ memory_order, memory_order);
+bool atomic_compare_exchange_strong_explicit(atomic_bool*, bool*, bool,
+ memory_order, memory_order);
+
+typedef struct atomic_bool
+{
+ bool __v_;
+
+ _LIBCPP_INLINE_VISIBILITY
+ bool is_lock_free() const volatile
+ {return atomic_is_lock_free(this);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool is_lock_free() const
+ {return atomic_is_lock_free(this);}
+ _LIBCPP_INLINE_VISIBILITY
+ void store(bool __v) volatile
+ {atomic_store(this, __v);}
+ _LIBCPP_INLINE_VISIBILITY
+ void store(bool __v, memory_order __o) volatile
+ {atomic_store_explicit(this, __v, __o);}
+ _LIBCPP_INLINE_VISIBILITY
+ void store(bool __v)
+ {atomic_store(this, __v);}
+ _LIBCPP_INLINE_VISIBILITY
+ void store(bool __v, memory_order __o)
+ {atomic_store_explicit(this, __v, __o);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool load() const volatile
+ {return atomic_load(this);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool load(memory_order __o) const volatile
+ {return atomic_load_explicit(this, __o);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool load() const
+ {return atomic_load(this);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool load(memory_order __o) const
+ {return atomic_load_explicit(this, __o);}
+ _LIBCPP_INLINE_VISIBILITY
+ operator bool() const volatile
+ {return load();}
+ _LIBCPP_INLINE_VISIBILITY
+ operator bool() const
+ {return load();}
+ _LIBCPP_INLINE_VISIBILITY
+ bool exchange(bool __v) volatile
+ {return atomic_exchange(this, __v);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool exchange(bool __v, memory_order __o) volatile
+ {return atomic_exchange_explicit(this, __v, __o);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool exchange(bool __v)
+ {return atomic_exchange(this, __v);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool exchange(bool __v, memory_order __o)
+ {return atomic_exchange_explicit(this, __v, __o);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_weak(bool& __v, bool __e, memory_order __s,
+ memory_order __f) volatile
+ {return atomic_compare_exchange_weak_explicit(this, &__v, __e, __s,
+ __f);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_weak(bool& __v, bool __e, memory_order __s) volatile
+ {return atomic_compare_exchange_weak_explicit(this, &__v, __e, __s,
+ __s);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_weak(bool& __v, bool __e) volatile
+ {return atomic_compare_exchange_weak(this, &__v, __e);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_weak(bool& __v, bool __e, memory_order __s,
+ memory_order __f)
+ {return atomic_compare_exchange_weak_explicit(this, &__v, __e, __s,
+ __f);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_weak(bool& __v, bool __e, memory_order __s)
+ {return atomic_compare_exchange_weak_explicit(this, &__v, __e, __s,
+ __s);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_weak(bool& __v, bool __e)
+ {return atomic_compare_exchange_weak(this, &__v, __e);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_strong(bool& __v, bool __e, memory_order __s,
+ memory_order __f) volatile
+ {return atomic_compare_exchange_strong_explicit(this, &__v, __e, __s,
+ __f);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_strong(bool& __v, bool __e, memory_order __s) volatile
+ {return atomic_compare_exchange_strong_explicit(this, &__v, __e, __s,
+ __s);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_strong(bool& __v, bool __e) volatile
+ {return atomic_compare_exchange_strong(this, &__v, __e);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_strong(bool& __v, bool __e, memory_order __s,
+ memory_order __f)
+ {return atomic_compare_exchange_strong_explicit(this, &__v, __e, __s,
+ __f);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_strong(bool& __v, bool __e, memory_order __s)
+ {return atomic_compare_exchange_strong_explicit(this, &__v, __e, __s,
+ __s);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool compare_exchange_strong(bool& __v, bool __e)
+ {return atomic_compare_exchange_strong(this, &__v, __e);}
+#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
+ atomic_bool() = default;
+#else
+ _LIBCPP_INLINE_VISIBILITY
+ atomic_bool() {}
+#endif
+ _LIBCPP_INLINE_VISIBILITY
+ /*constexpr*/ atomic_bool(bool __v)
+ : __v_(__v) {}
+#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
+ atomic_bool(const atomic_bool&) = delete;
+ atomic_bool& operator=(const atomic_bool&) = delete;
+ atomic_bool& operator=(const atomic_bool&) volatile = delete;
+#else
+private:
+ atomic_bool(const atomic_bool&);
+ atomic_bool& operator=(const atomic_bool&);
+ atomic_bool& operator=(const atomic_bool&) volatile;
+public:
+#endif
+ _LIBCPP_INLINE_VISIBILITY
+ bool operator=(bool __v) volatile
+ {store(__v); return __v;}
+} atomic_bool;
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_is_lock_free(const volatile atomic_bool*)
+{
+#if __has_feature(__atomic_store_seq_cst_b) && \
+ __has_feature(__atomic_load_seq_cst_b) && \
+ __has_feature(__atomic_exchange_seq_cst_b) && \
+ __has_feature(__atomic_compare_strong_weak_seq_cst_seq_cst_b)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_is_lock_free(const atomic_bool* __obj)
+{
+ return atomic_is_lock_free(const_cast<const volatile atomic_bool*>(__obj));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void atomic_init(volatile atomic_bool* __obj, bool __desr)
+{
+ __obj->__v_ = __desr;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void atomic_init(atomic_bool* __obj, bool __desr)
+{
+ __obj->__v_ = __desr;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void atomic_store(volatile atomic_bool* __obj, bool __desr)
+{
+ __choose_store_seq_cst(&__obj->__v_, __desr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void atomic_store(atomic_bool* __obj, bool __desr)
+{
+ atomic_store(const_cast<volatile atomic_bool*>(__obj), __desr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void atomic_store_explicit(volatile atomic_bool* __obj, bool __desr,
+ memory_order __o)
+{
+ switch (__o)
+ {
+ case memory_order_relaxed:
+ __choose_store_relaxed(&__obj->__v_, __desr);
+ break;
+ case memory_order_release:
+ __choose_store_release(&__obj->__v_, __desr);
+ break;
+ case memory_order_seq_cst:
+ __choose_store_seq_cst(&__obj->__v_, __desr);
+ break;
+ }
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void atomic_store_explicit(atomic_bool* __obj, bool __desr, memory_order __o)
+{
+ atomic_store_explicit(const_cast<volatile atomic_bool*>(__obj), __desr,
+ __o);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_load(const volatile atomic_bool* __obj)
+{
+ return __choose_load_seq_cst(&__obj->__v_);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_load(const atomic_bool* __obj)
+{
+ return atomic_load(const_cast<const volatile atomic_bool*>(__obj));
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_load_explicit(const volatile atomic_bool* __obj, memory_order __o)
+{
+ switch (__o)
+ {
+ case memory_order_relaxed:
+ return __choose_load_relaxed(&__obj->__v_);
+ case memory_order_consume:
+ return __choose_load_consume(&__obj->__v_);
+ case memory_order_acquire:
+ return __choose_load_acquire(&__obj->__v_);
+ case memory_order_seq_cst:
+ return __choose_load_seq_cst(&__obj->__v_);
+ }
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_load_explicit(const atomic_bool* __obj, memory_order __o)
+{
+ return atomic_load_explicit(const_cast<const volatile atomic_bool*>
+ (__obj), __o);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_exchange(volatile atomic_bool* __obj, bool __desr)
+{
+ return __choose_exchange_seq_cst(&__obj->__v_, __desr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_exchange(atomic_bool* __obj, bool __desr)
+{
+ return atomic_exchange(const_cast<volatile atomic_bool*>(__obj), __desr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_exchange_explicit(volatile atomic_bool* __obj, bool __desr,
+ memory_order __o)
+{
+ switch (__o)
+ {
+ case memory_order_relaxed:
+ return __choose_exchange_relaxed(&__obj->__v_, __desr);
+ case memory_order_consume:
+ return __choose_exchange_consume(&__obj->__v_, __desr);
+ case memory_order_acquire:
+ return __choose_exchange_acquire(&__obj->__v_, __desr);
+ case memory_order_release:
+ return __choose_exchange_release(&__obj->__v_, __desr);
+ case memory_order_acq_rel:
+ return __choose_exchange_acq_rel(&__obj->__v_, __desr);
+ case memory_order_seq_cst:
+ return __choose_exchange_seq_cst(&__obj->__v_, __desr);
+ }
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_exchange_explicit(atomic_bool* __obj, bool __desr, memory_order __o)
+{
+ return atomic_exchange_explicit(const_cast<volatile atomic_bool*>
+ (__obj), __desr, __o);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_compare_exchange_weak(volatile atomic_bool* __obj, bool* __exp,
+ bool __desr)
+{
+ return __choose_compare_exchange_weak_seq_cst_seq_cst(&__obj->__v_, __exp,
+ __desr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_compare_exchange_weak(atomic_bool* __obj, bool* __exp, bool __desr)
+{
+ return atomic_compare_exchange_weak(const_cast<volatile atomic_bool*>
+ (__obj), __exp, __desr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_compare_exchange_weak_explicit(volatile atomic_bool* __obj,
+ bool* __exp, bool __desr,
+ memory_order __s, memory_order __f)
+{
+ __f = __translate_memory_order(__f);
+ switch (__s)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_weak_relaxed_relaxed(&__obj->__v_,
+ __exp, __desr);
+ case memory_order_consume:
+ switch (__f)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_weak_consume_relaxed(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_consume:
+ return __choose_compare_exchange_weak_consume_consume(
+ &__obj->__v_, __exp, __desr);
+ }
+ case memory_order_acquire:
+ switch (__f)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_weak_acquire_relaxed(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_consume:
+ return __choose_compare_exchange_weak_acquire_consume(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_acquire:
+ return __choose_compare_exchange_weak_acquire_acquire(
+ &__obj->__v_, __exp, __desr);
+ }
+ case memory_order_release:
+ switch (__f)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_weak_release_relaxed(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_consume:
+ return __choose_compare_exchange_weak_release_consume(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_acquire:
+ return __choose_compare_exchange_weak_release_acquire(
+ &__obj->__v_, __exp, __desr);
+ }
+ case memory_order_acq_rel:
+ switch (__f)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_weak_acq_rel_relaxed(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_consume:
+ return __choose_compare_exchange_weak_acq_rel_consume(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_acquire:
+ return __choose_compare_exchange_weak_acq_rel_acquire(
+ &__obj->__v_, __exp, __desr);
+ }
+ case memory_order_seq_cst:
+ switch (__f)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_weak_seq_cst_relaxed(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_consume:
+ return __choose_compare_exchange_weak_seq_cst_consume(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_acquire:
+ return __choose_compare_exchange_weak_seq_cst_acquire(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_seq_cst:
+ return __choose_compare_exchange_weak_seq_cst_seq_cst(
+ &__obj->__v_, __exp, __desr);
+ }
+ }
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_compare_exchange_weak_explicit(atomic_bool* __obj, bool* __exp,
+ bool __desr,
+ memory_order __s, memory_order __f)
+{
+ return atomic_compare_exchange_weak_explicit(
+ const_cast<volatile atomic_bool*>(__obj), __exp, __desr, __s, __f);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_compare_exchange_strong(volatile atomic_bool* __obj, bool* __exp,
+ bool __desr)
+{
+ return __choose_compare_exchange_strong_seq_cst_seq_cst(&__obj->__v_, __exp,
+ __desr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_compare_exchange_strong(atomic_bool* __obj, bool* __exp,
+ bool __desr)
+{
+ return atomic_compare_exchange_strong(const_cast<volatile atomic_bool*>
+ (__obj), __exp, __desr);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_compare_exchange_strong_explicit(volatile atomic_bool* __obj,
+ bool* __exp, bool __desr,
+ memory_order __s, memory_order __f)
+{
+ __f = __translate_memory_order(__f);
+ switch (__s)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_strong_relaxed_relaxed(&__obj->__v_,
+ __exp, __desr);
+ case memory_order_consume:
+ switch (__f)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_strong_consume_relaxed(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_consume:
+ return __choose_compare_exchange_strong_consume_consume(
+ &__obj->__v_, __exp, __desr);
+ }
+ case memory_order_acquire:
+ switch (__f)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_strong_acquire_relaxed(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_consume:
+ return __choose_compare_exchange_strong_acquire_consume(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_acquire:
+ return __choose_compare_exchange_strong_acquire_acquire(
+ &__obj->__v_, __exp, __desr);
+ }
+ case memory_order_release:
+ switch (__f)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_strong_release_relaxed(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_consume:
+ return __choose_compare_exchange_strong_release_consume(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_acquire:
+ return __choose_compare_exchange_strong_release_acquire(
+ &__obj->__v_, __exp, __desr);
+ }
+ case memory_order_acq_rel:
+ switch (__f)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_strong_acq_rel_relaxed(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_consume:
+ return __choose_compare_exchange_strong_acq_rel_consume(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_acquire:
+ return __choose_compare_exchange_strong_acq_rel_acquire(
+ &__obj->__v_, __exp, __desr);
+ }
+ case memory_order_seq_cst:
+ switch (__f)
+ {
+ case memory_order_relaxed:
+ return __choose_compare_exchange_strong_seq_cst_relaxed(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_consume:
+ return __choose_compare_exchange_strong_seq_cst_consume(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_acquire:
+ return __choose_compare_exchange_strong_seq_cst_acquire(
+ &__obj->__v_, __exp, __desr);
+ case memory_order_seq_cst:
+ return __choose_compare_exchange_strong_seq_cst_seq_cst(
+ &__obj->__v_, __exp, __desr);
+ }
+ }
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+bool atomic_compare_exchange_strong_explicit(atomic_bool* __obj, bool* __exp,
+ bool __desr,
+ memory_order __s, memory_order __f)
+{
+ return atomic_compare_exchange_strong_explicit(
+ const_cast<volatile atomic_bool*>(__obj), __exp, __desr, __s, __f);
+}
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/src/atomic.cpp b/libcxx/src/atomic.cpp
new file mode 100644
index 00000000000..dc354df2303
--- /dev/null
+++ b/libcxx/src/atomic.cpp
@@ -0,0 +1,23 @@
+//===------------------------- atomic.cpp ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "__mutex_base"
+#include "atomic"
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_VISIBLE
+mutex&
+__not_atomic_mut()
+{
+ static mutex m;
+ return m;
+}
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp b/libcxx/test/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
index af3573bf9fd..61f5fd80723 100644
--- a/libcxx/test/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
+++ b/libcxx/test/atomics/atomics.flag/atomic_flag_clear_explicit.pass.cpp
@@ -28,12 +28,6 @@ int main()
{
std::atomic_flag f;
f.test_and_set();
- atomic_flag_clear_explicit(&f, std::memory_order_consume);
- assert(f.test_and_set() == 0);
- }
- {
- std::atomic_flag f;
- f.test_and_set();
atomic_flag_clear_explicit(&f, std::memory_order_release);
assert(f.test_and_set() == 0);
}
@@ -52,12 +46,6 @@ int main()
{
volatile std::atomic_flag f;
f.test_and_set();
- atomic_flag_clear_explicit(&f, std::memory_order_consume);
- assert(f.test_and_set() == 0);
- }
- {
- volatile std::atomic_flag f;
- f.test_and_set();
atomic_flag_clear_explicit(&f, std::memory_order_release);
assert(f.test_and_set() == 0);
}
diff --git a/libcxx/test/atomics/atomics.flag/clear.pass.cpp b/libcxx/test/atomics/atomics.flag/clear.pass.cpp
index 59c86a9330c..f019290ce4d 100644
--- a/libcxx/test/atomics/atomics.flag/clear.pass.cpp
+++ b/libcxx/test/atomics/atomics.flag/clear.pass.cpp
@@ -34,12 +34,6 @@ int main()
{
std::atomic_flag f;
f.test_and_set();
- f.clear(std::memory_order_consume);
- assert(f.test_and_set() == 0);
- }
- {
- std::atomic_flag f;
- f.test_and_set();
f.clear(std::memory_order_release);
assert(f.test_and_set() == 0);
}
@@ -64,12 +58,6 @@ int main()
{
volatile std::atomic_flag f;
f.test_and_set();
- f.clear(std::memory_order_consume);
- assert(f.test_and_set() == 0);
- }
- {
- volatile std::atomic_flag f;
- f.test_and_set();
f.clear(std::memory_order_release);
assert(f.test_and_set() == 0);
}
OpenPOWER on IntegriCloud