Back to home page

EIC code displayed by LXR

 
 

    


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

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) 2011 Helge Bahmann
0007  * Copyright (c) 2013 Tim Blechmann
0008  * Copyright (c) 2014, 2020 Andrey Semashev
0009  */
0010 /*!
0011  * \file   atomic/detail/atomic_flag_impl.hpp
0012  *
0013  * This header contains implementation of \c atomic_flag.
0014  */
0015 
0016 #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_IMPL_HPP_INCLUDED_
0017 #define BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_IMPL_HPP_INCLUDED_
0018 
0019 #include <boost/assert.hpp>
0020 #include <boost/memory_order.hpp>
0021 #include <boost/atomic/detail/config.hpp>
0022 #include <boost/atomic/detail/core_operations.hpp>
0023 #include <boost/atomic/detail/wait_operations.hpp>
0024 #include <boost/atomic/detail/aligned_variable.hpp>
0025 #include <boost/atomic/detail/header.hpp>
0026 
0027 #ifdef BOOST_HAS_PRAGMA_ONCE
0028 #pragma once
0029 #endif
0030 
0031 /*
0032  * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
0033  *                      see comment for convert_memory_order_to_gcc in gcc_atomic_memory_order_utils.hpp.
0034  */
0035 
0036 namespace boost {
0037 namespace atomics {
0038 namespace detail {
0039 
0040 #if defined(BOOST_ATOMIC_DETAIL_NO_CXX11_CONSTEXPR_UNION_INIT) || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
0041 #define BOOST_ATOMIC_NO_ATOMIC_FLAG_INIT
0042 #else
0043 #define BOOST_ATOMIC_FLAG_INIT {}
0044 #endif
0045 
0046 //! Atomic flag implementation
0047 template< bool IsInterprocess >
0048 struct atomic_flag_impl
0049 {
0050     // Prefer 4-byte storage as most platforms support waiting/notifying operations without a lock pool for 32-bit integers
0051     typedef atomics::detail::core_operations< 4u, false, IsInterprocess > core_operations;
0052     typedef atomics::detail::wait_operations< core_operations > wait_operations;
0053     typedef typename core_operations::storage_type storage_type;
0054 
0055     static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = core_operations::is_always_lock_free;
0056     static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = wait_operations::always_has_native_wait_notify;
0057 
0058     BOOST_ATOMIC_DETAIL_ALIGNED_VAR_TPL(core_operations::storage_alignment, storage_type, m_storage);
0059 
0060     BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT atomic_flag_impl() BOOST_NOEXCEPT : m_storage(0u)
0061     {
0062     }
0063 
0064     BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT
0065     {
0066         return is_always_lock_free;
0067     }
0068 
0069     BOOST_FORCEINLINE bool has_native_wait_notify() const volatile BOOST_NOEXCEPT
0070     {
0071         return wait_operations::has_native_wait_notify(m_storage);
0072     }
0073 
0074     BOOST_FORCEINLINE bool test(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0075     {
0076         BOOST_ASSERT(order != memory_order_release);
0077         BOOST_ASSERT(order != memory_order_acq_rel);
0078         return !!core_operations::load(m_storage, order);
0079     }
0080 
0081     BOOST_FORCEINLINE bool test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0082     {
0083         return core_operations::test_and_set(m_storage, order);
0084     }
0085 
0086     BOOST_FORCEINLINE void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
0087     {
0088         BOOST_ASSERT(order != memory_order_consume);
0089         BOOST_ASSERT(order != memory_order_acquire);
0090         BOOST_ASSERT(order != memory_order_acq_rel);
0091         core_operations::clear(m_storage, order);
0092     }
0093 
0094     BOOST_FORCEINLINE bool wait(bool old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
0095     {
0096         BOOST_ASSERT(order != memory_order_release);
0097         BOOST_ASSERT(order != memory_order_acq_rel);
0098 
0099         return !!wait_operations::wait(m_storage, static_cast< storage_type >(old_val), order);
0100     }
0101 
0102     BOOST_FORCEINLINE void notify_one() volatile BOOST_NOEXCEPT
0103     {
0104         wait_operations::notify_one(m_storage);
0105     }
0106 
0107     BOOST_FORCEINLINE void notify_all() volatile BOOST_NOEXCEPT
0108     {
0109         wait_operations::notify_all(m_storage);
0110     }
0111 
0112     BOOST_DELETED_FUNCTION(atomic_flag_impl(atomic_flag_impl const&))
0113     BOOST_DELETED_FUNCTION(atomic_flag_impl& operator= (atomic_flag_impl const&))
0114 };
0115 
0116 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
0117 template< bool IsInterprocess >
0118 BOOST_CONSTEXPR_OR_CONST bool atomic_flag_impl< IsInterprocess >::is_always_lock_free;
0119 template< bool IsInterprocess >
0120 BOOST_CONSTEXPR_OR_CONST bool atomic_flag_impl< IsInterprocess >::always_has_native_wait_notify;
0121 #endif
0122 
0123 } // namespace detail
0124 } // namespace atomics
0125 } // namespace boost
0126 
0127 #include <boost/atomic/detail/footer.hpp>
0128 
0129 #endif // BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_IMPL_HPP_INCLUDED_