]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/atomic/detail/extra_ops_emulated.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / atomic / detail / extra_ops_emulated.hpp
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/extra_ops_emulated.hpp
10 *
11 * This header contains emulated (lock-based) implementation of the extra atomic operations.
12 */
13
14 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_
15 #define BOOST_ATOMIC_DETAIL_EXTRA_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/storage_traits.hpp>
22 #include <boost/atomic/detail/extra_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 extra operations
34 template< typename Base, std::size_t Size, bool Signed >
35 struct extra_operations_emulated :
36 public Base
37 {
38 typedef Base base_type;
39 typedef typename base_type::storage_type storage_type;
40 typedef typename base_type::scoped_lock scoped_lock;
41
42 static storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
43 {
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);
49 return old_val;
50 }
51
52 static storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
53 {
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);
58 s = new_val;
59 return new_val;
60 }
61
62 static storage_type add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
63 {
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;
68 new_val += v;
69 s = new_val;
70 return new_val;
71 }
72
73 static storage_type sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
74 {
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;
79 new_val -= v;
80 s = new_val;
81 return new_val;
82 }
83
84 static storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
85 {
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;
90 new_val &= v;
91 s = new_val;
92 return new_val;
93 }
94
95 static storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
96 {
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;
101 new_val |= v;
102 s = new_val;
103 return new_val;
104 }
105
106 static storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
107 {
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;
112 new_val ^= v;
113 s = new_val;
114 return new_val;
115 }
116
117 static storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
118 {
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);
124 return old_val;
125 }
126
127 static storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
128 {
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);
133 s = new_val;
134 return new_val;
135 }
136
137 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
138 {
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);
141 }
142
143 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
144 {
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);
147 }
148
149 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
150 {
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);
153 }
154
155 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
156 {
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);
159 }
160
161 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
162 {
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);
165 }
166
167 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
168 {
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);
171 }
172
173 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
174 {
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);
177 }
178
179 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
180 {
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);
183 }
184
185 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
186 {
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);
189 }
190
191 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
192 {
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);
195 }
196
197 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
198 {
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);
201 }
202
203 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
204 {
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);
207 }
208
209 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
210 {
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);
213 }
214
215 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
216 {
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);
219 }
220
221 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
222 {
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);
227 }
228
229 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
230 {
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);
235 }
236
237 static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
238 {
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);
243 }
244 };
245
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 >
249 {
250 };
251
252 } // namespace detail
253 } // namespace atomics
254 } // namespace boost
255
256 #include <boost/atomic/detail/footer.hpp>
257
258 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_