From 55e8b16a12cc21fc4ffec0759031d2e84dc47938 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sun, 16 Jun 2013 13:40:11 +0000 Subject: [PATCH] Fixed compilation with gcc 4.4. Optimized code for gcc older than 4.7 and also added support for 128-bit atomic ops. Completed transition to defaulted and deleted functions. [SVN r84801] --- include/boost/atomic/atomic.hpp | 4 + include/boost/atomic/detail/cas128strong.hpp | 285 +++++++++++ include/boost/atomic/detail/cas32strong.hpp | 67 ++- include/boost/atomic/detail/cas32weak.hpp | 115 +++-- .../boost/atomic/detail/cas64strong-ptr.hpp | 16 +- include/boost/atomic/detail/cas64strong.hpp | 16 +- include/boost/atomic/detail/gcc-armv6plus.hpp | 1 + include/boost/atomic/detail/gcc-atomic.hpp | 61 ++- include/boost/atomic/detail/gcc-cas.hpp | 64 +-- include/boost/atomic/detail/gcc-ppc.hpp | 199 +++++--- include/boost/atomic/detail/gcc-sparcv9.hpp | 189 ++++--- include/boost/atomic/detail/gcc-x86.hpp | 481 ++++++++++++------ include/boost/atomic/detail/linux-arm.hpp | 1 + include/boost/atomic/detail/windows.hpp | 83 +-- src/lockpool.cpp | 9 +- test/api_test_helpers.hpp | 4 +- test/native_api.cpp | 8 + 17 files changed, 1125 insertions(+), 478 deletions(-) create mode 100644 include/boost/atomic/detail/cas128strong.hpp diff --git a/include/boost/atomic/atomic.hpp b/include/boost/atomic/atomic.hpp index 1d16e07..ba1366f 100644 --- a/include/boost/atomic/atomic.hpp +++ b/include/boost/atomic/atomic.hpp @@ -60,6 +60,10 @@ namespace boost { #define BOOST_ATOMIC_LLONG_LOCK_FREE 0 #endif +#ifndef BOOST_ATOMIC_INT128_LOCK_FREE +#define BOOST_ATOMIC_INT128_LOCK_FREE 0 +#endif + #ifndef BOOST_ATOMIC_POINTER_LOCK_FREE #define BOOST_ATOMIC_POINTER_LOCK_FREE 0 #endif diff --git a/include/boost/atomic/detail/cas128strong.hpp b/include/boost/atomic/detail/cas128strong.hpp new file mode 100644 index 0000000..66ef47b --- /dev/null +++ b/include/boost/atomic/detail/cas128strong.hpp @@ -0,0 +1,285 @@ +#ifndef BOOST_ATOMIC_DETAIL_CAS128STRONG_HPP +#define BOOST_ATOMIC_DETAIL_CAS128STRONG_HPP + +// 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) +// +// Copyright (c) 2011 Helge Bahmann +// Copyright (c) 2013 Tim Blechmann, Andrey Semashev + +// Build 128-bit atomic operation on integers/UDTs from platform_cmpxchg128_strong +// primitive. It is assumed that 128-bit loads/stores are not +// atomic, so they are implemented through platform_load128/platform_store128. + +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +/* integral types */ + +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_DEFAULTED_FUNCTION(base_atomic(void), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} + + void + store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + platform_fence_before_store(order); + platform_store128(v, &v_); + platform_fence_after_store(order); + } + + value_type + load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + value_type v = platform_load128(&v_); + platform_fence_after_load(order); + return v; + } + + value_type + exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); + return original; + } + + bool + compare_exchange_weak( + value_type & expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + bool + compare_exchange_strong( + value_type & expected, + value_type desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + platform_fence_before(success_order); + + bool success = platform_cmpxchg128_strong(expected, desired, &v_); + + if (success) { + platform_fence_after(success_order); + } else { + platform_fence_after(failure_order); + } + + return success; + } + + value_type + fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed)); + return original; + } + + value_type + fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed)); + return original; + } + + value_type + fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed)); + return original; + } + + value_type + fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed)); + return original; + } + + value_type + fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed)); + return original; + } + + bool + is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return true; + } + + 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_; +}; + +/* generic types */ + +#if defined(BOOST_HAS_INT128) + +typedef boost::uint128_type storage128_type; + +#else // defined(BOOST_HAS_INT128) + +struct BOOST_ALIGNMENT(16) storage128_type +{ + uint64_t data[2]; +}; + +inline bool operator== (storage128_type const& left, storage128_type const& right) +{ + return left.data[0] == right.data[0] && left.data[1] == right.data[1]; +} +inline bool operator!= (storage128_type const& left, storage128_type const& right) +{ + return !(left == right); +} + +#endif // defined(BOOST_HAS_INT128) + +template +class base_atomic +{ +private: + typedef base_atomic this_type; + typedef T value_type; + typedef storage128_type storage_type; + +protected: + typedef value_type const& value_arg_type; + +public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) + { + memcpy(&v_, &v, sizeof(value_type)); + } + + void + store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + storage_type value_s = 0; + memcpy(&value_s, &value, sizeof(value_type)); + platform_fence_before_store(order); + platform_store128(value_s, &v_); + platform_fence_after_store(order); + } + + value_type + load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT + { + storage_type value_s = platform_load128(&v_); + platform_fence_after_load(order); + value_type value; + memcpy(&value, &value_s, sizeof(value_type)); + return value; + } + + value_type + exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT + { + value_type original = load(memory_order_relaxed); + do { + } while (!compare_exchange_weak(original, v, order, memory_order_relaxed)); + return original; + } + + bool + compare_exchange_weak( + value_type & expected, + value_type const& desired, + memory_order success_order, + memory_order failure_order) volatile BOOST_NOEXCEPT + { + return compare_exchange_strong(expected, desired, success_order, failure_order); + } + + 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)); + + platform_fence_before(success_order); + bool success = platform_cmpxchg128_strong(expected_s, desired_s, &v_); + + if (success) { + platform_fence_after(success_order); + } else { + platform_fence_after(failure_order); + memcpy(&expected, &expected_s, sizeof(value_type)); + } + + return success; + } + + bool + is_lock_free(void) const volatile BOOST_NOEXCEPT + { + return true; + } + + 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 diff --git a/include/boost/atomic/detail/cas32strong.hpp b/include/boost/atomic/detail/cas32strong.hpp index 1b4c0e5..a6a0e06 100644 --- a/include/boost/atomic/detail/cas32strong.hpp +++ b/include/boost/atomic/detail/cas32strong.hpp @@ -41,8 +41,8 @@ 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 @@ -155,9 +155,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 */ ; storage_type v_; }; @@ -174,8 +176,8 @@ 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 @@ -288,9 +290,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 */ ; storage_type v_; }; @@ -306,8 +310,8 @@ 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 @@ -416,9 +420,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_; }; @@ -436,8 +442,8 @@ 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 @@ -519,9 +525,11 @@ 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_; }; @@ -537,8 +545,8 @@ 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 @@ -620,9 +628,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_; }; @@ -640,13 +650,12 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT { @@ -718,9 +727,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -736,13 +747,12 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT { @@ -815,9 +825,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -833,13 +845,12 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -912,9 +923,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; diff --git a/include/boost/atomic/detail/cas32weak.hpp b/include/boost/atomic/detail/cas32weak.hpp index 8a07dc0..bc35670 100644 --- a/include/boost/atomic/detail/cas32weak.hpp +++ b/include/boost/atomic/detail/cas32weak.hpp @@ -38,8 +38,8 @@ 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 @@ -97,11 +97,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -160,9 +162,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 */ ; storage_type v_; }; @@ -179,8 +183,8 @@ 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 @@ -238,11 +242,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -301,9 +307,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 */ ; storage_type v_; }; @@ -319,8 +327,8 @@ 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 @@ -374,11 +382,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -437,9 +447,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_; }; @@ -457,8 +469,8 @@ 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 @@ -512,11 +524,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -548,9 +562,11 @@ 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_; }; @@ -566,8 +582,8 @@ 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 @@ -621,11 +637,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -657,9 +675,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_; }; @@ -677,13 +697,12 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -746,11 +765,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -764,9 +785,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -782,13 +805,12 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -851,11 +873,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -869,9 +893,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -887,13 +913,12 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -956,11 +981,13 @@ public: memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT { - for(;;) { + while (true) + { value_type tmp = expected; if (compare_exchange_weak(tmp, desired, success_order, failure_order)) return true; - if (tmp != expected) { + if (tmp != expected) + { expected = tmp; return false; } @@ -974,9 +1001,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; diff --git a/include/boost/atomic/detail/cas64strong-ptr.hpp b/include/boost/atomic/detail/cas64strong-ptr.hpp index a1672e1..49258ef 100644 --- a/include/boost/atomic/detail/cas64strong-ptr.hpp +++ b/include/boost/atomic/detail/cas64strong-ptr.hpp @@ -45,8 +45,8 @@ 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 @@ -128,9 +128,11 @@ 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_; }; @@ -146,8 +148,8 @@ 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 @@ -229,9 +231,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_; }; diff --git a/include/boost/atomic/detail/cas64strong.hpp b/include/boost/atomic/detail/cas64strong.hpp index 51a78b0..91c10ef 100644 --- a/include/boost/atomic/detail/cas64strong.hpp +++ b/include/boost/atomic/detail/cas64strong.hpp @@ -40,8 +40,8 @@ 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 @@ -150,9 +150,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_; }; @@ -170,11 +172,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -246,9 +248,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; diff --git a/include/boost/atomic/detail/gcc-armv6plus.hpp b/include/boost/atomic/detail/gcc-armv6plus.hpp index 128f7ed..65266b0 100644 --- a/include/boost/atomic/detail/gcc-armv6plus.hpp +++ b/include/boost/atomic/detail/gcc-armv6plus.hpp @@ -222,6 +222,7 @@ public: return expected; } }; + #define BOOST_ATOMIC_FLAG_LOCK_FREE 2 } diff --git a/include/boost/atomic/detail/gcc-atomic.hpp b/include/boost/atomic/detail/gcc-atomic.hpp index 95ffd59..c5901ba 100644 --- a/include/boost/atomic/detail/gcc-atomic.hpp +++ b/include/boost/atomic/detail/gcc-atomic.hpp @@ -98,6 +98,9 @@ public: #if __GCC_ATOMIC_LLONG_LOCK_FREE == 2 #define BOOST_ATOMIC_LLONG_LOCK_FREE 2 #endif +#if defined(BOOST_ATOMIC_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT)) +#define BOOST_ATOMIC_INT128_LOCK_FREE 2 +#endif #if __GCC_ATOMIC_POINTER_LOCK_FREE == 2 #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 #endif @@ -136,8 +139,8 @@ 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), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -227,10 +230,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) 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 { @@ -303,8 +307,8 @@ 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), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -394,10 +398,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) 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 { @@ -470,8 +475,8 @@ 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), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -561,11 +566,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) 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 { @@ -654,8 +659,8 @@ 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), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -745,11 +750,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) 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 { @@ -824,7 +829,7 @@ private: #endif // defined(BOOST_ATOMIC_LLONG_LOCK_FREE) && BOOST_ATOMIC_LLONG_LOCK_FREE > 0 -#if defined(BOOST_ATOMIC_X86_HAS_CMPXCHG16B) && defined(BOOST_HAS_INT128) +#if defined(BOOST_ATOMIC_INT128_LOCK_FREE) && BOOST_ATOMIC_INT128_LOCK_FREE > 0 template class base_atomic @@ -838,8 +843,8 @@ 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), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -917,23 +922,45 @@ private: value_type v_; }; +#if defined(BOOST_HAS_INT128) + +typedef boost::uint128_type storage128_type; + +#else // defined(BOOST_HAS_INT128) + +struct BOOST_ALIGNMENT(16) storage128_type +{ + uint64_t data[2]; +}; + +inline bool operator== (storage128_type const& left, storage128_type const& right) +{ + return left.data[0] == right.data[0] && left.data[1] == right.data[1]; +} +inline bool operator!= (storage128_type const& left, storage128_type const& right) +{ + return !(left == right); +} + +#endif // defined(BOOST_HAS_INT128) + template class base_atomic { private: typedef base_atomic this_type; typedef T value_type; - typedef uint128_type storage_type; + typedef storage128_type storage_type; protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) 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 { @@ -1006,7 +1033,7 @@ private: storage_type v_; }; -#endif // defined(BOOST_ATOMIC_X86_HAS_CMPXCHG16B) && defined(BOOST_HAS_INT128) +#endif // defined(BOOST_ATOMIC_INT128_LOCK_FREE) && BOOST_ATOMIC_INT128_LOCK_FREE > 0 /* pointers */ @@ -1025,8 +1052,8 @@ 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), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -1101,8 +1128,8 @@ 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), {}) + BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { diff --git a/include/boost/atomic/detail/gcc-cas.hpp b/include/boost/atomic/detail/gcc-cas.hpp index 55e2132..5965e65 100644 --- a/include/boost/atomic/detail/gcc-cas.hpp +++ b/include/boost/atomic/detail/gcc-cas.hpp @@ -25,16 +25,17 @@ namespace boost { inline void atomic_thread_fence(memory_order order) { - switch(order) { - case memory_order_relaxed: - break; - case memory_order_release: - case memory_order_consume: - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: - __sync_synchronize(); - break; + switch(order) + { + case memory_order_relaxed: + break; + case memory_order_release: + case memory_order_consume: + case memory_order_acquire: + case memory_order_acq_rel: + case memory_order_seq_cst: + __sync_synchronize(); + break; } } @@ -56,16 +57,17 @@ platform_fence_after(memory_order) inline void platform_fence_before_store(memory_order order) { - switch(order) { - case memory_order_relaxed: - case memory_order_acquire: - case memory_order_consume: - break; - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: - __sync_synchronize(); - break; + switch(order) + { + case memory_order_relaxed: + case memory_order_acquire: + case memory_order_consume: + break; + case memory_order_release: + case memory_order_acq_rel: + case memory_order_seq_cst: + __sync_synchronize(); + break; } } @@ -79,16 +81,17 @@ platform_fence_after_store(memory_order order) inline void platform_fence_after_load(memory_order order) { - switch(order) { - case memory_order_relaxed: - case memory_order_release: - break; - case memory_order_consume: - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: - __sync_synchronize(); - break; + switch(order) + { + case memory_order_relaxed: + case memory_order_release: + break; + case memory_order_consume: + case memory_order_acquire: + case memory_order_acq_rel: + case memory_order_seq_cst: + __sync_synchronize(); + break; } } @@ -132,6 +135,7 @@ public: return expected; } }; + #define BOOST_ATOMIC_FLAG_LOCK_FREE 2 } diff --git a/include/boost/atomic/detail/gcc-ppc.hpp b/include/boost/atomic/detail/gcc-ppc.hpp index 0be626b..9fe43dc 100644 --- a/include/boost/atomic/detail/gcc-ppc.hpp +++ b/include/boost/atomic/detail/gcc-ppc.hpp @@ -65,40 +65,43 @@ namespace detail { inline void ppc_fence_before(memory_order order) { - switch(order) { - case memory_order_release: - case memory_order_acq_rel: + switch(order) + { + case memory_order_release: + case memory_order_acq_rel: #if defined(__powerpc64__) - __asm__ __volatile__ ("lwsync" ::: "memory"); - break; + __asm__ __volatile__ ("lwsync" ::: "memory"); + break; #endif - case memory_order_seq_cst: - __asm__ __volatile__ ("sync" ::: "memory"); - default:; + case memory_order_seq_cst: + __asm__ __volatile__ ("sync" ::: "memory"); + default:; } } inline void ppc_fence_after(memory_order order) { - switch(order) { - case memory_order_acquire: - case memory_order_acq_rel: - case memory_order_seq_cst: - __asm__ __volatile__ ("isync"); - case memory_order_consume: - __asm__ __volatile__ ("" ::: "memory"); - default:; + switch(order) + { + case memory_order_acquire: + case memory_order_acq_rel: + case memory_order_seq_cst: + __asm__ __volatile__ ("isync"); + case memory_order_consume: + __asm__ __volatile__ ("" ::: "memory"); + default:; } } inline void ppc_fence_after_store(memory_order order) { - switch(order) { - case memory_order_seq_cst: - __asm__ __volatile__ ("sync"); - default:; + switch(order) + { + case memory_order_seq_cst: + __asm__ __volatile__ ("sync"); + default:; } } @@ -209,8 +212,8 @@ 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 @@ -416,9 +419,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 */ ; storage_type v_; }; @@ -435,8 +440,8 @@ 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 @@ -643,9 +648,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 */ ; storage_type v_; }; @@ -662,8 +669,8 @@ 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 @@ -870,9 +877,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 */ ; storage_type v_; }; @@ -889,8 +898,8 @@ 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 @@ -1097,9 +1106,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 */ ; storage_type v_; }; @@ -1115,8 +1126,8 @@ 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 @@ -1317,9 +1328,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_; }; @@ -1337,8 +1350,8 @@ 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 @@ -1539,9 +1552,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_; }; @@ -1563,8 +1578,8 @@ 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 @@ -1716,9 +1731,11 @@ 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_; }; @@ -1734,8 +1751,8 @@ 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 @@ -1889,9 +1906,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_; }; @@ -1909,8 +1928,8 @@ 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 @@ -2062,9 +2081,11 @@ 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_; }; @@ -2080,8 +2101,8 @@ 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 @@ -2235,9 +2256,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_; }; @@ -2257,11 +2280,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -2395,9 +2418,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -2413,13 +2438,12 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -2552,9 +2576,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -2570,13 +2596,12 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -2709,9 +2734,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -2729,13 +2756,12 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -2868,11 +2894,14 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; + #endif } @@ -2882,19 +2911,20 @@ private: inline void atomic_thread_fence(memory_order order) { - switch(order) { - case memory_order_acquire: - __asm__ __volatile__ ("isync" ::: "memory"); - break; - case memory_order_release: + switch(order) + { + case memory_order_acquire: + __asm__ __volatile__ ("isync" ::: "memory"); + break; + case memory_order_release: #if defined(__powerpc64__) - __asm__ __volatile__ ("lwsync" ::: "memory"); - break; + __asm__ __volatile__ ("lwsync" ::: "memory"); + break; #endif - case memory_order_acq_rel: - case memory_order_seq_cst: - __asm__ __volatile__ ("sync" ::: "memory"); - default:; + case memory_order_acq_rel: + case memory_order_seq_cst: + __asm__ __volatile__ ("sync" ::: "memory"); + default:; } } @@ -2902,14 +2932,15 @@ atomic_thread_fence(memory_order order) inline void atomic_signal_fence(memory_order order) { - switch(order) { - case memory_order_acquire: - case memory_order_release: - case memory_order_acq_rel: - case memory_order_seq_cst: - __asm__ __volatile__ ("" ::: "memory"); - break; - default:; + switch(order) + { + case memory_order_acquire: + case memory_order_release: + case memory_order_acq_rel: + case memory_order_seq_cst: + __asm__ __volatile__ ("" ::: "memory"); + break; + default:; } } diff --git a/include/boost/atomic/detail/gcc-sparcv9.hpp b/include/boost/atomic/detail/gcc-sparcv9.hpp index a76d2e3..d221faf 100644 --- a/include/boost/atomic/detail/gcc-sparcv9.hpp +++ b/include/boost/atomic/detail/gcc-sparcv9.hpp @@ -23,53 +23,56 @@ namespace detail { inline void platform_fence_before(memory_order order) { - switch(order) { - case memory_order_relaxed: - case memory_order_acquire: - case memory_order_consume: - break; - case memory_order_release: - case memory_order_acq_rel: - __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); - /* release */ - break; - case memory_order_seq_cst: - __asm__ __volatile__ ("membar #Sync" ::: "memory"); - /* seq */ - break; + switch(order) + { + case memory_order_relaxed: + case memory_order_acquire: + case memory_order_consume: + break; + case memory_order_release: + case memory_order_acq_rel: + __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); + /* release */ + break; + case memory_order_seq_cst: + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + /* seq */ + break; } } inline void platform_fence_after(memory_order order) { - switch(order) { - case memory_order_relaxed: - case memory_order_release: - break; - case memory_order_acquire: - case memory_order_acq_rel: - __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); - /* acquire */ - break; - case memory_order_consume: - /* consume */ - break; - case memory_order_seq_cst: - __asm__ __volatile__ ("membar #Sync" ::: "memory"); - /* seq */ - break; - default:; + switch(order) + { + case memory_order_relaxed: + case memory_order_release: + break; + case memory_order_acquire: + case memory_order_acq_rel: + __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); + /* acquire */ + break; + case memory_order_consume: + /* consume */ + break; + case memory_order_seq_cst: + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + /* seq */ + break; + default:; } } inline void platform_fence_after_store(memory_order order) { - switch(order) { - case memory_order_seq_cst: - __asm__ __volatile__ ("membar #Sync" ::: "memory"); - default:; + switch(order) + { + case memory_order_seq_cst: + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + default:; } } @@ -141,24 +144,25 @@ namespace boost { inline void atomic_thread_fence(memory_order order) { - switch(order) { - case memory_order_relaxed: - break; - case memory_order_release: - __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); - break; - case memory_order_acquire: - __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); - break; - case memory_order_acq_rel: - __asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore" ::: "memory"); - break; - case memory_order_consume: - break; - case memory_order_seq_cst: - __asm__ __volatile__ ("membar #Sync" ::: "memory"); - break; - default:; + switch(order) + { + case memory_order_relaxed: + break; + case memory_order_release: + __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory"); + break; + case memory_order_acquire: + __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory"); + break; + case memory_order_acq_rel: + __asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore" ::: "memory"); + break; + case memory_order_consume: + break; + case memory_order_seq_cst: + __asm__ __volatile__ ("membar #Sync" ::: "memory"); + break; + default:; } } @@ -187,8 +191,8 @@ 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 @@ -296,9 +300,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 */ ; storage_type v_; }; @@ -315,8 +321,8 @@ 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 @@ -424,9 +430,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 */ ; storage_type v_; }; @@ -443,8 +451,8 @@ 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 @@ -552,9 +560,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 */ ; storage_type v_; }; @@ -571,8 +581,8 @@ 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 @@ -680,9 +690,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 */ ; storage_type v_; }; @@ -698,8 +710,8 @@ 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 @@ -805,9 +817,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_; }; @@ -825,8 +839,8 @@ 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 @@ -906,9 +920,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_; }; @@ -924,8 +939,8 @@ 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 @@ -1007,9 +1022,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_; }; @@ -1027,11 +1044,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1104,9 +1121,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -1122,11 +1141,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1199,9 +1218,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -1217,11 +1238,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1294,9 +1315,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; diff --git a/include/boost/atomic/detail/gcc-x86.hpp b/include/boost/atomic/detail/gcc-x86.hpp index c776a37..e86c2fe 100644 --- a/include/boost/atomic/detail/gcc-x86.hpp +++ b/include/boost/atomic/detail/gcc-x86.hpp @@ -213,8 +213,10 @@ public: #if defined(__x86_64__) || defined(BOOST_ATOMIC_X86_HAS_CMPXCHG8B) #define BOOST_ATOMIC_LLONG_LOCK_FREE 2 -#else -#define BOOST_ATOMIC_LLONG_LOCK_FREE 0 +#endif + +#if defined(BOOST_ATOMIC_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT)) +#define BOOST_ATOMIC_INT128_LOCK_FREE 2 #endif #define BOOST_ATOMIC_POINTER_LOCK_FREE 2 @@ -270,8 +272,8 @@ 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 @@ -296,9 +298,12 @@ public: fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddb %0, %1" : "+q" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return v; @@ -314,7 +319,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgb %0, %1" : "+q" (v), "+m" (v_) ); @@ -331,12 +337,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgb %2, %1" - : "+a" (previous), "+m" (v_) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgb %3, %1\n\t" + "sete %2" + : "+a" (previous), "+m" (v_), "=q" (success) : "q" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -359,7 +368,7 @@ public: fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for(; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -370,7 +379,7 @@ public: fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -381,7 +390,7 @@ public: fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -395,9 +404,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_; }; @@ -413,8 +424,8 @@ 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 @@ -439,9 +450,12 @@ public: fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddw %0, %1" : "+q" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return v; @@ -457,7 +471,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgw %0, %1" : "+q" (v), "+m" (v_) ); @@ -474,12 +489,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgw %2, %1" - : "+a" (previous), "+m" (v_) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgw %3, %1\n\t" + "sete %2" + : "+a" (previous), "+m" (v_), "=q" (success) : "q" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -502,7 +520,7 @@ public: fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -513,7 +531,7 @@ public: fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -524,7 +542,7 @@ public: fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -538,9 +556,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_; }; @@ -556,8 +576,8 @@ 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 @@ -582,9 +602,12 @@ public: fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddl %0, %1" : "+r" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return v; @@ -600,7 +623,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgl %0, %1" : "+r" (v), "+m" (v_) ); @@ -617,12 +641,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgl %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgl %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -645,7 +672,7 @@ public: fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -656,7 +683,7 @@ public: fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -667,7 +694,7 @@ public: fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -681,9 +708,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_; }; @@ -700,8 +729,8 @@ 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 @@ -726,9 +755,12 @@ public: fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddq %0, %1" : "+r" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return v; @@ -744,7 +776,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgq %0, %1" : "+r" (v), "+m" (v_) ); @@ -761,12 +794,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgq %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgq %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -789,7 +825,7 @@ public: fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp & v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -800,7 +836,7 @@ public: fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp | v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -811,7 +847,7 @@ public: fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { value_type tmp = load(memory_order_relaxed); - for (; !compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed);) + while (!compare_exchange_weak(tmp, tmp ^ v, order, memory_order_relaxed)) { BOOST_ATOMIC_X86_PAUSE(); } @@ -825,9 +861,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_; }; @@ -850,8 +888,8 @@ 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 @@ -874,7 +912,8 @@ public: value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgl %0, %1" : "+r" (v), "+m" (v_) ); @@ -888,12 +927,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgl %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgl %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -919,10 +961,13 @@ public: fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( - "lock ; xaddl %0, %1" - : "+r" (v), "+m" (v_) - ); + __asm__ __volatile__ + ( + "lock ; xaddl %0, %1" + : "+r" (v), "+m" (v_) + : + : "cc" + ); platform_fence_after(order); return reinterpret_cast(v); } @@ -934,9 +979,11 @@ 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_; }; @@ -952,8 +999,8 @@ 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 @@ -978,7 +1025,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgl %0, %1" : "+r" (v), "+m" (v_) ); @@ -995,12 +1043,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgl %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgl %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -1024,9 +1075,12 @@ public: { v = v * sizeof(*v_); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddl %0, %1" : "+r" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return reinterpret_cast(v); @@ -1045,9 +1099,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_; }; @@ -1065,8 +1121,8 @@ 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 @@ -1089,7 +1145,8 @@ public: value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgq %0, %1" : "+r" (v), "+m" (v_) ); @@ -1103,12 +1160,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgq %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgq %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -1134,9 +1194,12 @@ public: fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddq %0, %1" : "+r" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return reinterpret_cast(v); @@ -1149,9 +1212,11 @@ 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_; }; @@ -1167,8 +1232,8 @@ 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 @@ -1193,7 +1258,8 @@ public: exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgq %0, %1" : "+r" (v), "+m" (v_) ); @@ -1210,12 +1276,15 @@ public: { value_type previous = expected; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgq %2, %1" - : "+a" (previous), "+m" (v_) - : "r" (desired) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgq %3, %1\n\t" + "sete %2" + : "+a,a" (previous), "+m,m" (v_), "=q,m" (success) + : "r,r" (desired) + : "cc" ); - bool success = (previous == expected); if (success) platform_fence_after(success_order); else @@ -1239,9 +1308,12 @@ public: { v = v * sizeof(*v_); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "lock ; xaddq %0, %1" : "+r" (v), "+m" (v_) + : + : "cc" ); platform_fence_after(order); return reinterpret_cast(v); @@ -1260,9 +1332,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_; }; @@ -1280,10 +1354,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast(v)) - {} - base_atomic(void) {} + { + } void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1314,7 +1389,8 @@ public: storage_type tmp; memcpy(&tmp, &v, sizeof(value_type)); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgb %0, %1" : "+q" (tmp), "+m" (v_) ); @@ -1336,12 +1412,15 @@ public: memcpy(&desired_s, &desired, sizeof(value_type)); storage_type previous_s = expected_s; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgb %2, %1" - : "+a" (previous_s), "+m" (v_) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgb %3, %1\n\t" + "sete %2" + : "+a" (previous_s), "+m" (v_), "=q" (success) : "q" (desired_s) + : "cc" ); - bool success = (previous_s == expected_s); if (success) platform_fence_after(success_order); else @@ -1367,9 +1446,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -1385,10 +1466,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast(v)) - {} - base_atomic(void) {} + { + } void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1419,7 +1501,8 @@ public: storage_type tmp; memcpy(&tmp, &v, sizeof(value_type)); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgw %0, %1" : "+q" (tmp), "+m" (v_) ); @@ -1441,12 +1524,15 @@ public: memcpy(&desired_s, &desired, sizeof(value_type)); storage_type previous_s = expected_s; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgw %2, %1" - : "+a" (previous_s), "+m" (v_) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgw %3, %1\n\t" + "sete %2" + : "+a" (previous_s), "+m" (v_), "=q" (success) : "q" (desired_s) + : "cc" ); - bool success = (previous_s == expected_s); if (success) platform_fence_after(success_order); else @@ -1472,9 +1558,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -1490,11 +1578,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1525,7 +1613,8 @@ public: storage_type tmp = 0; memcpy(&tmp, &v, sizeof(value_type)); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgl %0, %1" : "+q" (tmp), "+m" (v_) ); @@ -1547,12 +1636,15 @@ public: memcpy(&desired_s, &desired, sizeof(value_type)); storage_type previous_s = expected_s; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgl %2, %1" - : "+a" (previous_s), "+m" (v_) - : "q" (desired_s) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgl %3, %1\n\t" + "sete %2" + : "+a,a" (previous_s), "+m,m" (v_), "=q,m" (success) + : "q,q" (desired_s) + : "cc" ); - bool success = (previous_s == expected_s); if (success) platform_fence_after(success_order); else @@ -1578,9 +1670,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -1597,11 +1691,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1632,7 +1726,8 @@ public: storage_type tmp = 0; memcpy(&tmp, &v, sizeof(value_type)); platform_fence_before(order); - __asm__ ( + __asm__ __volatile__ + ( "xchgq %0, %1" : "+q" (tmp), "+m" (v_) ); @@ -1654,12 +1749,15 @@ public: memcpy(&desired_s, &desired, sizeof(value_type)); storage_type previous_s = expected_s; platform_fence_before(success_order); - __asm__ ( - "lock ; cmpxchgq %2, %1" - : "+a" (previous_s), "+m" (v_) - : "q" (desired_s) + bool success; + __asm__ __volatile__ + ( + "lock ; cmpxchgq %3, %1\n\t" + "sete %2" + : "+a,a" (previous_s), "+m,m" (v_), "=q,m" (success) + : "q,q" (desired_s) + : "cc" ); - bool success = (previous_s == expected_s); if (success) platform_fence_after(success_order); else @@ -1685,9 +1783,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; #endif @@ -1720,17 +1820,18 @@ platform_cmpxchg64_strong(T & expected, T desired, volatile T * ptr) BOOST_NOEXC In theory, could push/pop ebx onto/off the stack, but movs to a prepared stack slot turn out to be faster. */ + bool success; __asm__ __volatile__ ( - "movl %%ebx, %1\n" - "movl %2, %%ebx\n" - "lock; cmpxchg8b 0(%4)\n" - "movl %1, %%ebx\n" - : "=A" (prev), "=m" (scratch) - : "D" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)), "S" (ptr), "0" (prev) - : "memory" + "movl %%ebx, %[scratch]\n\t" + "movl %[desired_lo], %%ebx\n\t" + "lock; cmpxchg8b 0(%[dest])\n\t" + "movl %[scratch], %%ebx\n\t" + "sete %[success]" + : "+A,A,A,A,A,A,A,A" (prev), [scratch] "=m,m,m,m,m,m,m,m" (scratch), [success] "=q,m,q,m,q,m,q,m" (success) + : [desired_lo] "S,S,D,D,m,m,m,m" ((uint32_t)desired), "c,c,c,c,c,c,c,c" ((uint32_t)(desired >> 32)), [dest] "D,D,S,S,D,D,S,S" (ptr) + : "memory", "cc" ); - bool success = (prev == expected); expected = prev; return success; #endif @@ -1772,11 +1873,21 @@ platform_store64(T value, volatile T * ptr) BOOST_NOEXCEPT } else { - T expected = *ptr; - while (!platform_cmpxchg64_strong(expected, value, ptr)) - { - BOOST_ATOMIC_X86_PAUSE(); - } + uint32_t scratch; + __asm__ __volatile__ + ( + "movl %%ebx, %[scratch]\n\t" + "movl %[value_lo], %%ebx\n\t" + "movl 0(%[dest]), %%eax\n\t" + "movl 4(%[dest]), %%edx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg8b 0(%[dest])\n\t" + "jne 1b\n\t" + "movl %[scratch], %%ebx" + : [scratch] "=m,m" (scratch) + : [value_lo] "S,D" ((uint32_t)value), "c,c" ((uint32_t)(value >> 32)), [dest] "D,S" (ptr) + : "memory", "cc", "eax", "edx" + ); } } @@ -1810,9 +1921,21 @@ platform_load64(const volatile T * ptr) BOOST_NOEXCEPT } else { - value = T(); // We don't care for comparison result here; the previous value will be stored into value anyway. - platform_cmpxchg64_strong(value, value, const_cast(ptr)); + uint32_t scratch; + __asm__ __volatile__ + ( + "movl %%ebx, %[scratch]\n\t" + "xorl %%eax, %%eax\n\t" + "xorl %%ebx, %%ebx\n\t" + "xorl %%ecx, %%ecx\n\t" + "xorl %%edx, %%edx\n\t" + "lock; cmpxchg8b 0(%[dest])\n\t" + "movl %[scratch], %%ebx" + : "=A,A" (value), [scratch] "=m,m" (scratch) + : [dest] "D,S" (ptr) + : "cc", "ecx" + ); } return value; @@ -1820,6 +1943,67 @@ platform_load64(const volatile T * ptr) BOOST_NOEXCEPT #endif +#if defined(BOOST_ATOMIC_INT128_LOCK_FREE) && BOOST_ATOMIC_INT128_LOCK_FREE > 0 + +template +inline bool +platform_cmpxchg128_strong(T& expected, T desired, volatile T* ptr) BOOST_NOEXCEPT +{ + uint64_t const* p_desired = (uint64_t const*)&desired; + bool success; + __asm__ __volatile__ + ( + "lock; cmpxchg16b 0(%[dest])\n\t" + "sete %[success]" + : "+A,A,A,A" (expected), [success] "=q,m,q,m" (success) + : "b,b,b,b" (p_desired[0]), "c,c,c,c" (p_desired[1]), [dest] "D,D,S,S" (ptr) + : "memory", "cc" + ); + return success; +} + +template +inline void +platform_store128(T value, volatile T* ptr) BOOST_NOEXCEPT +{ + uint64_t const* p_value = (uint64_t const*)&value; + __asm__ __volatile__ + ( + "movq 0(%[dest]), %%rax\n\t" + "movq 8(%[dest]), %%rdx\n\t" + ".align 16\n\t" + "1: lock; cmpxchg16b 0(%[dest])\n\t" + "jne 1b\n\t" + : + : "b" (p_value[0]), "c" (p_value[1]), [dest] "D,S" (ptr) + : "memory", "cc", "rax", "rdx" + ); +} + +template +inline T +platform_load128(const volatile T* ptr) BOOST_NOEXCEPT +{ + T value; + + // We don't care for comparison result here; the previous value will be stored into value anyway. + __asm__ __volatile__ + ( + "xorq %%rax, %%rax\n\t" + "xorq %%rbx, %%rbx\n\t" + "xorq %%rcx, %%rcx\n\t" + "xorq %%rdx, %%rdx\n\t" + "lock; cmpxchg16b 0(%[dest])\n\t" + : "=A,A" (value) + : [dest] "D,S" (ptr) + : "cc", "rbx", "rcx" + ); + + return value; +} + +#endif // defined(BOOST_ATOMIC_INT128_LOCK_FREE) && BOOST_ATOMIC_INT128_LOCK_FREE > 0 + } } } @@ -1829,6 +2013,11 @@ platform_load64(const volatile T * ptr) BOOST_NOEXCEPT #include #endif +/* pull in 128-bit atomic type using cmpxchg16b above */ +#if defined(BOOST_ATOMIC_INT128_LOCK_FREE) && BOOST_ATOMIC_INT128_LOCK_FREE > 0 +#include +#endif + #endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */ #endif diff --git a/include/boost/atomic/detail/linux-arm.hpp b/include/boost/atomic/detail/linux-arm.hpp index ed9a73b..d39dcd0 100644 --- a/include/boost/atomic/detail/linux-arm.hpp +++ b/include/boost/atomic/detail/linux-arm.hpp @@ -163,6 +163,7 @@ public: return expected; } }; + #define BOOST_ATOMIC_FLAG_LOCK_FREE 2 } diff --git a/include/boost/atomic/detail/windows.hpp b/include/boost/atomic/detail/windows.hpp index 05c3397..1561c78 100644 --- a/include/boost/atomic/detail/windows.hpp +++ b/include/boost/atomic/detail/windows.hpp @@ -218,8 +218,8 @@ 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 @@ -382,9 +382,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 */ ; storage_type v_; }; @@ -409,8 +411,8 @@ 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 @@ -573,9 +575,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 */ ; storage_type v_; }; @@ -592,8 +596,8 @@ 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 @@ -729,9 +733,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 */ ; storage_type v_; }; @@ -750,8 +756,8 @@ 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 @@ -824,9 +830,11 @@ 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_; }; @@ -842,8 +850,8 @@ 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 @@ -925,9 +933,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_; }; @@ -948,6 +958,8 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + #ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8 BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast< storage_type const& >(v)) { @@ -958,7 +970,6 @@ public: memcpy(&v_, &v, sizeof(value_type)); } #endif - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1042,9 +1053,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -1064,6 +1077,8 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) + #ifdef BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16 BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(reinterpret_cast< storage_type const& >(v)) { @@ -1075,8 +1090,6 @@ public: } #endif - base_atomic(void) {} - void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT { @@ -1159,9 +1172,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -1177,11 +1192,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1257,9 +1272,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; @@ -1278,8 +1295,8 @@ 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 @@ -1415,9 +1432,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 */ ; storage_type v_; }; @@ -1433,11 +1452,11 @@ protected: typedef value_type const& value_arg_type; public: + BOOST_DEFAULTED_FUNCTION(base_atomic(void), {}) explicit base_atomic(value_type const& v) : v_(0) { memcpy(&v_, &v, sizeof(value_type)); } - base_atomic(void) {} void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT @@ -1513,9 +1532,11 @@ public: } BOOST_ATOMIC_DECLARE_BASE_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 */ ; storage_type v_; }; diff --git a/src/lockpool.cpp b/src/lockpool.cpp index c269103..a989fee 100644 --- a/src/lockpool.cpp +++ b/src/lockpool.cpp @@ -14,7 +14,8 @@ namespace detail { namespace { // This seems to be the maximum across all modern CPUs -enum { cache_line_size = 64 }; +// NOTE: This constant is made as a macro because some compilers (gcc 4.4 for one) don't allow enums or regular constants in alignment attributes +#define BOOST_ATOMIC_CACHE_LINE_SIZE 64 template< unsigned int N > struct padding @@ -26,11 +27,13 @@ struct padding< 0 > { }; -struct BOOST_ALIGNMENT(cache_line_size) padded_lock +struct BOOST_ALIGNMENT(BOOST_ATOMIC_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)) }; + enum { padding_size = (sizeof(lockpool::lock_type) <= BOOST_ATOMIC_CACHE_LINE_SIZE ? + (BOOST_ATOMIC_CACHE_LINE_SIZE - sizeof(lockpool::lock_type)) : + (BOOST_ATOMIC_CACHE_LINE_SIZE - sizeof(lockpool::lock_type) % BOOST_ATOMIC_CACHE_LINE_SIZE)) }; padding< padding_size > pad; }; diff --git a/test/api_test_helpers.hpp b/test/api_test_helpers.hpp index f9dbf36..1d71547 100644 --- a/test/api_test_helpers.hpp +++ b/test/api_test_helpers.hpp @@ -265,8 +265,8 @@ void test_integral_api(void) test_additive_wrap(0); test_additive_wrap((T) -1); - test_additive_wrap(-1LL << (sizeof(T) * 8 - 1)); - test_additive_wrap(~ (-1LL << (sizeof(T) * 8 - 1))); + test_additive_wrap(((T)-1) << (sizeof(T) * 8 - 1)); + test_additive_wrap(~ (((T)-1) << (sizeof(T) * 8 - 1))); } template diff --git a/test/native_api.cpp b/test/native_api.cpp index 087f828..b489264 100644 --- a/test/native_api.cpp +++ b/test/native_api.cpp @@ -4,6 +4,7 @@ // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#include #include #include #include @@ -33,6 +34,10 @@ int test_main(int, char *[]) test_integral_api(); test_integral_api(); test_integral_api(); +#if defined(BOOST_HAS_INT128) + test_integral_api(); + test_integral_api(); +#endif test_constexpr_ctor(); test_constexpr_ctor(); @@ -48,6 +53,9 @@ int test_main(int, char *[]) test_struct_api >(); test_struct_api >(); test_struct_api >(); +#if defined(BOOST_HAS_INT128) + test_struct_api >(); +#endif test_large_struct_api();