Back to home page

EIC code displayed by LXR

 
 

    


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

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 Andrey Semashev
0007  */
0008 /*!
0009  * \file   atomic/detail/wait_ops_futex.hpp
0010  *
0011  * This header contains implementation of the waiting/notifying atomic operations based on futexes.
0012  */
0013 
0014 #ifndef BOOST_ATOMIC_DETAIL_WAIT_OPS_FUTEX_HPP_INCLUDED_
0015 #define BOOST_ATOMIC_DETAIL_WAIT_OPS_FUTEX_HPP_INCLUDED_
0016 
0017 #include <boost/memory_order.hpp>
0018 #include <boost/atomic/detail/config.hpp>
0019 #include <boost/atomic/detail/futex.hpp>
0020 #include <boost/atomic/detail/wait_operations_fwd.hpp>
0021 #include <boost/atomic/detail/header.hpp>
0022 
0023 #ifdef BOOST_HAS_PRAGMA_ONCE
0024 #pragma once
0025 #endif
0026 
0027 namespace boost {
0028 namespace atomics {
0029 namespace detail {
0030 
0031 template< typename Base >
0032 struct wait_operations< Base, 4u, true, false > :
0033     public Base
0034 {
0035     typedef Base base_type;
0036     typedef typename base_type::storage_type storage_type;
0037 
0038     static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = true;
0039 
0040     static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
0041     {
0042         return true;
0043     }
0044 
0045     static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
0046     {
0047         storage_type new_val = base_type::load(storage, order);
0048         while (new_val == old_val)
0049         {
0050             atomics::detail::futex_wait_private(const_cast< storage_type* >(&storage), old_val);
0051             new_val = base_type::load(storage, order);
0052         }
0053 
0054         return new_val;
0055     }
0056 
0057     static BOOST_FORCEINLINE void notify_one(storage_type volatile& storage) BOOST_NOEXCEPT
0058     {
0059         atomics::detail::futex_signal_private(const_cast< storage_type* >(&storage));
0060     }
0061 
0062     static BOOST_FORCEINLINE void notify_all(storage_type volatile& storage) BOOST_NOEXCEPT
0063     {
0064         atomics::detail::futex_broadcast_private(const_cast< storage_type* >(&storage));
0065     }
0066 };
0067 
0068 template< typename Base >
0069 struct wait_operations< Base, 4u, true, true > :
0070     public Base
0071 {
0072     typedef Base base_type;
0073     typedef typename base_type::storage_type storage_type;
0074 
0075     static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = true;
0076 
0077     static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
0078     {
0079         return true;
0080     }
0081 
0082     static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
0083     {
0084         storage_type new_val = base_type::load(storage, order);
0085         while (new_val == old_val)
0086         {
0087             atomics::detail::futex_wait(const_cast< storage_type* >(&storage), old_val);
0088             new_val = base_type::load(storage, order);
0089         }
0090 
0091         return new_val;
0092     }
0093 
0094     static BOOST_FORCEINLINE void notify_one(storage_type volatile& storage) BOOST_NOEXCEPT
0095     {
0096         atomics::detail::futex_signal(const_cast< storage_type* >(&storage));
0097     }
0098 
0099     static BOOST_FORCEINLINE void notify_all(storage_type volatile& storage) BOOST_NOEXCEPT
0100     {
0101         atomics::detail::futex_broadcast(const_cast< storage_type* >(&storage));
0102     }
0103 };
0104 
0105 } // namespace detail
0106 } // namespace atomics
0107 } // namespace boost
0108 
0109 #include <boost/atomic/detail/footer.hpp>
0110 
0111 #endif // BOOST_ATOMIC_DETAIL_WAIT_OPS_FUTEX_HPP_INCLUDED_