File indexing completed on 2026-09-04 08:42:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_ATOMIC_DETAIL_WAIT_OPS_WINDOWS_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_WAIT_OPS_WINDOWS_HPP_INCLUDED_
0016
0017 #include <cstddef>
0018 #include <cstdint>
0019 #include <chrono>
0020 #include <boost/memory_order.hpp>
0021 #include <boost/atomic/detail/config.hpp>
0022 #include <boost/atomic/detail/chrono.hpp>
0023 #include <boost/atomic/detail/wait_operations_fwd.hpp>
0024 #include <boost/atomic/detail/wait_capabilities.hpp>
0025 #include <boost/winapi/wait_constants.hpp>
0026 #include <boost/winapi/wait_on_address.hpp>
0027 #if (defined(BOOST_ATOMIC_FORCE_AUTO_LINK) || (!defined(BOOST_ALL_NO_LIB) && !defined(BOOST_ATOMIC_NO_LIB)))
0028 #define BOOST_LIB_NAME "synchronization"
0029 #if defined(BOOST_AUTO_LINK_NOMANGLE)
0030 #include <boost/config/auto_link.hpp>
0031 #else
0032 #define BOOST_AUTO_LINK_NOMANGLE
0033 #include <boost/config/auto_link.hpp>
0034 #undef BOOST_AUTO_LINK_NOMANGLE
0035 #endif
0036 #endif
0037 #include <boost/atomic/detail/header.hpp>
0038
0039 #ifdef BOOST_HAS_PRAGMA_ONCE
0040 #pragma once
0041 #endif
0042
0043 namespace boost {
0044 namespace atomics {
0045 namespace detail {
0046
0047 template< typename Base, std::size_t Size >
0048 struct wait_operations_windows :
0049 public Base
0050 {
0051 using base_type = Base;
0052 using storage_type = typename base_type::storage_type;
0053
0054 static constexpr bool always_has_native_wait_notify = true;
0055
0056 static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) noexcept
0057 {
0058 return true;
0059 }
0060
0061 static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) noexcept
0062 {
0063 storage_type new_val = base_type::load(storage, order);
0064 while (new_val == old_val)
0065 {
0066 boost::winapi::WaitOnAddress(const_cast< storage_type* >(&storage), &old_val, Size, boost::winapi::infinite);
0067 new_val = base_type::load(storage, order);
0068 }
0069
0070 return new_val;
0071 }
0072
0073 private:
0074 template< typename Clock >
0075 static BOOST_FORCEINLINE storage_type wait_until_impl
0076 (
0077 storage_type const volatile& storage,
0078 storage_type old_val,
0079 typename Clock::time_point timeout,
0080 typename Clock::time_point now,
0081 memory_order order,
0082 bool& timed_out
0083 ) noexcept(noexcept(Clock::now()))
0084 {
0085 storage_type new_val = base_type::load(storage, order);
0086 while (new_val == old_val)
0087 {
0088 const std::int64_t msec = atomics::detail::chrono::ceil< std::chrono::milliseconds >(timeout - now).count();
0089 if (msec <= 0)
0090 {
0091 timed_out = true;
0092 break;
0093 }
0094
0095 boost::winapi::WaitOnAddress
0096 (
0097 const_cast< storage_type* >(&storage),
0098 &old_val,
0099 Size,
0100 msec <= static_cast< std::int64_t >(boost::winapi::max_non_infinite_wait) ?
0101 static_cast< boost::winapi::DWORD_ >(msec) : boost::winapi::max_non_infinite_wait
0102 );
0103
0104 now = Clock::now();
0105 new_val = base_type::load(storage, order);
0106 }
0107
0108 return new_val;
0109 }
0110
0111 public:
0112 template< typename Clock, typename Duration >
0113 static BOOST_FORCEINLINE storage_type wait_until
0114 (
0115 storage_type const volatile& storage,
0116 storage_type old_val,
0117 std::chrono::time_point< Clock, Duration > timeout,
0118 memory_order order,
0119 bool& timed_out
0120 ) noexcept(noexcept(Clock::now()))
0121 {
0122 return wait_until_impl< Clock >(storage, old_val, timeout, Clock::now(), order, timed_out);
0123 }
0124
0125 template< typename Rep, typename Period >
0126 static BOOST_FORCEINLINE storage_type wait_for
0127 (
0128 storage_type const volatile& storage,
0129 storage_type old_val,
0130 std::chrono::duration< Rep, Period > timeout,
0131 memory_order order,
0132 bool& timed_out
0133 ) noexcept
0134 {
0135 const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
0136 return wait_until_impl< std::chrono::steady_clock >(storage, old_val, now + timeout, now, order, timed_out);
0137 }
0138
0139 static BOOST_FORCEINLINE void notify_one(storage_type volatile& storage) noexcept
0140 {
0141 boost::winapi::WakeByAddressSingle(const_cast< storage_type* >(&storage));
0142 }
0143
0144 static BOOST_FORCEINLINE void notify_all(storage_type volatile& storage) noexcept
0145 {
0146 boost::winapi::WakeByAddressAll(const_cast< storage_type* >(&storage));
0147 }
0148 };
0149
0150 template< typename Base >
0151 struct wait_operations< Base, 1u, true, false > :
0152 public wait_operations_windows< Base, 1u >
0153 {
0154 };
0155
0156 template< typename Base >
0157 struct wait_operations< Base, 2u, true, false > :
0158 public wait_operations_windows< Base, 2u >
0159 {
0160 };
0161
0162 template< typename Base >
0163 struct wait_operations< Base, 4u, true, false > :
0164 public wait_operations_windows< Base, 4u >
0165 {
0166 };
0167
0168 template< typename Base >
0169 struct wait_operations< Base, 8u, true, false > :
0170 public wait_operations_windows< Base, 8u >
0171 {
0172 };
0173
0174 }
0175 }
0176 }
0177
0178 #include <boost/atomic/detail/footer.hpp>
0179
0180 #endif