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) 2018 Andrey Semashev 7 */ 8 /*! 9 * \file atomic/detail/fp_ops_emulated.hpp 10 * 11 * This header contains emulated (lock-based) implementation of the floating point atomic operations. 12 */ 13 14 #ifndef BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_ 15 #define BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_ 16 17 #include <cstddef> 18 #include <boost/static_assert.hpp> 19 #include <boost/memory_order.hpp> 20 #include <boost/atomic/detail/config.hpp> 21 #include <boost/atomic/detail/bitwise_fp_cast.hpp> 22 #include <boost/atomic/detail/fp_operations_fwd.hpp> 23 #include <boost/atomic/detail/header.hpp> 24 25 #ifdef BOOST_HAS_PRAGMA_ONCE 26 #pragma once 27 #endif 28 29 namespace boost { 30 namespace atomics { 31 namespace detail { 32 33 //! Emulated implementation of floating point operations 34 template< typename Base, typename Value, std::size_t Size > 35 struct fp_operations_emulated : 36 public Base 37 { 38 typedef Base base_type; 39 typedef typename base_type::storage_type storage_type; 40 typedef Value value_type; 41 typedef typename base_type::scoped_lock scoped_lock; 42 fetch_addboost::atomics::detail::fp_operations_emulated43 static value_type fetch_add(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT 44 { 45 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object"); 46 storage_type& s = const_cast< storage_type& >(storage); 47 scoped_lock lock(&storage); 48 value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s); 49 value_type new_val = old_val + v; 50 s = atomics::detail::bitwise_fp_cast< storage_type >(new_val); 51 return old_val; 52 } 53 fetch_subboost::atomics::detail::fp_operations_emulated54 static value_type fetch_sub(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT 55 { 56 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object"); 57 storage_type& s = const_cast< storage_type& >(storage); 58 scoped_lock lock(&storage); 59 value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s); 60 value_type new_val = old_val - v; 61 s = atomics::detail::bitwise_fp_cast< storage_type >(new_val); 62 return old_val; 63 } 64 }; 65 66 template< typename Base, typename Value, std::size_t Size > 67 struct fp_operations< Base, Value, Size, false > : 68 public fp_operations_emulated< Base, Value, Size > 69 { 70 }; 71 72 } // namespace detail 73 } // namespace atomics 74 } // namespace boost 75 76 #include <boost/atomic/detail/footer.hpp> 77 78 #endif // BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_ 79