From 9cab8a9ebf4d21703f96edd03f34d1f166fc6520 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 15 Jun 2013 20:43:48 +0000 Subject: [PATCH] Added a generic atomic<> implementation based on the new __atomic intrinsics available in gcc 4.7 and clang 3.2. The new implementation adds support for 128-bit atomic. Other implementations updated to employ new macros in Boost.Config for defaulted and deleted functions (this is not complete yet). Fixed padding for the lock pool. Initializing constructor for atomic<> made explicit to avoid ambiguities of different overloads of operator=. [SVN r84800] --- include/boost/atomic/atomic.hpp | 34 +- include/boost/atomic/detail/base.hpp | 66 +- include/boost/atomic/detail/cas32strong.hpp | 42 +- include/boost/atomic/detail/cas32weak.hpp | 42 +- .../boost/atomic/detail/cas64strong-ptr.hpp | 12 +- include/boost/atomic/detail/cas64strong.hpp | 12 +- include/boost/atomic/detail/config.hpp | 6 +- include/boost/atomic/detail/gcc-alpha.hpp | 2 +- include/boost/atomic/detail/gcc-armv6plus.hpp | 2 +- include/boost/atomic/detail/gcc-atomic.hpp | 1176 +++++++++++++++++ include/boost/atomic/detail/gcc-cas.hpp | 2 +- include/boost/atomic/detail/gcc-ppc.hpp | 72 +- include/boost/atomic/detail/gcc-sparcv9.hpp | 52 +- include/boost/atomic/detail/gcc-x86.hpp | 69 +- include/boost/atomic/detail/generic-cas.hpp | 2 +- include/boost/atomic/detail/interlocked.hpp | 2 +- include/boost/atomic/detail/linux-arm.hpp | 2 +- include/boost/atomic/detail/lockpool.hpp | 15 +- include/boost/atomic/detail/platform.hpp | 8 +- .../atomic/detail/type-classification.hpp | 4 +- include/boost/atomic/detail/windows.hpp | 52 +- src/lockpool.cpp | 31 +- test/lockfree.cpp | 14 +- 23 files changed, 1640 insertions(+), 79 deletions(-) create mode 100644 include/boost/atomic/detail/gcc-atomic.hpp 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; }