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/extending_cas_based_arithmetic.hpp 10 * 11 * This header contains a boilerplate of core atomic operations that require sign/zero extension in arithmetic operations. 12 */ 13 14 #ifndef BOOST_ATOMIC_DETAIL_EXTENDING_CAS_BASED_ARITHMETIC_HPP_INCLUDED_ 15 #define BOOST_ATOMIC_DETAIL_EXTENDING_CAS_BASED_ARITHMETIC_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_traits.hpp> 21 #include <boost/atomic/detail/integral_conversions.hpp> 22 #include <boost/atomic/detail/header.hpp> 23 24 #ifdef BOOST_HAS_PRAGMA_ONCE 25 #pragma once 26 #endif 27 28 namespace boost { 29 namespace atomics { 30 namespace detail { 31 32 template< typename Base, std::size_t Size, bool Signed > 33 struct extending_cas_based_arithmetic : 34 public Base 35 { 36 typedef typename Base::storage_type storage_type; 37 typedef typename storage_traits< Size >::type emulated_storage_type; 38 fetch_addboost::atomics::detail::extending_cas_based_arithmetic39 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 40 { 41 storage_type old_val; 42 atomics::detail::non_atomic_load(storage, old_val); 43 storage_type new_val; 44 do 45 { 46 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val + v)); 47 } 48 while (!Base::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); 49 return old_val; 50 } 51 fetch_subboost::atomics::detail::extending_cas_based_arithmetic52 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 53 { 54 storage_type old_val; 55 atomics::detail::non_atomic_load(storage, old_val); 56 storage_type new_val; 57 do 58 { 59 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val - v)); 60 } 61 while (!Base::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed)); 62 return old_val; 63 } 64 }; 65 66 } // namespace detail 67 } // namespace atomics 68 } // namespace boost 69 70 #include <boost/atomic/detail/footer.hpp> 71 72 #endif // BOOST_ATOMIC_DETAIL_EXTENDING_CAS_BASED_ARITHMETIC_HPP_INCLUDED_ 73