// -*- C++ -*- header.
-// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
#include <bits/c++config.h>
#include <stdbool.h>
#include <stdint.h>
+#include <bits/atomic_lockfree_defines.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
memory_order_seq_cst
} memory_order;
- inline memory_order
- __calculate_memory_order(memory_order __m) noexcept
+ // Drop release ordering as per [atomics.types.operations.req]/21
+ constexpr memory_order
+ __cmpexch_failure_order(memory_order __m) noexcept
{
- const bool __cond1 = __m == memory_order_release;
- const bool __cond2 = __m == memory_order_acq_rel;
- memory_order __mo1(__cond1 ? memory_order_relaxed : __m);
- memory_order __mo2(__cond2 ? memory_order_acquire : __mo1);
- return __mo2;
+ return __m == memory_order_acq_rel ? memory_order_acquire
+ : __m == memory_order_release ? memory_order_relaxed : __m;
}
inline void
atomic_thread_fence(memory_order __m) noexcept
- {
- __atomic_thread_fence (__m);
- }
+ { __atomic_thread_fence(__m); }
inline void
atomic_signal_fence(memory_order __m) noexcept
- {
- __atomic_thread_fence (__m);
- }
+ { __atomic_signal_fence(__m); }
/// kill_dependency
template<typename _Tp>
return __ret;
}
- /// Lock-free Property
-
-#define LOCKFREE_PROP(T) (__atomic_always_lock_free (sizeof (T), 0) ? 2 : 1)
-
-#define ATOMIC_CHAR_LOCK_FREE LOCKFREE_PROP (char)
-#define ATOMIC_CHAR16_T_LOCK_FREE LOCKFREE_PROP (char16_t)
-#define ATOMIC_CHAR32_T_LOCK_FREE LOCKFREE_PROP (char32_t)
-#define ATOMIC_WCHAR_T_LOCK_FREE LOCKFREE_PROP (wchar_t)
-#define ATOMIC_SHORT_LOCK_FREE LOCKFREE_PROP (short)
-#define ATOMIC_INT_LOCK_FREE LOCKFREE_PROP (int)
-#define ATOMIC_LONG_LOCK_FREE LOCKFREE_PROP (long)
-#define ATOMIC_LLONG_LOCK_FREE LOCKFREE_PROP (long long)
-
// Base types for atomics.
template<typename _IntTp>
struct __atomic_flag_base
{
+ /* The target's "set" value for test-and-set may not be exactly 1. */
+#if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1
bool _M_i;
+#else
+ unsigned char _M_i;
+#endif
};
_GLIBCXX_END_EXTERN_C
-#define ATOMIC_FLAG_INIT { false }
+#define ATOMIC_FLAG_INIT { 0 }
/// atomic_flag
struct atomic_flag : public __atomic_flag_base
atomic_flag& operator=(const atomic_flag&) volatile = delete;
// Conversion to ATOMIC_FLAG_INIT.
- atomic_flag(bool __i) noexcept : __atomic_flag_base({ __i }) { }
+ constexpr atomic_flag(bool __i) noexcept
+ : __atomic_flag_base({ __i ? __GCC_ATOMIC_TEST_AND_SET_TRUEVAL : 0 })
+ { }
bool
test_and_set(memory_order __m = memory_order_seq_cst) noexcept
memory_order __m = memory_order_seq_cst) noexcept
{
return compare_exchange_weak(__i1, __i2, __m,
- __calculate_memory_order(__m));
+ __cmpexch_failure_order(__m));
}
bool
memory_order __m = memory_order_seq_cst) volatile noexcept
{
return compare_exchange_weak(__i1, __i2, __m,
- __calculate_memory_order(__m));
+ __cmpexch_failure_order(__m));
}
bool
memory_order __m = memory_order_seq_cst) noexcept
{
return compare_exchange_strong(__i1, __i2, __m,
- __calculate_memory_order(__m));
+ __cmpexch_failure_order(__m));
}
bool
memory_order __m = memory_order_seq_cst) volatile noexcept
{
return compare_exchange_strong(__i1, __i2, __m,
- __calculate_memory_order(__m));
+ __cmpexch_failure_order(__m));
}
__int_type
__pointer_type _M_p;
+ // Factored out to facilitate explicit specialization.
+ constexpr ptrdiff_t
+ _M_type_size(ptrdiff_t __d) { return __d * sizeof(_PTp); }
+
+ constexpr ptrdiff_t
+ _M_type_size(ptrdiff_t __d) volatile { return __d * sizeof(_PTp); }
+
public:
__atomic_base() noexcept = default;
~__atomic_base() noexcept = default;
__pointer_type
operator++() noexcept
- { return __atomic_add_fetch(&_M_p, 1, memory_order_seq_cst); }
+ { return __atomic_add_fetch(&_M_p, _M_type_size(1),
+ memory_order_seq_cst); }
__pointer_type
operator++() volatile noexcept
- { return __atomic_add_fetch(&_M_p, 1, memory_order_seq_cst); }
+ { return __atomic_add_fetch(&_M_p, _M_type_size(1),
+ memory_order_seq_cst); }
__pointer_type
operator--() noexcept
- { return __atomic_sub_fetch(&_M_p, 1, memory_order_seq_cst); }
+ { return __atomic_sub_fetch(&_M_p, _M_type_size(1),
+ memory_order_seq_cst); }
__pointer_type
operator--() volatile noexcept
- { return __atomic_sub_fetch(&_M_p, 1, memory_order_seq_cst); }
+ { return __atomic_sub_fetch(&_M_p, _M_type_size(1),
+ memory_order_seq_cst); }
__pointer_type
operator+=(ptrdiff_t __d) noexcept
- { return __atomic_add_fetch(&_M_p, __d, memory_order_seq_cst); }
+ { return __atomic_add_fetch(&_M_p, _M_type_size(__d),
+ memory_order_seq_cst); }
__pointer_type
operator+=(ptrdiff_t __d) volatile noexcept
- { return __atomic_add_fetch(&_M_p, __d, memory_order_seq_cst); }
+ { return __atomic_add_fetch(&_M_p, _M_type_size(__d),
+ memory_order_seq_cst); }
__pointer_type
operator-=(ptrdiff_t __d) noexcept
- { return __atomic_sub_fetch(&_M_p, __d, memory_order_seq_cst); }
+ { return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
+ memory_order_seq_cst); }
__pointer_type
operator-=(ptrdiff_t __d) volatile noexcept
- { return __atomic_sub_fetch(&_M_p, __d, memory_order_seq_cst); }
+ { return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
+ memory_order_seq_cst); }
bool
is_lock_free() const noexcept
- { return __atomic_is_lock_free (sizeof (_M_p), &_M_p); }
+ { return __atomic_is_lock_free(_M_type_size(1), &_M_p); }
bool
is_lock_free() const volatile noexcept
- { return __atomic_is_lock_free (sizeof (_M_p), &_M_p); }
+ { return __atomic_is_lock_free(_M_type_size(1), &_M_p); }
void
store(__pointer_type __p,
__pointer_type
fetch_add(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) noexcept
- { return __atomic_fetch_add(&_M_p, __d, __m); }
+ { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
__pointer_type
fetch_add(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) volatile noexcept
- { return __atomic_fetch_add(&_M_p, __d, __m); }
+ { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
__pointer_type
fetch_sub(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) noexcept
- { return __atomic_fetch_sub(&_M_p, __d, __m); }
+ { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
__pointer_type
fetch_sub(ptrdiff_t __d,
memory_order __m = memory_order_seq_cst) volatile noexcept
- { return __atomic_fetch_sub(&_M_p, __d, __m); }
+ { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
};
// @} group atomics