File indexing completed on 2025-01-30 09:33:56
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_
0016
0017 #include <cstddef>
0018 #include <boost/memory_order.hpp>
0019 #include <boost/atomic/detail/config.hpp>
0020 #include <boost/atomic/detail/storage_traits.hpp>
0021 #include <boost/atomic/detail/integral_conversions.hpp>
0022 #include <boost/atomic/detail/extra_operations_fwd.hpp>
0023 #include <boost/atomic/detail/header.hpp>
0024
0025 #ifdef BOOST_HAS_PRAGMA_ONCE
0026 #pragma once
0027 #endif
0028
0029 namespace boost {
0030 namespace atomics {
0031 namespace detail {
0032
0033
0034 template< typename Base, std::size_t Size, bool Signed, bool = Base::full_cas_based >
0035 struct extra_operations_generic :
0036 public Base
0037 {
0038 typedef Base base_type;
0039 typedef typename base_type::storage_type storage_type;
0040 typedef typename storage_traits< Size >::type emulated_storage_type;
0041
0042 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0043 {
0044 storage_type old_val;
0045 atomics::detail::non_atomic_load(storage, old_val);
0046 while (!base_type::compare_exchange_weak(storage, old_val, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val)), order, memory_order_relaxed)) {}
0047 return old_val;
0048 }
0049
0050 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0051 {
0052 storage_type old_val, new_val;
0053 atomics::detail::non_atomic_load(storage, old_val);
0054 do
0055 {
0056 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val));
0057 }
0058 while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
0059 return new_val;
0060 }
0061
0062 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0063 {
0064 return base_type::fetch_add(storage, v, order) + v;
0065 }
0066
0067 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0068 {
0069 return base_type::fetch_sub(storage, v, order) - v;
0070 }
0071
0072 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0073 {
0074 return base_type::fetch_and(storage, v, order) & v;
0075 }
0076
0077 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0078 {
0079 return base_type::fetch_or(storage, v, order) | v;
0080 }
0081
0082 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0083 {
0084 return base_type::fetch_xor(storage, v, order) ^ v;
0085 }
0086
0087 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0088 {
0089 return base_type::fetch_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order);
0090 }
0091
0092 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0093 {
0094 const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u)));
0095 return base_type::fetch_xor(storage, mask, order) ^ mask;
0096 }
0097
0098 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0099 {
0100 base_type::fetch_add(storage, v, order);
0101 }
0102
0103 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0104 {
0105 base_type::fetch_sub(storage, v, order);
0106 }
0107
0108 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0109 {
0110 fetch_negate(storage, order);
0111 }
0112
0113 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0114 {
0115 base_type::fetch_and(storage, v, order);
0116 }
0117
0118 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0119 {
0120 base_type::fetch_or(storage, v, order);
0121 }
0122
0123 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0124 {
0125 base_type::fetch_xor(storage, v, order);
0126 }
0127
0128 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0129 {
0130 fetch_complement(storage, order);
0131 }
0132
0133 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0134 {
0135 return !!static_cast< emulated_storage_type >(add(storage, v, order));
0136 }
0137
0138 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0139 {
0140 return !!static_cast< emulated_storage_type >(sub(storage, v, order));
0141 }
0142
0143 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0144 {
0145 return !!negate(storage, order);
0146 }
0147
0148 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0149 {
0150 return !!bitwise_and(storage, v, order);
0151 }
0152
0153 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0154 {
0155 return !!bitwise_or(storage, v, order);
0156 }
0157
0158 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0159 {
0160 return !!bitwise_xor(storage, v, order);
0161 }
0162
0163 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0164 {
0165 return !!static_cast< emulated_storage_type >(bitwise_complement(storage, order));
0166 }
0167
0168 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0169 {
0170 const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
0171 storage_type old_val = base_type::fetch_or(storage, mask, order);
0172 return !!(old_val & mask);
0173 }
0174
0175 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0176 {
0177 const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
0178 storage_type old_val = base_type::fetch_and(storage, ~mask, order);
0179 return !!(old_val & mask);
0180 }
0181
0182 static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0183 {
0184 const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
0185 storage_type old_val = base_type::fetch_xor(storage, mask, order);
0186 return !!(old_val & mask);
0187 }
0188 };
0189
0190
0191 template< typename Base, std::size_t Size, bool Signed >
0192 struct extra_operations_generic< Base, Size, Signed, true > :
0193 public Base
0194 {
0195 typedef Base base_type;
0196 typedef typename base_type::storage_type storage_type;
0197 typedef typename storage_traits< Size >::type emulated_storage_type;
0198
0199 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0200 {
0201 storage_type old_val;
0202 atomics::detail::non_atomic_load(storage, old_val);
0203 while (!base_type::compare_exchange_weak(storage, old_val, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val)), order, memory_order_relaxed)) {}
0204 return old_val;
0205 }
0206
0207 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0208 {
0209 storage_type old_val, new_val;
0210 atomics::detail::non_atomic_load(storage, old_val);
0211 do
0212 {
0213 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val));
0214 }
0215 while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
0216 return new_val;
0217 }
0218
0219 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0220 {
0221 storage_type old_val, new_val;
0222 atomics::detail::non_atomic_load(storage, old_val);
0223 do
0224 {
0225 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val + v));
0226 }
0227 while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
0228 return new_val;
0229 }
0230
0231 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0232 {
0233 storage_type old_val, new_val;
0234 atomics::detail::non_atomic_load(storage, old_val);
0235 do
0236 {
0237 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val - v));
0238 }
0239 while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
0240 return new_val;
0241 }
0242
0243 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0244 {
0245 storage_type old_val, new_val;
0246 atomics::detail::non_atomic_load(storage, old_val);
0247 do
0248 {
0249 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val & v));
0250 }
0251 while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
0252 return new_val;
0253 }
0254
0255 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0256 {
0257 storage_type old_val, new_val;
0258 atomics::detail::non_atomic_load(storage, old_val);
0259 do
0260 {
0261 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val | v));
0262 }
0263 while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
0264 return new_val;
0265 }
0266
0267 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0268 {
0269 storage_type old_val, new_val;
0270 atomics::detail::non_atomic_load(storage, old_val);
0271 do
0272 {
0273 new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val ^ v));
0274 }
0275 while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
0276 return new_val;
0277 }
0278
0279 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0280 {
0281 return base_type::fetch_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order);
0282 }
0283
0284 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0285 {
0286 return bitwise_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order);
0287 }
0288
0289 static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0290 {
0291 base_type::fetch_add(storage, v, order);
0292 }
0293
0294 static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0295 {
0296 base_type::fetch_sub(storage, v, order);
0297 }
0298
0299 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0300 {
0301 fetch_negate(storage, order);
0302 }
0303
0304 static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0305 {
0306 base_type::fetch_and(storage, v, order);
0307 }
0308
0309 static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0310 {
0311 base_type::fetch_or(storage, v, order);
0312 }
0313
0314 static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0315 {
0316 base_type::fetch_xor(storage, v, order);
0317 }
0318
0319 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0320 {
0321 fetch_complement(storage, order);
0322 }
0323
0324 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0325 {
0326 return !!static_cast< emulated_storage_type >(add(storage, v, order));
0327 }
0328
0329 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0330 {
0331 return !!static_cast< emulated_storage_type >(sub(storage, v, order));
0332 }
0333
0334 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0335 {
0336 return !!negate(storage, order);
0337 }
0338
0339 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0340 {
0341 return !!bitwise_and(storage, v, order);
0342 }
0343
0344 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0345 {
0346 return !!bitwise_or(storage, v, order);
0347 }
0348
0349 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0350 {
0351 return !!bitwise_xor(storage, v, order);
0352 }
0353
0354 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0355 {
0356 return !!static_cast< emulated_storage_type >(bitwise_complement(storage, order));
0357 }
0358
0359 static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0360 {
0361 const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
0362 storage_type old_val = base_type::fetch_or(storage, mask, order);
0363 return !!(old_val & mask);
0364 }
0365
0366 static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0367 {
0368 const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
0369 storage_type old_val = base_type::fetch_and(storage, ~mask, order);
0370 return !!(old_val & mask);
0371 }
0372
0373 static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0374 {
0375 const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
0376 storage_type old_val = base_type::fetch_xor(storage, mask, order);
0377 return !!(old_val & mask);
0378 }
0379 };
0380
0381
0382 template< typename Base, std::size_t Size, bool Signed >
0383 struct extra_operations< Base, Size, Signed, true > :
0384 public extra_operations_generic< Base, Size, Signed >
0385 {
0386 };
0387
0388 }
0389 }
0390 }
0391
0392 #include <boost/atomic/detail/footer.hpp>
0393
0394 #endif