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 <boost/memory_order.hpp> 18 #include <boost/atomic/detail/config.hpp> 19 #include <boost/atomic/detail/storage_type.hpp> 20 21 #ifdef BOOST_HAS_PRAGMA_ONCE 22 #pragma once 23 #endif 24 25 namespace boost { 26 namespace atomics { 27 namespace detail { 28 29 template< typename Base, unsigned int Size, bool Signed > 30 struct extending_cas_based_operations : 31 public Base 32 { 33 typedef typename Base::storage_type storage_type; 34 typedef typename make_storage_type< Size, Signed >::type emulated_storage_type; 35 fetch_addboost::atomics::detail::extending_cas_based_operations36 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 37 { 38 storage_type old_val = Base::load(storage, memory_order_relaxed); 39 emulated_storage_type new_val; 40 do 41 { 42 new_val = static_cast< emulated_storage_type >(old_val) + static_cast< emulated_storage_type >(v); 43 } 44 while (!Base::compare_exchange_weak(storage, old_val, static_cast< storage_type >(new_val), order, memory_order_relaxed)); 45 return old_val; 46 } 47 fetch_subboost::atomics::detail::extending_cas_based_operations48 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT 49 { 50 storage_type old_val = Base::load(storage, memory_order_relaxed); 51 emulated_storage_type new_val; 52 do 53 { 54 new_val = static_cast< emulated_storage_type >(old_val) - static_cast< emulated_storage_type >(v); 55 } 56 while (!Base::compare_exchange_weak(storage, old_val, static_cast< storage_type >(new_val), order, memory_order_relaxed)); 57 return old_val; 58 } 59 }; 60 61 } // namespace detail 62 } // namespace atomics 63 } // namespace boost 64 65 #endif // BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_ 66