From bf182818f4c55f254c254c5bbaf07f0be952d2cb Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 30 May 2020 14:47:28 +0300 Subject: [PATCH] Added futex-based implementation for waiting/notifying operations. --- include/boost/atomic/detail/platform.hpp | 9 +++ .../boost/atomic/detail/wait_ops_futex.hpp | 64 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 include/boost/atomic/detail/wait_ops_futex.hpp diff --git a/include/boost/atomic/detail/platform.hpp b/include/boost/atomic/detail/platform.hpp index b8955d7..6f1916f 100644 --- a/include/boost/atomic/detail/platform.hpp +++ b/include/boost/atomic/detail/platform.hpp @@ -133,6 +133,15 @@ #endif // !defined(BOOST_ATOMIC_DETAIL_CORE_BACKEND) +// Waiting and notifying operations backends +#if !defined(BOOST_WINDOWS) +#include + +#if defined(BOOST_ATOMIC_DETAIL_HAS_FUTEX) +#define BOOST_ATOMIC_DETAIL_WAIT_BACKEND futex +#endif +#endif // !defined(BOOST_WINDOWS) + #endif // !defined(BOOST_ATOMIC_FORCE_FALLBACK) #if !defined(BOOST_ATOMIC_DETAIL_CORE_BACKEND) diff --git a/include/boost/atomic/detail/wait_ops_futex.hpp b/include/boost/atomic/detail/wait_ops_futex.hpp new file mode 100644 index 0000000..7e73cbe --- /dev/null +++ b/include/boost/atomic/detail/wait_ops_futex.hpp @@ -0,0 +1,64 @@ +/* + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * Copyright (c) 2020 Andrey Semashev + */ +/*! + * \file atomic/detail/wait_ops_futex.hpp + * + * This header contains implementation of the wait/notify atomic operations based on futexes. + */ + +#ifndef BOOST_ATOMIC_DETAIL_WAIT_OPS_FUTEX_HPP_INCLUDED_ +#define BOOST_ATOMIC_DETAIL_WAIT_OPS_FUTEX_HPP_INCLUDED_ + +#include +#include +#include +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { +namespace atomics { +namespace detail { + +template< typename Base > +struct wait_operations< Base, 4u, true > : + public Base +{ + typedef Base base_type; + typedef typename base_type::storage_type storage_type; + + static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT + { + storage_type new_val = base_type::load(storage, order); + while (new_val == old_val) + { + atomics::detail::futex_wait_private(const_cast< storage_type* >(&storage), old_val); + new_val = base_type::load(storage, order); + } + + return new_val; + } + + static BOOST_FORCEINLINE void notify_one(storage_type volatile& storage) BOOST_NOEXCEPT + { + atomics::detail::futex_signal_private(const_cast< storage_type* >(&storage)); + } + + static BOOST_FORCEINLINE void notify_all(storage_type volatile& storage) BOOST_NOEXCEPT + { + atomics::detail::futex_broadcast_private(const_cast< storage_type* >(&storage)); + } +}; + +} // namespace detail +} // namespace atomics +} // namespace boost + +#endif // BOOST_ATOMIC_DETAIL_WAIT_OPS_FUTEX_HPP_INCLUDED_