diff options
Diffstat (limited to 'boost/atomic/detail/ops_cas_based.hpp')
-rw-r--r-- | boost/atomic/detail/ops_cas_based.hpp | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/boost/atomic/detail/ops_cas_based.hpp b/boost/atomic/detail/ops_cas_based.hpp index 7f8d288f7f..504cedb70f 100644 --- a/boost/atomic/detail/ops_cas_based.hpp +++ b/boost/atomic/detail/ops_cas_based.hpp @@ -16,6 +16,7 @@ #include <boost/memory_order.hpp> #include <boost/atomic/detail/config.hpp> +#include <boost/atomic/detail/storage_type.hpp> #ifdef BOOST_HAS_PRAGMA_ONCE #pragma once @@ -26,6 +27,21 @@ namespace atomics { namespace detail { template< typename Base > +struct cas_based_exchange : + public Base +{ + typedef typename Base::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT + { + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); + while (!Base::compare_exchange_weak(storage, old_val, v, order, memory_order_relaxed)) {} + return old_val; + } +}; + +template< typename Base > struct cas_based_operations : public Base { @@ -33,49 +49,47 @@ struct cas_based_operations : static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { - storage_type old_val = Base::load(storage, memory_order_relaxed); + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, old_val + v, order, memory_order_relaxed)) {} return old_val; } static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { - storage_type old_val = Base::load(storage, memory_order_relaxed); + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, old_val - v, order, memory_order_relaxed)) {} return old_val; } - static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT - { - storage_type old_val = Base::load(storage, memory_order_relaxed); - while (!Base::compare_exchange_weak(storage, old_val, v, order, memory_order_relaxed)) {} - return old_val; - } - static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { - storage_type old_val = Base::load(storage, memory_order_relaxed); + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, old_val & v, order, memory_order_relaxed)) {} return old_val; } static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { - storage_type old_val = Base::load(storage, memory_order_relaxed); + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, old_val | v, order, memory_order_relaxed)) {} return old_val; } static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT { - storage_type old_val = Base::load(storage, memory_order_relaxed); + storage_type old_val; + atomics::detail::non_atomic_load(storage, old_val); while (!Base::compare_exchange_weak(storage, old_val, old_val ^ v, order, memory_order_relaxed)) {} return old_val; } static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT { - return !!exchange(storage, (storage_type)1, order); + return !!Base::exchange(storage, (storage_type)1, order); } static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT |