Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-04 08:42: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) 2020-2025 Andrey Semashev
0007  */
0008 /*!
0009  * \file   atomic/detail/wait_ops_windows.hpp
0010  *
0011  * This header contains implementation of the waiting/notifying atomic operations on Windows.
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 // defined(BOOST_AUTO_LINK_NOMANGLE)
0032 #define BOOST_AUTO_LINK_NOMANGLE
0033 #include <boost/config/auto_link.hpp>
0034 #undef BOOST_AUTO_LINK_NOMANGLE
0035 #endif // defined(BOOST_AUTO_LINK_NOMANGLE)
0036 #endif // (defined(BOOST_ATOMIC_FORCE_AUTO_LINK) || (!defined(BOOST_ALL_NO_LIB) && !defined(BOOST_ATOMIC_NO_LIB)))
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 } // namespace detail
0175 } // namespace atomics
0176 } // namespace boost
0177 
0178 #include <boost/atomic/detail/footer.hpp>
0179 
0180 #endif // BOOST_ATOMIC_DETAIL_WAIT_OPS_WINDOWS_HPP_INCLUDED_