Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:33:54

0001 /*
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * Copyright (c) 2018 Andrey Semashev
0007  */
0008 /*!
0009  * \file   atomic/detail/extra_ops_emulated.hpp
0010  *
0011  * This header contains emulated (lock-based) implementation of the extra atomic operations.
0012  */
0013 
0014 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_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/extra_operations_fwd.hpp>
0022 #include <boost/atomic/detail/header.hpp>
0023 
0024 #ifdef BOOST_HAS_PRAGMA_ONCE
0025 #pragma once
0026 #endif
0027 
0028 namespace boost {
0029 namespace atomics {
0030 namespace detail {
0031 
0032 //! Emulated implementation of extra operations
0033 template< typename Base, std::size_t Size, bool Signed >
0034 struct extra_operations_emulated :
0035     public Base
0036 {
0037     typedef Base base_type;
0038     typedef typename base_type::storage_type storage_type;
0039     typedef typename base_type::scoped_lock scoped_lock;
0040 
0041     static storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
0042     {
0043         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0044         storage_type& s = const_cast< storage_type& >(storage);
0045         scoped_lock lock(&storage);
0046         storage_type old_val = s;
0047         s = static_cast< storage_type >(-old_val);
0048         return old_val;
0049     }
0050 
0051     static storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
0052     {
0053         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0054         storage_type& s = const_cast< storage_type& >(storage);
0055         scoped_lock lock(&storage);
0056         storage_type new_val = static_cast< storage_type >(-s);
0057         s = new_val;
0058         return new_val;
0059     }
0060 
0061     static storage_type add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
0062     {
0063         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0064         storage_type& s = const_cast< storage_type& >(storage);
0065         scoped_lock lock(&storage);
0066         storage_type new_val = s;
0067         new_val += v;
0068         s = new_val;
0069         return new_val;
0070     }
0071 
0072     static storage_type sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
0073     {
0074         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0075         storage_type& s = const_cast< storage_type& >(storage);
0076         scoped_lock lock(&storage);
0077         storage_type new_val = s;
0078         new_val -= v;
0079         s = new_val;
0080         return new_val;
0081     }
0082 
0083     static storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
0084     {
0085         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0086         storage_type& s = const_cast< storage_type& >(storage);
0087         scoped_lock lock(&storage);
0088         storage_type new_val = s;
0089         new_val &= v;
0090         s = new_val;
0091         return new_val;
0092     }
0093 
0094     static storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
0095     {
0096         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0097         storage_type& s = const_cast< storage_type& >(storage);
0098         scoped_lock lock(&storage);
0099         storage_type new_val = s;
0100         new_val |= v;
0101         s = new_val;
0102         return new_val;
0103     }
0104 
0105     static storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
0106     {
0107         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0108         storage_type& s = const_cast< storage_type& >(storage);
0109         scoped_lock lock(&storage);
0110         storage_type new_val = s;
0111         new_val ^= v;
0112         s = new_val;
0113         return new_val;
0114     }
0115 
0116     static storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
0117     {
0118         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0119         storage_type& s = const_cast< storage_type& >(storage);
0120         scoped_lock lock(&storage);
0121         storage_type old_val = s;
0122         s = static_cast< storage_type >(~old_val);
0123         return old_val;
0124     }
0125 
0126     static storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
0127     {
0128         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0129         storage_type& s = const_cast< storage_type& >(storage);
0130         scoped_lock lock(&storage);
0131         storage_type new_val = static_cast< storage_type >(~s);
0132         s = new_val;
0133         return new_val;
0134     }
0135 
0136     static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0137     {
0138         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0139         base_type::fetch_add(storage, v, order);
0140     }
0141 
0142     static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0143     {
0144         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0145         base_type::fetch_sub(storage, v, order);
0146     }
0147 
0148     static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0149     {
0150         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0151         fetch_negate(storage, order);
0152     }
0153 
0154     static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0155     {
0156         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0157         base_type::fetch_and(storage, v, order);
0158     }
0159 
0160     static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0161     {
0162         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0163         base_type::fetch_or(storage, v, order);
0164     }
0165 
0166     static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0167     {
0168         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0169         base_type::fetch_xor(storage, v, order);
0170     }
0171 
0172     static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0173     {
0174         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0175         fetch_complement(storage, order);
0176     }
0177 
0178     static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0179     {
0180         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0181         return !!add(storage, v, order);
0182     }
0183 
0184     static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0185     {
0186         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0187         return !!sub(storage, v, order);
0188     }
0189 
0190     static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0191     {
0192         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0193         return !!negate(storage, order);
0194     }
0195 
0196     static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0197     {
0198         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0199         return !!bitwise_and(storage, v, order);
0200     }
0201 
0202     static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0203     {
0204         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0205         return !!bitwise_or(storage, v, order);
0206     }
0207 
0208     static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
0209     {
0210         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0211         return !!bitwise_xor(storage, v, order);
0212     }
0213 
0214     static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
0215     {
0216         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0217         return !!bitwise_complement(storage, order);
0218     }
0219 
0220     static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0221     {
0222         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0223         storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
0224         storage_type old_val = base_type::fetch_or(storage, mask, order);
0225         return !!(old_val & mask);
0226     }
0227 
0228     static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0229     {
0230         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0231         storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
0232         storage_type old_val = base_type::fetch_and(storage, ~mask, order);
0233         return !!(old_val & mask);
0234     }
0235 
0236     static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
0237     {
0238         static_assert(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
0239         storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
0240         storage_type old_val = base_type::fetch_xor(storage, mask, order);
0241         return !!(old_val & mask);
0242     }
0243 };
0244 
0245 template< typename Base, std::size_t Size, bool Signed >
0246 struct extra_operations< Base, Size, Signed, false > :
0247     public extra_operations_emulated< Base, Size, Signed >
0248 {
0249 };
0250 
0251 } // namespace detail
0252 } // namespace atomics
0253 } // namespace boost
0254 
0255 #include <boost/atomic/detail/footer.hpp>
0256 
0257 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_