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_emulated.hpp 10 * 11 * This header contains lockpool-based implementation of the \c operations template. 12 */ 13 14 #ifndef BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_ 15 #define BOOST_ATOMIC_DETAIL_OPS_EMULATED_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 #include <boost/atomic/detail/operations_fwd.hpp> 21 #include <boost/atomic/detail/lockpool.hpp> 22 #include <boost/atomic/capabilities.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 T > 33 struct emulated_operations 34 { 35 typedef T storage_type; 36 storeboost::atomics::detail::emulated_operations37 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 38 { 39 lockpool::scoped_lock lock(&storage); 40 const_cast< storage_type& >(storage) = v; 41 } 42 loadboost::atomics::detail::emulated_operations43 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT 44 { 45 lockpool::scoped_lock lock(&storage); 46 return const_cast< storage_type const& >(storage); 47 } 48 fetch_addboost::atomics::detail::emulated_operations49 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 50 { 51 storage_type& s = const_cast< storage_type& >(storage); 52 lockpool::scoped_lock lock(&storage); 53 storage_type old_val = s; 54 s += v; 55 return old_val; 56 } 57 fetch_subboost::atomics::detail::emulated_operations58 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 59 { 60 storage_type& s = const_cast< storage_type& >(storage); 61 lockpool::scoped_lock lock(&storage); 62 storage_type old_val = s; 63 s -= v; 64 return old_val; 65 } 66 exchangeboost::atomics::detail::emulated_operations67 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 68 { 69 storage_type& s = const_cast< storage_type& >(storage); 70 lockpool::scoped_lock lock(&storage); 71 storage_type old_val = s; 72 s = v; 73 return old_val; 74 } 75 compare_exchange_strongboost::atomics::detail::emulated_operations76 static BOOST_FORCEINLINE bool compare_exchange_strong( 77 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT 78 { 79 storage_type& s = const_cast< storage_type& >(storage); 80 lockpool::scoped_lock lock(&storage); 81 storage_type old_val = s; 82 const bool res = old_val == expected; 83 if (res) 84 s = desired; 85 expected = old_val; 86 87 return res; 88 } 89 compare_exchange_weakboost::atomics::detail::emulated_operations90 static BOOST_FORCEINLINE bool compare_exchange_weak( 91 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT 92 { 93 return compare_exchange_strong(storage, expected, desired, success_order, failure_order); 94 } 95 fetch_andboost::atomics::detail::emulated_operations96 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 97 { 98 storage_type& s = const_cast< storage_type& >(storage); 99 lockpool::scoped_lock lock(&storage); 100 storage_type old_val = s; 101 s &= v; 102 return old_val; 103 } 104 fetch_orboost::atomics::detail::emulated_operations105 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 106 { 107 storage_type& s = const_cast< storage_type& >(storage); 108 lockpool::scoped_lock lock(&storage); 109 storage_type old_val = s; 110 s |= v; 111 return old_val; 112 } 113 fetch_xorboost::atomics::detail::emulated_operations114 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT 115 { 116 storage_type& s = const_cast< storage_type& >(storage); 117 lockpool::scoped_lock lock(&storage); 118 storage_type old_val = s; 119 s ^= v; 120 return old_val; 121 } 122 test_and_setboost::atomics::detail::emulated_operations123 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 124 { 125 return !!exchange(storage, (storage_type)1, order); 126 } 127 clearboost::atomics::detail::emulated_operations128 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT 129 { 130 store(storage, (storage_type)0, order); 131 } 132 is_lock_freeboost::atomics::detail::emulated_operations133 static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT 134 { 135 return false; 136 } 137 }; 138 139 template< unsigned int Size, bool Signed > 140 struct operations : 141 public emulated_operations< typename make_storage_type< Size, Signed >::type > 142 { 143 }; 144 145 } // namespace detail 146 } // namespace atomics 147 } // namespace boost 148 149 #endif // BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_ 150