1 /* 2 * Distributed under the Boost Software License, Version 1.0. 3 * (See accompanying file LICENSE_1_0.txt or copy at 4 * http://www.boost.org/LICENSE_1_0.txt) 5 * 6 * Copyright (c) 2014 Andrey Semashev 7 */ 8 /*! 9 * \file atomic/detail/ops_extending_cas_based.hpp 10 * 11 * This header contains a boilerplate of the \c operations template implementation that requires sign/zero extension in arithmetic operations. 12 */ 13 14 #ifndef BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_ 15 #define BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_ 16 17 #include <cstddef> 18 #include <boost/memory_order.hpp> 19 #include <boost/atomic/detail/config.hpp> 20 #include <boost/atomic/detail/storage_type.hpp> 21 #include <boost/atomic/detail/integral_extend.hpp> 22 23 #ifdef BOOST_HAS_PRAGMA_ONCE 24 #pragma once 25 #endif 26 27 namespace boost { 28 namespace atomics { 29 namespace detail { 30 31 template< typename Base, std::size_t Size, bool Signed > 32 struct extending_cas_based_operations : 33 public Base 34 { 35 typedef typename Base::storage_type storage_type; 36 typedef typename make_storage_type< Size >::type emulated_storage_type; 37 fetch_addboost::atomics::detail::extending_cas_based_operations38 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 39 { 40 storage_type old_val; 41 atomics::detail::non_atomic_load(storage, old_val); 42 storage_type new_val; 43 do 44 { 45 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val + v)); 46 } 47 while (!Base::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); 48 return old_val; 49 } 50 fetch_subboost::atomics::detail::extending_cas_based_operations51 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 52 { 53 storage_type old_val; 54 atomics::detail::non_atomic_load(storage, old_val); 55 storage_type new_val; 56 do 57 { 58 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val - v)); 59 } 60 while (!Base::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); 61 return old_val; 62 } 63 }; 64 65 } // namespace detail 66 } // namespace atomics 67 } // namespace boost 68 69 #endif // BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_ 70