diff --git a/include/boost/atomic/atomic.hpp b/include/boost/atomic/atomic.hpp index 9e1ecbd..1d16e07 100644 --- a/include/boost/atomic/atomic.hpp +++ b/include/boost/atomic/atomic.hpp @@ -22,7 +22,7 @@ #include #endif -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -112,11 +112,18 @@ private: mpl::and_< boost::is_integral, boost::is_signed >::value #endif > super; -public: - atomic(void) BOOST_NOEXCEPT : super() {} - BOOST_CONSTEXPR atomic(value_type v) BOOST_NOEXCEPT : super(v) {} + typedef typename super::value_arg_type value_arg_type; - value_type operator=(value_type v) volatile BOOST_NOEXCEPT +public: + BOOST_DEFAULTED_FUNCTION(atomic(void), BOOST_NOEXCEPT {}) + + // NOTE: The constructor is made explicit because gcc 4.7 complains that + // operator=(value_arg_type) is considered ambiguous with operator=(atomic const&) + // in assignment expressions, even though conversion to atomic<> is less preferred + // than conversion to value_arg_type. + explicit BOOST_CONSTEXPR atomic(value_arg_type v) BOOST_NOEXCEPT : super(v) {} + + value_type operator=(value_arg_type v) volatile BOOST_NOEXCEPT { this->store(v); return v; @@ -127,14 +134,9 @@ public: return this->load(); } -#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS -private: - atomic(const atomic &) /* =delete */ ; - atomic & operator=(const atomic &) volatile /* =delete */ ; -#else - atomic(const atomic &) = delete; - atomic & operator=(const atomic &) volatile = delete; -#endif + BOOST_DELETED_FUNCTION(atomic(atomic const&)) + BOOST_DELETED_FUNCTION(atomic& operator=(atomic const&)) + BOOST_DELETED_FUNCTION(atomic& operator=(atomic const&) volatile) }; typedef atomic atomic_char; @@ -229,9 +231,11 @@ public: { v_.store(false, order); } + + BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&)) + BOOST_DELETED_FUNCTION(atomic_flag& operator=(atomic_flag const&)) + private: - atomic_flag(const atomic_flag &) /* = delete */ ; - atomic_flag & operator=(const atomic_flag &) /* = delete */ ; atomic v_; }; #endif diff --git a/include/boost/atomic/detail/base.hpp b/include/boost/atomic/detail/base.hpp index 54dac60..ca5a45f 100644 --- a/include/boost/atomic/detail/base.hpp +++ b/include/boost/atomic/detail/base.hpp @@ -19,7 +19,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -155,13 +155,14 @@ namespace detail { inline memory_order calculate_failure_order(memory_order order) { - switch(order) { - case memory_order_acq_rel: - return memory_order_acquire; - case memory_order_release: - return memory_order_relaxed; - default: - return order; + switch(order) + { + case memory_order_acq_rel: + return memory_order_acquire; + case memory_order_release: + return memory_order_relaxed; + default: + return order; } } @@ -172,11 +173,12 @@ private: typedef base_atomic this_type; typedef T value_type; typedef lockpool::scoped_lock guard_type; - typedef char storage_type[sizeof(value_type)]; + +protected: + typedef value_type const& value_arg_type; public: - base_atomic(void) {} - + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(v) {} @@ -249,15 +251,16 @@ public: } BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: char * storage_ptr() volatile const BOOST_NOEXCEPT { return const_cast(&reinterpret_cast(v_)); } - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; - T v_; }; @@ -269,9 +272,13 @@ private: typedef T value_type; typedef T difference_type; typedef lockpool::scoped_lock guard_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -381,9 +388,11 @@ public: } BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -395,9 +404,13 @@ private: typedef T * value_type; typedef ptrdiff_t difference_type; typedef lockpool::scoped_lock guard_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -474,9 +487,11 @@ public: } BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; @@ -488,9 +503,13 @@ private: typedef ptrdiff_t difference_type; typedef void * value_type; typedef lockpool::scoped_lock guard_type; + +protected: + typedef value_type value_arg_type; + public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} - base_atomic(void) {} void store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -572,9 +591,10 @@ public: BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + private: - base_atomic(const base_atomic &) /* = delete */ ; - void operator=(const base_atomic &) /* = delete */ ; value_type v_; }; diff --git a/include/boost/atomic/detail/cas32strong.hpp b/include/boost/atomic/detail/cas32strong.hpp index ac66a12..1b4c0e5 100644 --- a/include/boost/atomic/detail/cas32strong.hpp +++ b/include/boost/atomic/detail/cas32strong.hpp @@ -18,7 +18,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -31,10 +31,15 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -159,10 +164,15 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -287,9 +297,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -412,9 +427,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef void * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -508,9 +528,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -606,9 +631,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { @@ -697,9 +727,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { @@ -789,9 +824,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { diff --git a/include/boost/atomic/detail/cas32weak.hpp b/include/boost/atomic/detail/cas32weak.hpp index de2314c..8a07dc0 100644 --- a/include/boost/atomic/detail/cas32weak.hpp +++ b/include/boost/atomic/detail/cas32weak.hpp @@ -15,7 +15,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -28,10 +28,15 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -164,10 +169,15 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -300,9 +310,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -433,9 +448,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef void * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -537,9 +557,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -643,9 +668,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { @@ -743,9 +773,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { @@ -843,9 +878,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { diff --git a/include/boost/atomic/detail/cas64strong-ptr.hpp b/include/boost/atomic/detail/cas64strong-ptr.hpp index a9f9a10..a1672e1 100644 --- a/include/boost/atomic/detail/cas64strong-ptr.hpp +++ b/include/boost/atomic/detail/cas64strong-ptr.hpp @@ -23,7 +23,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -36,9 +36,14 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef void * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -132,9 +137,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} diff --git a/include/boost/atomic/detail/cas64strong.hpp b/include/boost/atomic/detail/cas64strong.hpp index 20db427..51a78b0 100644 --- a/include/boost/atomic/detail/cas64strong.hpp +++ b/include/boost/atomic/detail/cas64strong.hpp @@ -18,7 +18,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -31,9 +31,14 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -156,9 +161,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint64_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { diff --git a/include/boost/atomic/detail/config.hpp b/include/boost/atomic/detail/config.hpp index 979bdd8..63af276 100644 --- a/include/boost/atomic/detail/config.hpp +++ b/include/boost/atomic/detail/config.hpp @@ -9,11 +9,7 @@ #include -#if (defined(_MSC_VER) && (_MSC_VER >= 1020)) || defined(__GNUC__) || defined(BOOST_CLANG) || defined(BOOST_INTEL) || defined(__COMO__) || defined(__DMC__) -#define BOOST_ATOMIC_HAS_PRAGMA_ONCE -#endif - -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif diff --git a/include/boost/atomic/detail/gcc-alpha.hpp b/include/boost/atomic/detail/gcc-alpha.hpp index 360a9db..2775499 100644 --- a/include/boost/atomic/detail/gcc-alpha.hpp +++ b/include/boost/atomic/detail/gcc-alpha.hpp @@ -12,7 +12,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif diff --git a/include/boost/atomic/detail/gcc-armv6plus.hpp b/include/boost/atomic/detail/gcc-armv6plus.hpp index c11e5cd..128f7ed 100644 --- a/include/boost/atomic/detail/gcc-armv6plus.hpp +++ b/include/boost/atomic/detail/gcc-armv6plus.hpp @@ -14,7 +14,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif diff --git a/include/boost/atomic/detail/gcc-atomic.hpp b/include/boost/atomic/detail/gcc-atomic.hpp new file mode 100644 index 0000000..95ffd59 --- /dev/null +++ b/include/boost/atomic/detail/gcc-atomic.hpp @@ -0,0 +1,1176 @@ +#ifndef BOOST_ATOMIC_DETAIL_GCC_ATOMIC_HPP +#define BOOST_ATOMIC_DETAIL_GCC_ATOMIC_HPP + +// Copyright (c) 2013 Andrey Semashev +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +#if (defined(__i386__) && defined(__SSE2__)) || defined(__x86_64__) +#define BOOST_ATOMIC_X86_PAUSE() __asm__ __volatile__ ("pause\n") +#endif + +#if defined(__i386__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) +#define BOOST_ATOMIC_X86_HAS_CMPXCHG8B 1 +#endif + +#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define BOOST_ATOMIC_X86_HAS_CMPXCHG16B 1 +#endif + +BOOST_FORCEINLINE BOOST_CONSTEXPR int convert_memory_order_to_gcc(memory_order order) BOOST_NOEXCEPT +{ + return (order == memory_order_relaxed ? __ATOMIC_RELAXED : (order == memory_order_consume ? __ATOMIC_CONSUME : + (order == memory_order_acquire ? __ATOMIC_ACQUIRE : (order == memory_order_release ? __ATOMIC_RELEASE : + (order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_SEQ_CST))))); +} + +} // namespace detail +} // namespace atomics + +#if __GCC_ATOMIC_BOOL_LOCK_FREE == 2 + +class atomic_flag +{ +private: + atomic_flag(const atomic_flag &) /* = delete */ ; + atomic_flag & operator=(const atomic_flag &) /* = delete */ ; + bool v_; + +public: + BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(false) {} + + bool test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_test_and_set(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_clear((bool*)&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } +}; + +#define BOOST_ATOMIC_FLAG_LOCK_FREE 2 + +#endif // __GCC_ATOMIC_BOOL_LOCK_FREE == 2 + +} // namespace boost + +#include + +#if !defined(BOOST_ATOMIC_FORCE_FALLBACK) + +#if __GCC_ATOMIC_CHAR_LOCK_FREE == 2 +#define BOOST_ATOMIC_CHAR_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_CHAR16_T_LOCK_FREE == 2 +#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_CHAR32_T_LOCK_FREE == 2 +#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_WCHAR_T_LOCK_FREE == 2 +#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_SHORT_LOCK_FREE == 2 +#define BOOST_ATOMIC_SHORT_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_INT_LOCK_FREE == 2 +#define BOOST_ATOMIC_INT_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_LONG_LOCK_FREE == 2 +#define BOOST_ATOMIC_LONG_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_LLONG_LOCK_FREE == 2 +#define BOOST_ATOMIC_LLONG_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_POINTER_LOCK_FREE == 2 +#define BOOST_ATOMIC_POINTER_LOCK_FREE 2 +#endif +#if __GCC_ATOMIC_BOOL_LOCK_FREE == 2 +#define BOOST_ATOMIC_BOOL_LOCK_FREE 2 +#endif + +namespace boost { + +#define BOOST_ATOMIC_THREAD_FENCE 2 +BOOST_FORCEINLINE void atomic_thread_fence(memory_order order) +{ + __atomic_thread_fence(atomics::detail::convert_memory_order_to_gcc(order)); +} + +#define BOOST_ATOMIC_SIGNAL_FENCE 2 +BOOST_FORCEINLINE void atomic_signal_fence(memory_order order) +{ + __atomic_signal_fence(atomics::detail::convert_memory_order_to_gcc(order)); +} + +namespace atomics { +namespace detail { + +#if defined(BOOST_ATOMIC_CHAR_LOCK_FREE) && BOOST_ATOMIC_CHAR_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_and(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_or(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef uint8_t storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : + v_(reinterpret_cast(v)) + {} + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store(&v_, (storage_type*)&v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + value_type v; + __atomic_load(&v_, (storage_type*)&v, atomics::detail::convert_memory_order_to_gcc(order)); + return v; + } + + value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type r; + __atomic_exchange(&v_, (storage_type*)&v, (storage_type*)&r, atomics::detail::convert_memory_order_to_gcc(order)); + return r; + } + + bool compare_exchange_strong( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange(&v_, (storage_type*)&expected, (storage_type*)&desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange(&v_, (storage_type*)&expected, (storage_type*)&desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#endif // defined(BOOST_ATOMIC_CHAR_LOCK_FREE) && BOOST_ATOMIC_CHAR_LOCK_FREE > 0 + +#if defined(BOOST_ATOMIC_SHORT_LOCK_FREE) && BOOST_ATOMIC_SHORT_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_and(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_or(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef uint16_t storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : + v_(reinterpret_cast(v)) + {} + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store(&v_, (storage_type*)&v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + value_type v; + __atomic_load(&v_, (storage_type*)&v, atomics::detail::convert_memory_order_to_gcc(order)); + return v; + } + + value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type r; + __atomic_exchange(&v_, (storage_type*)&v, (storage_type*)&r, atomics::detail::convert_memory_order_to_gcc(order)); + return r; + } + + bool compare_exchange_strong( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange(&v_, (storage_type*)&expected, (storage_type*)&desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange(&v_, (storage_type*)&expected, (storage_type*)&desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#endif // defined(BOOST_ATOMIC_SHORT_LOCK_FREE) && BOOST_ATOMIC_SHORT_LOCK_FREE > 0 + +#if defined(BOOST_ATOMIC_INT_LOCK_FREE) && BOOST_ATOMIC_INT_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_and(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_or(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + __atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + storage_type tmp = __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + value_type v; + memcpy(&v, &tmp, sizeof(value_type)); + return v; + } + + value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + value_type res; + memcpy(&res, &tmp, sizeof(value_type)); + return res; + } + + bool compare_exchange_strong( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool compare_exchange_weak( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#endif // defined(BOOST_ATOMIC_INT_LOCK_FREE) && BOOST_ATOMIC_INT_LOCK_FREE > 0 + +#if defined(BOOST_ATOMIC_LLONG_LOCK_FREE) && BOOST_ATOMIC_LLONG_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_and(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_or(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef uint64_t storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + __atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + storage_type tmp = __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + value_type v; + memcpy(&v, &tmp, sizeof(value_type)); + return v; + } + + value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + value_type res; + memcpy(&res, &tmp, sizeof(value_type)); + return res; + } + + bool compare_exchange_strong( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool compare_exchange_weak( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#endif // defined(BOOST_ATOMIC_LLONG_LOCK_FREE) && BOOST_ATOMIC_LLONG_LOCK_FREE > 0 + +#if defined(BOOST_ATOMIC_X86_HAS_CMPXCHG16B) && defined(BOOST_HAS_INT128) + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef T difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_and(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_or(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_xor(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef uint128_type storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + __atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + storage_type tmp = __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + value_type v; + memcpy(&v, &tmp, sizeof(value_type)); + return v; + } + + value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type tmp = 0; + memcpy(&tmp, &v, sizeof(value_type)); + tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order)); + value_type res; + memcpy(&res, &tmp, sizeof(value_type)); + return res; + } + + bool compare_exchange_strong( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool compare_exchange_weak( + value_type& expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + storage_type expected_s = 0, desired_s = 0; + memcpy(&expected_s, &expected, sizeof(value_type)); + memcpy(&desired_s, &desired, sizeof(value_type)); + const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + memcpy(&expected, &expected_s, sizeof(value_type)); + return success; + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_BASE_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + storage_type v_; +}; + +#endif // defined(BOOST_ATOMIC_X86_HAS_CMPXCHG16B) && defined(BOOST_HAS_INT128) + + +/* pointers */ + +#if defined(BOOST_ATOMIC_POINTER_LOCK_FREE) && BOOST_ATOMIC_POINTER_LOCK_FREE > 0 + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T* value_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v * sizeof(T), atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v * sizeof(T), atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef void* value_type; + typedef std::ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + +public: + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + + void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + __atomic_store_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + return __atomic_load_n(&v_, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_add(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_fetch_sub(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + return __atomic_exchange_n(&v_, v, atomics::detail::convert_memory_order_to_gcc(order)); + } + + bool compare_exchange_strong( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, false, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool compare_exchange_weak( + value_type& expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return __atomic_compare_exchange_n(&v_, &expected, desired, true, + atomics::detail::convert_memory_order_to_gcc(success_order), + atomics::detail::convert_memory_order_to_gcc(failure_order)); + } + + bool is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return __atomic_is_lock_free(sizeof(v_), &v_); + } + + BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS + + BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&)) + BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&)) + +private: + value_type v_; +}; + +#endif // defined(BOOST_ATOMIC_POINTER_LOCK_FREE) && BOOST_ATOMIC_POINTER_LOCK_FREE > 0 + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // !defined(BOOST_ATOMIC_FORCE_FALLBACK) + +#endif // BOOST_ATOMIC_DETAIL_GCC_ATOMIC_HPP diff --git a/include/boost/atomic/detail/gcc-cas.hpp b/include/boost/atomic/detail/gcc-cas.hpp index 446da37..55e2132 100644 --- a/include/boost/atomic/detail/gcc-cas.hpp +++ b/include/boost/atomic/detail/gcc-cas.hpp @@ -15,7 +15,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif diff --git a/include/boost/atomic/detail/gcc-ppc.hpp b/include/boost/atomic/detail/gcc-ppc.hpp index aaeeb96..0be626b 100644 --- a/include/boost/atomic/detail/gcc-ppc.hpp +++ b/include/boost/atomic/detail/gcc-ppc.hpp @@ -12,7 +12,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -199,10 +199,15 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef int32_t storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -420,10 +425,15 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -642,10 +652,15 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef int32_t storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -864,10 +879,15 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -1086,9 +1106,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -1303,9 +1328,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -1524,9 +1554,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef ptrdiff_t difference_type; typedef void * value_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -1690,9 +1725,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -1860,9 +1900,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef ptrdiff_t difference_type; typedef void * value_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -2026,9 +2071,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -2198,9 +2248,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { @@ -2349,9 +2404,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { @@ -2501,9 +2561,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { @@ -2655,9 +2720,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint64_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { diff --git a/include/boost/atomic/detail/gcc-sparcv9.hpp b/include/boost/atomic/detail/gcc-sparcv9.hpp index b524403..a76d2e3 100644 --- a/include/boost/atomic/detail/gcc-sparcv9.hpp +++ b/include/boost/atomic/detail/gcc-sparcv9.hpp @@ -12,7 +12,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -177,10 +177,15 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef int32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -300,10 +305,15 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -423,10 +433,15 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef int32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -546,10 +561,15 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; typedef uint32_t storage_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -669,9 +689,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -791,9 +816,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef ptrdiff_t difference_type; typedef void * value_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -885,9 +915,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -983,9 +1018,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { @@ -1073,9 +1113,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { @@ -1163,9 +1208,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { diff --git a/include/boost/atomic/detail/gcc-x86.hpp b/include/boost/atomic/detail/gcc-x86.hpp index 1067921..c776a37 100644 --- a/include/boost/atomic/detail/gcc-x86.hpp +++ b/include/boost/atomic/detail/gcc-x86.hpp @@ -12,7 +12,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -37,6 +37,10 @@ namespace detail { #define BOOST_ATOMIC_X86_HAS_CMPXCHG8B 1 #endif +#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define BOOST_ATOMIC_X86_HAS_CMPXCHG16B 1 +#endif + inline void platform_fence_before(memory_order order) { @@ -257,9 +261,14 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -395,9 +404,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -533,9 +547,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -672,9 +691,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -811,14 +835,20 @@ private: /* pointers */ -#if !defined(__x86_64__) +// NOTE: x32 target is still regarded to as x86_64 and can only be detected by the size of pointers +#if !defined(__x86_64__) || (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 4) template class base_atomic { +private: typedef base_atomic this_type; typedef ptrdiff_t difference_type; typedef void * value_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -913,9 +943,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -1021,9 +1056,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef ptrdiff_t difference_type; typedef void * value_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -1118,9 +1158,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T * value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} base_atomic(void) {} @@ -1226,9 +1271,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint8_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast(v)) @@ -1326,9 +1376,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint16_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast(v)) @@ -1426,9 +1481,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { @@ -1528,9 +1588,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint64_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { diff --git a/include/boost/atomic/detail/generic-cas.hpp b/include/boost/atomic/detail/generic-cas.hpp index f8cc3cc..cf4a3d7 100644 --- a/include/boost/atomic/detail/generic-cas.hpp +++ b/include/boost/atomic/detail/generic-cas.hpp @@ -14,7 +14,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif diff --git a/include/boost/atomic/detail/interlocked.hpp b/include/boost/atomic/detail/interlocked.hpp index 74285e7..ae8518d 100644 --- a/include/boost/atomic/detail/interlocked.hpp +++ b/include/boost/atomic/detail/interlocked.hpp @@ -10,7 +10,7 @@ #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif diff --git a/include/boost/atomic/detail/linux-arm.hpp b/include/boost/atomic/detail/linux-arm.hpp index af1606e..ed9a73b 100644 --- a/include/boost/atomic/detail/linux-arm.hpp +++ b/include/boost/atomic/detail/linux-arm.hpp @@ -36,7 +36,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif diff --git a/include/boost/atomic/detail/lockpool.hpp b/include/boost/atomic/detail/lockpool.hpp index b86cfae..c878926 100644 --- a/include/boost/atomic/detail/lockpool.hpp +++ b/include/boost/atomic/detail/lockpool.hpp @@ -12,7 +12,7 @@ #include #endif -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -31,9 +31,6 @@ public: private: lock_type& mtx_; - scoped_lock(scoped_lock const&) /* = delete */; - scoped_lock& operator=(scoped_lock const&) /* = delete */; - public: explicit scoped_lock(const volatile void * addr) : mtx_(get_lock_for(addr)) @@ -44,6 +41,9 @@ public: { mtx_.unlock(); } + + BOOST_DELETED_FUNCTION(scoped_lock(scoped_lock const&)) + BOOST_DELETED_FUNCTION(scoped_lock& operator=(scoped_lock const&)) }; private: @@ -61,10 +61,6 @@ public: { private: atomic_flag& flag_; - uint8_t padding[128 - sizeof(atomic_flag)]; - - scoped_lock(const scoped_lock &) /* = delete */; - scoped_lock& operator=(const scoped_lock &) /* = delete */; public: explicit @@ -82,6 +78,9 @@ public: { flag_.clear(memory_order_release); } + + BOOST_DELETED_FUNCTION(scoped_lock(const scoped_lock &)) + BOOST_DELETED_FUNCTION(scoped_lock& operator=(const scoped_lock &)) }; private: diff --git a/include/boost/atomic/detail/platform.hpp b/include/boost/atomic/detail/platform.hpp index a31ecec..9a59444 100644 --- a/include/boost/atomic/detail/platform.hpp +++ b/include/boost/atomic/detail/platform.hpp @@ -11,11 +11,15 @@ #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407)) || (defined(BOOST_CLANG) && ((__clang_major__ * 100 + __clang_minor__) >= 302)) + + #include + +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) #include diff --git a/include/boost/atomic/detail/type-classification.hpp b/include/boost/atomic/detail/type-classification.hpp index f7c2f8b..98bc311 100644 --- a/include/boost/atomic/detail/type-classification.hpp +++ b/include/boost/atomic/detail/type-classification.hpp @@ -10,7 +10,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -36,7 +36,7 @@ struct storage_size_of enum _ { size = sizeof(T), - value = (size == 3 ? 4 : (size == 5 || size == 6 || size == 7 ? 8 : size)) + value = (size == 3 ? 4 : (size >= 5 && size <= 7 ? 8 : (size >= 9 && size <= 15 ? 16 : size))) }; }; diff --git a/include/boost/atomic/detail/windows.hpp b/include/boost/atomic/detail/windows.hpp index 21e26fc..05c3397 100644 --- a/include/boost/atomic/detail/windows.hpp +++ b/include/boost/atomic/detail/windows.hpp @@ -15,7 +15,7 @@ #include #include -#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE +#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif @@ -204,6 +204,7 @@ namespace detail { template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; #ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 @@ -212,6 +213,10 @@ class base_atomic typedef uint32_t storage_type; #endif typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} base_atomic(void) {} @@ -390,6 +395,7 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; #ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 @@ -398,6 +404,10 @@ class base_atomic typedef uint32_t storage_type; #endif typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} base_atomic(void) {} @@ -572,10 +582,15 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef value_type storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} base_atomic(void) {} @@ -726,9 +741,14 @@ enum msvc_sizeof_pointer_workaround { sizeof_pointer = sizeof(void*) }; template class base_atomic { +private: typedef base_atomic this_type; typedef ptrdiff_t difference_type; typedef void* value_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} base_atomic(void) {} @@ -813,9 +833,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T* value_type; typedef ptrdiff_t difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} base_atomic(void) {} @@ -910,6 +935,7 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; #ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 @@ -917,6 +943,10 @@ class base_atomic #else typedef uint32_t storage_type; #endif + +protected: + typedef value_type const& value_arg_type; + public: #ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast< storage_type const& >(v)) @@ -1021,6 +1051,7 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; #ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 @@ -1028,6 +1059,10 @@ class base_atomic #else typedef uint32_t storage_type; #endif + +protected: + typedef value_type const& value_arg_type; + public: #ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast< storage_type const& >(v)) @@ -1133,9 +1168,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint32_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) : v_(0) { @@ -1228,10 +1268,15 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef value_type storage_type; typedef T difference_type; + +protected: + typedef value_type value_arg_type; + public: BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT: v_(v) {} base_atomic(void) {} @@ -1379,9 +1424,14 @@ private: template class base_atomic { +private: typedef base_atomic this_type; typedef T value_type; typedef uint64_t storage_type; + +protected: + typedef value_type const& value_arg_type; + public: explicit base_atomic(value_type const& v) : v_(0) { diff --git a/src/lockpool.cpp b/src/lockpool.cpp index da8e89a..c269103 100644 --- a/src/lockpool.cpp +++ b/src/lockpool.cpp @@ -1,3 +1,4 @@ +#include #include // Copyright (c) 2011 Helge Bahmann @@ -10,13 +11,39 @@ namespace boost { namespace atomics { namespace detail { -static lockpool::lock_type lock_pool_[41]; +namespace { + +// This seems to be the maximum across all modern CPUs +enum { cache_line_size = 64 }; + +template< unsigned int N > +struct padding +{ + char data[N]; +}; +template< > +struct padding< 0 > +{ +}; + +struct BOOST_ALIGNMENT(cache_line_size) padded_lock +{ + lockpool::lock_type lock; + // The additional padding is needed to avoid false sharing between locks + enum { padding_size = (sizeof(lockpool::lock_type) <= cache_line_size ? (cache_line_size - sizeof(lockpool::lock_type)) : (cache_line_size - sizeof(lockpool::lock_type) % cache_line_size)) }; + padding< padding_size > pad; +}; + +static padded_lock lock_pool_[41]; + +} // namespace + // NOTE: This function must NOT be inline. Otherwise MSVC 9 will sometimes generate broken code for modulus operation which result in crashes. BOOST_ATOMIC_DECL lockpool::lock_type& lockpool::get_lock_for(const volatile void* addr) { std::size_t index = reinterpret_cast(addr) % (sizeof(lock_pool_) / sizeof(*lock_pool_)); - return lock_pool_[index]; + return lock_pool_[index].lock; } } diff --git a/test/lockfree.cpp b/test/lockfree.cpp index 0a1905b..cea7df3 100644 --- a/test/lockfree.cpp +++ b/test/lockfree.cpp @@ -172,14 +172,14 @@ int test_main(int, char *[]) verify_lock_free("bool", BOOST_ATOMIC_BOOL_LOCK_FREE, EXPECT_BOOL_LOCK_FREE); bool any_lock_free = - BOOST_ATOMIC_CHAR_LOCK_FREE || - BOOST_ATOMIC_SHORT_LOCK_FREE || - BOOST_ATOMIC_INT_LOCK_FREE || - BOOST_ATOMIC_LONG_LOCK_FREE || - BOOST_ATOMIC_LLONG_LOCK_FREE || - BOOST_ATOMIC_BOOL_LOCK_FREE; + BOOST_ATOMIC_CHAR_LOCK_FREE > 0 || + BOOST_ATOMIC_SHORT_LOCK_FREE > 0 || + BOOST_ATOMIC_INT_LOCK_FREE > 0 || + BOOST_ATOMIC_LONG_LOCK_FREE > 0 || + BOOST_ATOMIC_LLONG_LOCK_FREE > 0 || + BOOST_ATOMIC_BOOL_LOCK_FREE > 0; - BOOST_CHECK(!any_lock_free || BOOST_ATOMIC_THREAD_FENCE); + BOOST_CHECK(!any_lock_free || BOOST_ATOMIC_THREAD_FENCE > 0); return 0; }