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/memory_order.hpp> 19 #include <boost/atomic/detail/config.hpp> 20 #include <boost/atomic/detail/bitwise_fp_cast.hpp> 21 #include <boost/atomic/detail/fp_operations_fwd.hpp> 22 #include <boost/atomic/detail/lockpool.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 //! Generic implementation of floating point operations 33 template< typename Base, typename Value, std::size_t Size > 34 struct emulated_fp_operations : 35 public Base 36 { 37 typedef Base base_type; 38 typedef typename base_type::storage_type storage_type; 39 typedef Value value_type; 40 fetch_addboost::atomics::detail::emulated_fp_operations41 static BOOST_FORCEINLINE value_type fetch_add(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT 42 { 43 storage_type& s = const_cast< storage_type& >(storage); 44 lockpool::scoped_lock lock(&storage); 45 value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s); 46 value_type new_val = old_val + v; 47 s = atomics::detail::bitwise_fp_cast< storage_type >(new_val); 48 return old_val; 49 } 50 fetch_subboost::atomics::detail::emulated_fp_operations51 static BOOST_FORCEINLINE value_type fetch_sub(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT 52 { 53 storage_type& s = const_cast< storage_type& >(storage); 54 lockpool::scoped_lock lock(&storage); 55 value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s); 56 value_type new_val = old_val - v; 57 s = atomics::detail::bitwise_fp_cast< storage_type >(new_val); 58 return old_val; 59 } 60 }; 61 62 template< typename Base, typename Value, std::size_t Size > 63 struct fp_operations< Base, Value, Size, false > : 64 public emulated_fp_operations< Base, Value, Size > 65 { 66 }; 67 68 } // namespace detail 69 } // namespace atomics 70 } // namespace boost 71 72 #endif // BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_ 73