From c849b6d877469d8a4ea013b9221f2aa2ec3bb3c9 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sun, 31 May 2020 17:42:30 +0300 Subject: [PATCH] Use 32-bit storage to implement atomic_flag. Most platforms that support futexes or similar mechanisms support it for 32-bit integers, which makes it more preferred to implement atomic_flag efficiently. Most architectures also support 32-bit atomic operations natively as well. Also, reduced code duplication in instantiating operation backends. --- include/boost/atomic/detail/atomic_flag.hpp | 5 +++-- .../boost/atomic/detail/atomic_ref_template.hpp | 14 +++++++------- include/boost/atomic/detail/atomic_template.hpp | 12 ++++++------ .../atomic/detail/extra_fp_operations_fwd.hpp | 2 +- .../boost/atomic/detail/extra_operations_fwd.hpp | 2 +- include/boost/atomic/detail/fp_operations_fwd.hpp | 2 +- .../boost/atomic/detail/wait_operations_fwd.hpp | 2 +- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/include/boost/atomic/detail/atomic_flag.hpp b/include/boost/atomic/detail/atomic_flag.hpp index 8223498..2739264 100644 --- a/include/boost/atomic/detail/atomic_flag.hpp +++ b/include/boost/atomic/detail/atomic_flag.hpp @@ -41,8 +41,9 @@ namespace atomics { struct atomic_flag { - typedef atomics::detail::operations< 1u, false > operations; - typedef atomics::detail::wait_operations< operations, 1u > wait_operations; + // Prefer 4-byte storage as most platforms support waiting/notifying operations without a lock pool for 32-bit integers + typedef atomics::detail::operations< 4u, false > operations; + typedef atomics::detail::wait_operations< operations > wait_operations; typedef operations::storage_type storage_type; BOOST_ATOMIC_DETAIL_ALIGNED_VAR(operations::storage_alignment, storage_type, m_storage); diff --git a/include/boost/atomic/detail/atomic_ref_template.hpp b/include/boost/atomic/detail/atomic_ref_template.hpp index 46888d6..ba8543e 100644 --- a/include/boost/atomic/detail/atomic_ref_template.hpp +++ b/include/boost/atomic/detail/atomic_ref_template.hpp @@ -82,7 +82,7 @@ protected: atomics::detail::operations< sizeof(value_type), IsSigned >, atomics::detail::emulated_operations< sizeof(value_type), atomics::detail::alignment_of< value_type >::value, IsSigned > >::type operations; - typedef atomics::detail::wait_operations< operations, sizeof(value_type) > wait_operations; + typedef atomics::detail::wait_operations< operations > wait_operations; typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type; typedef typename operations::storage_type storage_type; BOOST_STATIC_ASSERT_MSG(sizeof(storage_type) == sizeof(value_type), "Boost.Atomic internal error: atomic_ref storage size doesn't match the value size"); @@ -276,7 +276,7 @@ public: protected: typedef typename base_type::operations operations; typedef typename base_type::wait_operations wait_operations; - typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations; + typedef atomics::detail::extra_operations< operations > extra_operations; typedef typename base_type::storage_type storage_type; typedef value_type value_arg_type; @@ -605,7 +605,7 @@ public: protected: typedef base_type::operations operations; typedef base_type::wait_operations wait_operations; - typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations; + typedef atomics::detail::extra_operations< operations > extra_operations; typedef base_type::storage_type storage_type; typedef value_type value_arg_type; @@ -733,9 +733,9 @@ public: protected: typedef typename base_type::operations operations; typedef typename base_type::wait_operations wait_operations; - typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations; - typedef atomics::detail::fp_operations< extra_operations, value_type, operations::storage_size > fp_operations; - typedef atomics::detail::extra_fp_operations< fp_operations, value_type, operations::storage_size > extra_fp_operations; + typedef atomics::detail::extra_operations< operations > extra_operations; + typedef atomics::detail::fp_operations< extra_operations, value_type > fp_operations; + typedef atomics::detail::extra_fp_operations< fp_operations > extra_fp_operations; typedef typename base_type::storage_type storage_type; typedef value_type value_arg_type; @@ -938,7 +938,7 @@ public: protected: typedef typename base_type::operations operations; typedef typename base_type::wait_operations wait_operations; - typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations; + typedef atomics::detail::extra_operations< operations > extra_operations; typedef typename base_type::storage_type storage_type; typedef value_type value_arg_type; diff --git a/include/boost/atomic/detail/atomic_template.hpp b/include/boost/atomic/detail/atomic_template.hpp index bc09482..74e65f7 100644 --- a/include/boost/atomic/detail/atomic_template.hpp +++ b/include/boost/atomic/detail/atomic_template.hpp @@ -71,7 +71,7 @@ public: protected: typedef atomics::detail::operations< storage_size_of< value_type >::value, IsSigned > operations; - typedef atomics::detail::wait_operations< operations, storage_size_of< value_type >::value > wait_operations; + typedef atomics::detail::wait_operations< operations > wait_operations; typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type; typedef typename operations::storage_type storage_type; @@ -310,7 +310,7 @@ public: protected: typedef typename base_type::operations operations; typedef typename base_type::wait_operations wait_operations; - typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations; + typedef atomics::detail::extra_operations< operations > extra_operations; typedef typename base_type::storage_type storage_type; typedef value_type value_arg_type; @@ -764,9 +764,9 @@ public: protected: typedef typename base_type::operations operations; typedef typename base_type::wait_operations wait_operations; - typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations; - typedef atomics::detail::fp_operations< extra_operations, value_type, operations::storage_size > fp_operations; - typedef atomics::detail::extra_fp_operations< fp_operations, value_type, operations::storage_size > extra_fp_operations; + typedef atomics::detail::extra_operations< operations > extra_operations; + typedef atomics::detail::fp_operations< extra_operations, value_type > fp_operations; + typedef atomics::detail::extra_fp_operations< fp_operations > extra_fp_operations; typedef typename base_type::storage_type storage_type; typedef value_type value_arg_type; @@ -951,7 +951,7 @@ public: protected: typedef typename base_type::operations operations; typedef typename base_type::wait_operations wait_operations; - typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations; + typedef atomics::detail::extra_operations< operations > extra_operations; typedef typename base_type::storage_type storage_type; typedef value_type value_arg_type; diff --git a/include/boost/atomic/detail/extra_fp_operations_fwd.hpp b/include/boost/atomic/detail/extra_fp_operations_fwd.hpp index 79bca9d..f9c70ad 100644 --- a/include/boost/atomic/detail/extra_fp_operations_fwd.hpp +++ b/include/boost/atomic/detail/extra_fp_operations_fwd.hpp @@ -25,7 +25,7 @@ namespace boost { namespace atomics { namespace detail { -template< typename Base, typename Value, std::size_t Size, bool = Base::is_always_lock_free > +template< typename Base, typename Value = typename Base::value_type, std::size_t Size = sizeof(typename Base::storage_type), bool = Base::is_always_lock_free > struct extra_fp_operations; } // namespace detail diff --git a/include/boost/atomic/detail/extra_operations_fwd.hpp b/include/boost/atomic/detail/extra_operations_fwd.hpp index 399a823..a57960e 100644 --- a/include/boost/atomic/detail/extra_operations_fwd.hpp +++ b/include/boost/atomic/detail/extra_operations_fwd.hpp @@ -25,7 +25,7 @@ namespace boost { namespace atomics { namespace detail { -template< typename Base, std::size_t Size, bool Signed, bool = Base::is_always_lock_free > +template< typename Base, std::size_t Size = sizeof(typename Base::storage_type), bool Signed = Base::is_signed, bool = Base::is_always_lock_free > struct extra_operations; } // namespace detail diff --git a/include/boost/atomic/detail/fp_operations_fwd.hpp b/include/boost/atomic/detail/fp_operations_fwd.hpp index 8696de3..4fc57b0 100644 --- a/include/boost/atomic/detail/fp_operations_fwd.hpp +++ b/include/boost/atomic/detail/fp_operations_fwd.hpp @@ -25,7 +25,7 @@ namespace boost { namespace atomics { namespace detail { -template< typename Base, typename Value, std::size_t Size, bool = Base::is_always_lock_free > +template< typename Base, typename Value, std::size_t Size = sizeof(typename Base::storage_type), bool = Base::is_always_lock_free > struct fp_operations; } // namespace detail diff --git a/include/boost/atomic/detail/wait_operations_fwd.hpp b/include/boost/atomic/detail/wait_operations_fwd.hpp index 5e8c6d6..dac6d5c 100644 --- a/include/boost/atomic/detail/wait_operations_fwd.hpp +++ b/include/boost/atomic/detail/wait_operations_fwd.hpp @@ -25,7 +25,7 @@ namespace boost { namespace atomics { namespace detail { -template< typename Base, std::size_t Size, bool = Base::is_always_lock_free > +template< typename Base, std::size_t Size = sizeof(typename Base::storage_type), bool = Base::is_always_lock_free > struct wait_operations; } // namespace detail