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)
6 * Copyright (c) 2018 Andrey Semashev
9 * \file atomic/detail/extra_ops_emulated.hpp
11 * This header contains emulated (lock-based) implementation of the extra atomic operations.
14 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_
15 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_
18 #include <boost/static_assert.hpp>
19 #include <boost/memory_order.hpp>
20 #include <boost/atomic/detail/config.hpp>
21 #include <boost/atomic/detail/storage_traits.hpp>
22 #include <boost/atomic/detail/extra_operations_fwd.hpp>
23 #include <boost/atomic/detail/header.hpp>
25 #ifdef BOOST_HAS_PRAGMA_ONCE
33 //! Emulated implementation of extra operations
34 template< typename Base, std::size_t Size, bool Signed >
35 struct extra_operations_emulated :
38 typedef Base base_type;
39 typedef typename base_type::storage_type storage_type;
40 typedef typename base_type::scoped_lock scoped_lock;
42 static storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
44 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
45 storage_type& s = const_cast< storage_type& >(storage);
46 scoped_lock lock(&storage);
47 storage_type old_val = s;
48 s = static_cast< storage_type >(-old_val);
52 static storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
54 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
55 storage_type& s = const_cast< storage_type& >(storage);
56 scoped_lock lock(&storage);
57 storage_type new_val = static_cast< storage_type >(-s);
62 static storage_type add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
64 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
65 storage_type& s = const_cast< storage_type& >(storage);
66 scoped_lock lock(&storage);
67 storage_type new_val = s;
73 static storage_type sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
75 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
76 storage_type& s = const_cast< storage_type& >(storage);
77 scoped_lock lock(&storage);
78 storage_type new_val = s;
84 static storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
86 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
87 storage_type& s = const_cast< storage_type& >(storage);
88 scoped_lock lock(&storage);
89 storage_type new_val = s;
95 static storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
97 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
98 storage_type& s = const_cast< storage_type& >(storage);
99 scoped_lock lock(&storage);
100 storage_type new_val = s;
106 static storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
108 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
109 storage_type& s = const_cast< storage_type& >(storage);
110 scoped_lock lock(&storage);
111 storage_type new_val = s;
117 static storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
119 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
120 storage_type& s = const_cast< storage_type& >(storage);
121 scoped_lock lock(&storage);
122 storage_type old_val = s;
123 s = static_cast< storage_type >(~old_val);
127 static storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
129 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
130 storage_type& s = const_cast< storage_type& >(storage);
131 scoped_lock lock(&storage);
132 storage_type new_val = static_cast< storage_type >(~s);
137 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
139 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
140 base_type::fetch_add(storage, v, order);
143 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
145 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
146 base_type::fetch_sub(storage, v, order);
149 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
151 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
152 fetch_negate(storage, order);
155 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
157 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
158 base_type::fetch_and(storage, v, order);
161 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
163 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
164 base_type::fetch_or(storage, v, order);
167 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
169 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
170 base_type::fetch_xor(storage, v, order);
173 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
175 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
176 fetch_complement(storage, order);
179 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
181 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
182 return !!add(storage, v, order);
185 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
187 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
188 return !!sub(storage, v, order);
191 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
193 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
194 return !!negate(storage, order);
197 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
199 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
200 return !!bitwise_and(storage, v, order);
203 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
205 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
206 return !!bitwise_or(storage, v, order);
209 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
211 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
212 return !!bitwise_xor(storage, v, order);
215 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
217 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
218 return !!bitwise_complement(storage, order);
221 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
223 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
224 storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
225 storage_type old_val = base_type::fetch_or(storage, mask, order);
226 return !!(old_val & mask);
229 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
231 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
232 storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
233 storage_type old_val = base_type::fetch_and(storage, ~mask, order);
234 return !!(old_val & mask);
237 static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
239 BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
240 storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
241 storage_type old_val = base_type::fetch_xor(storage, mask, order);
242 return !!(old_val & mask);
246 template< typename Base, std::size_t Size, bool Signed >
247 struct extra_operations< Base, Size, Signed, false > :
248 public extra_operations_emulated< Base, Size, Signed >
252 } // namespace detail
253 } // namespace atomics
256 #include <boost/atomic/detail/footer.hpp>
258 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_