File indexing completed on 2025-01-30 09:33:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_ATOMIC_DETAIL_WAIT_OPS_GENERIC_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_WAIT_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/pause.hpp>
0021 #include <boost/atomic/detail/lock_pool.hpp>
0022 #include <boost/atomic/detail/wait_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, bool Interprocess >
0035 struct wait_operations_generic;
0036
0037 template< typename Base >
0038 struct wait_operations_generic< Base, false > :
0039 public Base
0040 {
0041 typedef Base base_type;
0042 typedef typename base_type::storage_type storage_type;
0043 typedef lock_pool::scoped_lock< base_type::storage_alignment, true > scoped_lock;
0044 typedef lock_pool::scoped_wait_state< base_type::storage_alignment > scoped_wait_state;
0045
0046 static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = false;
0047
0048 static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
0049 {
0050 return false;
0051 }
0052
0053 static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
0054 {
0055 storage_type new_val = base_type::load(storage, order);
0056 if (new_val == old_val)
0057 {
0058 scoped_wait_state wait_state(&storage);
0059 new_val = base_type::load(storage, order);
0060 while (new_val == old_val)
0061 {
0062 wait_state.wait();
0063 new_val = base_type::load(storage, order);
0064 }
0065 }
0066
0067 return new_val;
0068 }
0069
0070 static BOOST_FORCEINLINE void notify_one(storage_type volatile& storage) BOOST_NOEXCEPT
0071 {
0072 scoped_lock lock(&storage);
0073 lock_pool::notify_one(lock.get_lock_state(), &storage);
0074 }
0075
0076 static BOOST_FORCEINLINE void notify_all(storage_type volatile& storage) BOOST_NOEXCEPT
0077 {
0078 scoped_lock lock(&storage);
0079 lock_pool::notify_all(lock.get_lock_state(), &storage);
0080 }
0081 };
0082
0083 template< typename Base >
0084 struct wait_operations_generic< Base, true > :
0085 public Base
0086 {
0087 typedef Base base_type;
0088 typedef typename base_type::storage_type storage_type;
0089
0090 static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = false;
0091
0092 static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
0093 {
0094 return false;
0095 }
0096
0097 static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
0098 {
0099 storage_type new_val = base_type::load(storage, order);
0100 if (new_val == old_val)
0101 {
0102 for (unsigned int i = 0u; i < 16u; ++i)
0103 {
0104 atomics::detail::pause();
0105 new_val = base_type::load(storage, order);
0106 if (new_val != old_val)
0107 goto finish;
0108 }
0109
0110 do
0111 {
0112 atomics::detail::wait_some();
0113 new_val = base_type::load(storage, order);
0114 }
0115 while (new_val == old_val);
0116 }
0117
0118 finish:
0119 return new_val;
0120 }
0121
0122 static BOOST_FORCEINLINE void notify_one(storage_type volatile&) BOOST_NOEXCEPT
0123 {
0124 }
0125
0126 static BOOST_FORCEINLINE void notify_all(storage_type volatile&) BOOST_NOEXCEPT
0127 {
0128 }
0129 };
0130
0131 template< typename Base, std::size_t Size, bool Interprocess >
0132 struct wait_operations< Base, Size, true, Interprocess > :
0133 public wait_operations_generic< Base, Interprocess >
0134 {
0135 };
0136
0137 }
0138 }
0139 }
0140
0141 #include <boost/atomic/detail/footer.hpp>
0142
0143 #endif