From a2cf59ad0206ca9a6990a63aa98166e21c07551d Mon Sep 17 00:00:00 2001 From: Mike Popoloski Date: Sun, 15 Dec 2024 18:28:28 -0500 Subject: [PATCH] Remove unused stats tracking stuff --- boost_unordered.hpp | 826 ------------------ include/boost/core/detail/sp_thread_pause.hpp | 71 -- include/boost/core/detail/sp_thread_sleep.hpp | 121 --- include/boost/core/detail/sp_thread_yield.hpp | 99 --- include/boost/core/detail/sp_win32_sleep.hpp | 54 -- include/boost/core/yield_primitives.hpp | 12 - include/boost/unordered/detail/foa/core.hpp | 80 -- .../unordered/detail/foa/cumulative_stats.hpp | 176 ---- .../unordered/detail/foa/rw_spinlock.hpp | 179 ---- include/boost/unordered/detail/foa/table.hpp | 7 - .../boost/unordered/unordered_flat_map.hpp | 10 - .../boost/unordered/unordered_flat_set.hpp | 10 - .../boost/unordered/unordered_node_map.hpp | 10 - .../boost/unordered/unordered_node_set.hpp | 10 - make_unordered.sh | 6 +- 15 files changed, 2 insertions(+), 1669 deletions(-) delete mode 100644 include/boost/core/detail/sp_thread_pause.hpp delete mode 100644 include/boost/core/detail/sp_thread_sleep.hpp delete mode 100644 include/boost/core/detail/sp_thread_yield.hpp delete mode 100644 include/boost/core/detail/sp_win32_sleep.hpp delete mode 100644 include/boost/core/yield_primitives.hpp delete mode 100644 include/boost/unordered/detail/foa/cumulative_stats.hpp delete mode 100644 include/boost/unordered/detail/foa/rw_spinlock.hpp diff --git a/boost_unordered.hpp b/boost_unordered.hpp index c45ce47..4bc8808 100644 --- a/boost_unordered.hpp +++ b/boost_unordered.hpp @@ -29,7 +29,6 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #pragma once -#include #include #include #include @@ -1763,692 +1762,6 @@ __asm__(".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n" #endif // !defined(BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS) #endif // !defined(BOOST_UNORDERED_UNORDERED_PRINTERS_HPP) -#ifndef BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED -#define BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// boost/core/detail/sp_thread_pause.hpp -// -// inline void bost::core::sp_thread_pause(); -// -// Emits a "pause" instruction. -// -// Copyright 2008, 2020, 2023 Peter Dimov -// Distributed under the Boost Software License, Version 1.0 -// https://www.boost.org/LICENSE_1_0.txt - -#ifdef __has_builtin -# if __has_builtin(__builtin_ia32_pause) && !defined(__INTEL_COMPILER) -# define BOOST_CORE_HAS_BUILTIN_IA32_PAUSE -# endif -#endif - -#ifdef BOOST_CORE_HAS_BUILTIN_IA32_PAUSE - -# define BOOST_CORE_SP_PAUSE() __builtin_ia32_pause() - -#elif defined(_MSC_VER) && ( defined(_M_IX86) || defined(_M_X64) ) - -# include -# define BOOST_CORE_SP_PAUSE() _mm_pause() - -#elif defined(_MSC_VER) && ( defined(_M_ARM) || defined(_M_ARM64) ) - -# include -# define BOOST_CORE_SP_PAUSE() __yield() - -#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) - -# define BOOST_CORE_SP_PAUSE() __asm__ __volatile__( "rep; nop" : : : "memory" ) - -#elif defined(__GNUC__) && ( (defined(__ARM_ARCH) && __ARM_ARCH >= 8) || defined(__ARM_ARCH_8A__) || defined(__aarch64__) ) - -# define BOOST_CORE_SP_PAUSE() __asm__ __volatile__( "yield" : : : "memory" ) - -#else - -# define BOOST_CORE_SP_PAUSE() ((void)0) - -#endif - -namespace boost -{ -namespace core -{ - -BOOST_FORCEINLINE void sp_thread_pause() noexcept -{ - BOOST_CORE_SP_PAUSE(); -} - -} // namespace core -} // namespace boost - -#undef BOOST_CORE_SP_PAUSE - -#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED -#ifndef BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED -#define BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// boost/core/detail/sp_win32_sleep.hpp -// -// Declares the Win32 Sleep() function. -// -// Copyright 2008, 2020 Peter Dimov -// Distributed under the Boost Software License, Version 1.0 -// https://www.boost.org/LICENSE_1_0.txt - -#ifdef BOOST_USE_WINDOWS_H -# include -#endif - -namespace boost -{ -namespace core -{ -namespace detail -{ - -#ifndef BOOST_USE_WINDOWS_H - -#if defined(__clang__) && defined(__x86_64__) -// clang x64 warns that __stdcall is ignored -# define BOOST_CORE_SP_STDCALL -#else -# define BOOST_CORE_SP_STDCALL __stdcall -#endif - -#ifdef __LP64__ // Cygwin 64 - extern "C" __declspec(dllimport) void BOOST_CORE_SP_STDCALL Sleep( unsigned int ms ); -#else - extern "C" __declspec(dllimport) void BOOST_CORE_SP_STDCALL Sleep( unsigned long ms ); -#endif - -extern "C" __declspec(dllimport) int BOOST_CORE_SP_STDCALL SwitchToThread(); - -#undef BOOST_CORE_SP_STDCALL - -#endif // !defined( BOOST_USE_WINDOWS_H ) - -} // namespace detail -} // namespace core -} // namespace boost - -#endif // #ifndef BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED -#ifndef BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED -#define BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// boost/core/detail/sp_thread_yield.hpp -// -// inline void bost::core::sp_thread_yield(); -// -// Gives up the remainder of the time slice, -// as if by calling sched_yield(). -// -// Copyright 2008, 2020 Peter Dimov -// Distributed under the Boost Software License, Version 1.0 -// https://www.boost.org/LICENSE_1_0.txt - -#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) - -#ifdef BOOST_SP_REPORT_IMPLEMENTATION - BOOST_PRAGMA_MESSAGE("Using SwitchToThread() in sp_thread_yield") -#endif - -namespace boost -{ -namespace core -{ -namespace detail -{ - -inline void sp_thread_yield() noexcept -{ - SwitchToThread(); -} - -} // namespace detail - -using boost::core::detail::sp_thread_yield; - -} // namespace core -} // namespace boost - -#elif defined(BOOST_HAS_SCHED_YIELD) - -#ifdef BOOST_SP_REPORT_IMPLEMENTATION - BOOST_PRAGMA_MESSAGE("Using sched_yield() in sp_thread_yield") -#endif - -#ifndef _AIX -# include -#else - // AIX's sched.h defines ::var which sometimes conflicts with Lambda's var - extern "C" int sched_yield(void); -#endif - -namespace boost -{ -namespace core -{ - -inline void sp_thread_yield() noexcept -{ - sched_yield(); -} - -} // namespace core -} // namespace boost - -#else - -#ifdef BOOST_SP_REPORT_IMPLEMENTATION - BOOST_PRAGMA_MESSAGE("Using sp_thread_pause() in sp_thread_yield") -#endif - -namespace boost -{ -namespace core -{ - -inline void sp_thread_yield() noexcept -{ - sp_thread_pause(); -} - -} // namespace core -} // namespace boost - -#endif - -#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED -#ifndef BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED -#define BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// boost/core/detail/sp_thread_sleep.hpp -// -// inline void bost::core::sp_thread_sleep(); -// -// Cease execution for a while to yield to other threads, -// as if by calling nanosleep() with an appropriate interval. -// -// Copyright 2008, 2020, 2023 Peter Dimov -// Distributed under the Boost Software License, Version 1.0 -// https://www.boost.org/LICENSE_1_0.txt - -#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) - -#ifdef BOOST_SP_REPORT_IMPLEMENTATION - BOOST_PRAGMA_MESSAGE("Using Sleep(1) in sp_thread_sleep") -#endif - -namespace boost -{ -namespace core -{ -namespace detail -{ - -inline void sp_thread_sleep() noexcept -{ - Sleep( 1 ); -} - -} // namespace detail - -using boost::core::detail::sp_thread_sleep; - -} // namespace core -} // namespace boost - -#elif defined(BOOST_HAS_NANOSLEEP) - -#ifdef BOOST_SP_REPORT_IMPLEMENTATION - BOOST_PRAGMA_MESSAGE("Using nanosleep() in sp_thread_sleep") -#endif - -#include - -#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) -# include -#endif - -namespace boost -{ -namespace core -{ - -inline void sp_thread_sleep() noexcept -{ -#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) - - int oldst; - pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldst ); - -#endif - - // g++ -Wextra warns on {} or {0} - struct timespec rqtp = { 0, 0 }; - - // POSIX says that timespec has tv_sec and tv_nsec - // But it doesn't guarantee order or placement - - rqtp.tv_sec = 0; - rqtp.tv_nsec = 1000; - - nanosleep( &rqtp, 0 ); - -#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) - - pthread_setcancelstate( oldst, &oldst ); - -#endif - -} - -} // namespace core -} // namespace boost - -#else - -#ifdef BOOST_SP_REPORT_IMPLEMENTATION - BOOST_PRAGMA_MESSAGE("Using sp_thread_yield() in sp_thread_sleep") -#endif - -namespace boost -{ -namespace core -{ - -inline void sp_thread_sleep() noexcept -{ - sp_thread_yield(); -} - -} // namespace core -} // namespace boost - -#endif - -#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED -#ifndef BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED -#define BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED - -// Copyright 2023 Peter Dimov -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#endif // #ifndef BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED -#ifndef BOOST_UNORDERED_DETAIL_FOA_RW_SPINLOCK_HPP_INCLUDED -#define BOOST_UNORDERED_DETAIL_FOA_RW_SPINLOCK_HPP_INCLUDED - -// Copyright 2023 Peter Dimov -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -namespace boost{ -namespace unordered{ -namespace detail{ -namespace foa{ - -class rw_spinlock -{ -private: - - // bit 31: locked exclusive - // bit 30: writer pending - // bit 29..0: reader lock count - - static constexpr std::uint32_t locked_exclusive_mask = 1u << 31; // 0x8000'0000 - static constexpr std::uint32_t writer_pending_mask = 1u << 30; // 0x4000'0000 - static constexpr std::uint32_t reader_lock_count_mask = writer_pending_mask - 1; // 0x3FFF'FFFF - - std::atomic state_ = {}; - -private: - - // Effects: Provides a hint to the implementation that the current thread - // has been unable to make progress for k+1 iterations. - - static void yield( unsigned k ) noexcept - { - unsigned const sleep_every = 1024; // see below - - k %= sleep_every; - - if( k < 5 ) - { - // Intel recommendation from the Optimization Reference Manual - // Exponentially increase number of PAUSE instructions each - // iteration until reaching a maximum which is approximately - // one timeslice long (2^4 == 16 in our case) - - unsigned const pause_count = 1u << k; - - for( unsigned i = 0; i < pause_count; ++i ) - { - boost::core::sp_thread_pause(); - } - } - else if( k < sleep_every - 1 ) - { - // Once the maximum number of PAUSE instructions is reached, - // we switch to yielding the timeslice immediately - - boost::core::sp_thread_yield(); - } - else - { - // After `sleep_every` iterations of no progress, we sleep, - // to avoid a deadlock if a lower priority thread has the lock - - boost::core::sp_thread_sleep(); - } - } - -public: - - bool try_lock_shared() noexcept - { - std::uint32_t st = state_.load( std::memory_order_relaxed ); - - if( st >= reader_lock_count_mask ) - { - // either bit 31 set, bit 30 set, or reader count is max - return false; - } - - std::uint32_t newst = st + 1; - return state_.compare_exchange_strong( st, newst, std::memory_order_acquire, std::memory_order_relaxed ); - } - - void lock_shared() noexcept - { - for( unsigned k = 0; ; ++k ) - { - std::uint32_t st = state_.load( std::memory_order_relaxed ); - - if( st < reader_lock_count_mask ) - { - std::uint32_t newst = st + 1; - if( state_.compare_exchange_weak( st, newst, std::memory_order_acquire, std::memory_order_relaxed ) ) return; - } - - yield( k ); - } - } - - void unlock_shared() noexcept - { - // pre: locked shared, not locked exclusive - - state_.fetch_sub( 1, std::memory_order_release ); - - // if the writer pending bit is set, there's a writer waiting - // let it acquire the lock; it will clear the bit on unlock - } - - bool try_lock() noexcept - { - std::uint32_t st = state_.load( std::memory_order_relaxed ); - - if( st & locked_exclusive_mask ) - { - // locked exclusive - return false; - } - - if( st & reader_lock_count_mask ) - { - // locked shared - return false; - } - - std::uint32_t newst = locked_exclusive_mask; - return state_.compare_exchange_strong( st, newst, std::memory_order_acquire, std::memory_order_relaxed ); - } - - void lock() noexcept - { - for( unsigned k = 0; ; ++k ) - { - std::uint32_t st = state_.load( std::memory_order_relaxed ); - - if( st & locked_exclusive_mask ) - { - // locked exclusive, spin - } - else if( ( st & reader_lock_count_mask ) == 0 ) - { - // not locked exclusive, not locked shared, try to lock - - std::uint32_t newst = locked_exclusive_mask; - if( state_.compare_exchange_weak( st, newst, std::memory_order_acquire, std::memory_order_relaxed ) ) return; - } - else if( st & writer_pending_mask ) - { - // writer pending bit already set, nothing to do - } - else - { - // locked shared, set writer pending bit - - std::uint32_t newst = st | writer_pending_mask; - state_.compare_exchange_weak( st, newst, std::memory_order_relaxed, std::memory_order_relaxed ); - } - - yield( k ); - } - } - - void unlock() noexcept - { - // pre: locked exclusive, not locked shared - state_.store( 0, std::memory_order_release ); - } -}; - -} -} -} -} - -#endif // BOOST_UNORDERED_DETAIL_FOA_RW_SPINLOCK_HPP_INCLUDED -/* Copyright 2024 Joaquin M Lopez Munoz. - * 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) - * - * See https://www.boost.org/libs/unordered for library home page. - */ - -#ifndef BOOST_UNORDERED_DETAIL_FOA_CUMULATIVE_STATS_HPP -#define BOOST_UNORDERED_DETAIL_FOA_CUMULATIVE_STATS_HPP - -#include - -#ifdef BOOST_HAS_THREADS -#include -#endif - -namespace boost{ -namespace unordered{ -namespace detail{ -namespace foa{ - -/* Cumulative one-pass calculation of the average, variance and deviation of - * running sequences. - */ - -struct sequence_stats_data -{ - double m=0.0; - double m_prior=0.0; - double s=0.0; -}; - -struct welfords_algorithm -{ - template - int operator()(T&& x,sequence_stats_data& d)const noexcept - { - static_assert( - noexcept(static_cast(x)), - "Argument conversion to double must not throw."); - - d.m_prior=d.m; - d.m+=(static_cast(x)-d.m)/static_cast(n); - d.s+=(n!=1)* - (static_cast(x)-d.m_prior)*(static_cast(x)-d.m); - - return 0; - } - - std::size_t n; -}; - -struct sequence_stats_summary -{ - double average; - double variance; - double deviation; -}; - -/* Stats calculated jointly for N same-sized sequences to save the space - * for count. - */ - -template -class cumulative_stats -{ -public: - struct summary - { - std::size_t count; - std::array sequence_summary; - }; - - void reset()noexcept{*this=cumulative_stats();} - - template - void add(Ts&&... xs)noexcept - { - static_assert( - sizeof...(Ts)==N,"A sample must be provided for each sequence."); - - if(BOOST_UNLIKELY(++n==0)){ - reset(); - n=1; - } - mp11::tuple_transform( - welfords_algorithm{n}, - std::forward_as_tuple(std::forward(xs)...), - data); - } - - summary get_summary()const noexcept - { - summary res; - res.count=n; - for(std::size_t i=0;i(n):0.0, - deviation=std::sqrt(variance); - res.sequence_summary[i]={average,variance,deviation}; - } - return res; - } - -private: - std::size_t n=0; - std::array data; -}; - -#ifdef BOOST_HAS_THREADS - -template -class concurrent_cumulative_stats:cumulative_stats -{ - using super=cumulative_stats; - using lock_guard=std::lock_guard; - -public: - using summary=typename super::summary; - - concurrent_cumulative_stats()noexcept:super{}{} - concurrent_cumulative_stats(const concurrent_cumulative_stats& x)noexcept: - concurrent_cumulative_stats{x,lock_guard{x.mut}}{} - - concurrent_cumulative_stats& - operator=(const concurrent_cumulative_stats& x)noexcept - { - auto x1=x; - lock_guard lck{mut}; - static_cast(*this)=x1; - return *this; - } - - void reset()noexcept - { - lock_guard lck{mut}; - super::reset(); - } - - template - void add(Ts&&... xs)noexcept - { - lock_guard lck{mut}; - super::add(std::forward(xs)...); - } - - summary get_summary()const noexcept - { - lock_guard lck{mut}; - return super::get_summary(); - } - -private: - concurrent_cumulative_stats(const super& x,lock_guard&&):super{x}{} - - mutable rw_spinlock mut; -}; - -#else - -template -using concurrent_cumulative_stats=cumulative_stats; - -#endif - -} -} -} -} - -#endif /* Copyright 2023 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -3600,45 +2913,6 @@ struct table_arrays value_type_pointer elements_; }; -#ifdef BOOST_UNORDERED_ENABLE_STATS -/* stats support */ - -struct table_core_cumulative_stats -{ - concurrent_cumulative_stats<1> insertion; - concurrent_cumulative_stats<2> successful_lookup, - unsuccessful_lookup; -}; - -struct table_core_insertion_stats -{ - std::size_t count; - sequence_stats_summary probe_length; -}; - -struct table_core_lookup_stats -{ - std::size_t count; - sequence_stats_summary probe_length; - sequence_stats_summary num_comparisons; -}; - -struct table_core_stats -{ - table_core_insertion_stats insertion; - table_core_lookup_stats successful_lookup, - unsuccessful_lookup; -}; - -#define BOOST_UNORDERED_ADD_STATS(stats,args) stats.add args -#define BOOST_UNORDERED_SWAP_STATS(stats1,stats2) std::swap(stats1,stats2) -#define BOOST_UNORDERED_COPY_STATS(stats1,stats2) stats1=stats2 -#define BOOST_UNORDERED_RESET_STATS_OF(x) x.reset_stats() -#define BOOST_UNORDERED_STATS_COUNTER(name) std::size_t name=0 -#define BOOST_UNORDERED_INCREMENT_STATS_COUNTER(name) ++name - -#else - #define BOOST_UNORDERED_ADD_STATS(stats,args) ((void)0) #define BOOST_UNORDERED_SWAP_STATS(stats1,stats2) ((void)0) #define BOOST_UNORDERED_COPY_STATS(stats1,stats2) ((void)0) @@ -3646,8 +2920,6 @@ struct table_core_stats #define BOOST_UNORDERED_STATS_COUNTER(name) ((void)0) #define BOOST_UNORDERED_INCREMENT_STATS_COUNTER(name) ((void)0) -#endif - struct if_constexpr_void_else{void operator()()const{}}; template @@ -3908,11 +3180,6 @@ table_core:empty_value,empty_value,empty_value using locator=table_locator; using arrays_holder_type=arrays_holder; -#ifdef BOOST_UNORDERED_ENABLE_STATS - using cumulative_stats=table_core_cumulative_stats; - using stats=table_core_stats; -#endif - #ifdef BOOST_GCC #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" @@ -4287,38 +3554,6 @@ table_core:empty_value,empty_value,empty_value rehash(std::size_t(std::ceil(float(n)/mlf))); } -#ifdef BOOST_UNORDERED_ENABLE_STATS - stats get_stats()const - { - auto insertion=cstats.insertion.get_summary(); - auto successful_lookup=cstats.successful_lookup.get_summary(); - auto unsuccessful_lookup=cstats.unsuccessful_lookup.get_summary(); - return{ - { - insertion.count, - insertion.sequence_summary[0] - }, - { - successful_lookup.count, - successful_lookup.sequence_summary[0], - successful_lookup.sequence_summary[1] - }, - { - unsuccessful_lookup.count, - unsuccessful_lookup.sequence_summary[0], - unsuccessful_lookup.sequence_summary[1] - }, - }; - } - - void reset_stats()noexcept - { - cstats.insertion.reset(); - cstats.successful_lookup.reset(); - cstats.unsuccessful_lookup.reset(); - } -#endif - friend bool operator==(const table_core& x,const table_core& y) { return @@ -4529,10 +3764,6 @@ table_core:empty_value,empty_value,empty_value arrays_type arrays; size_ctrl_type size_ctrl; -#ifdef BOOST_UNORDERED_ENABLE_STATS - mutable cumulative_stats cstats; -#endif - private: template< typename,typename,template class, @@ -5191,10 +4422,6 @@ class table:table_core_impl const_iterator>::type; using erase_return_type=table_erase_return_type; -#ifdef BOOST_UNORDERED_ENABLE_STATS - using stats=typename super::stats; -#endif - table( std::size_t n=default_bucket_count,const Hash& h_=Hash(), const Pred& pred_=Pred(),const Allocator& al_=Allocator()): @@ -5376,11 +4603,6 @@ class table:table_core_impl using super::rehash; using super::reserve; -#ifdef BOOST_UNORDERED_ENABLE_STATS - using super::get_stats; - using super::reset_stats; -#endif - template friend std::size_t erase_if(table& x,Predicate& pr) { @@ -7081,10 +6303,6 @@ namespace boost { using iterator = typename table_type::iterator; using const_iterator = typename table_type::const_iterator; -#ifdef BOOST_UNORDERED_ENABLE_STATS - using stats = typename table_type::stats; -#endif - unordered_flat_set() : unordered_flat_set(0) {} explicit unordered_flat_set(size_type n, hasher const& h = hasher(), @@ -7495,14 +6713,6 @@ namespace boost { void reserve(size_type n) { table_.reserve(n); } -#ifdef BOOST_UNORDERED_ENABLE_STATS - /// Stats - /// - stats get_stats() const { return table_.get_stats(); } - - void reset_stats() noexcept { table_.reset_stats(); } -#endif - /// Observers /// @@ -8923,10 +8133,6 @@ namespace boost { using iterator = typename table_type::iterator; using const_iterator = typename table_type::const_iterator; -#ifdef BOOST_UNORDERED_ENABLE_STATS - using stats = typename table_type::stats; -#endif - unordered_flat_map() : unordered_flat_map(0) {} explicit unordered_flat_map(size_type n, hasher const& h = hasher(), @@ -9513,14 +8719,6 @@ namespace boost { void reserve(size_type n) { table_.reserve(n); } -#ifdef BOOST_UNORDERED_ENABLE_STATS - /// Stats - /// - stats get_stats() const { return table_.get_stats(); } - - void reset_stats() noexcept { table_.reset_stats(); } -#endif - /// Observers /// @@ -10343,10 +9541,6 @@ namespace boost { using insert_return_type = detail::foa::insert_return_type; -#ifdef BOOST_UNORDERED_ENABLE_STATS - using stats = typename table_type::stats; -#endif - unordered_node_set() : unordered_node_set(0) {} explicit unordered_node_set(size_type n, hasher const& h = hasher(), @@ -10824,14 +10018,6 @@ namespace boost { void reserve(size_type n) { table_.reserve(n); } -#ifdef BOOST_UNORDERED_ENABLE_STATS - /// Stats - /// - stats get_stats() const { return table_.get_stats(); } - - void reset_stats() noexcept { table_.reset_stats(); } -#endif - /// Observers /// @@ -11331,10 +10517,6 @@ namespace boost { using insert_return_type = detail::foa::insert_return_type; -#ifdef BOOST_UNORDERED_ENABLE_STATS - using stats = typename table_type::stats; -#endif - unordered_node_map() : unordered_node_map(0) {} explicit unordered_node_map(size_type n, hasher const& h = hasher(), @@ -11988,14 +11170,6 @@ namespace boost { void reserve(size_type n) { table_.reserve(n); } -#ifdef BOOST_UNORDERED_ENABLE_STATS - /// Stats - /// - stats get_stats() const { return table_.get_stats(); } - - void reset_stats() noexcept { table_.reset_stats(); } -#endif - /// Observers /// diff --git a/include/boost/core/detail/sp_thread_pause.hpp b/include/boost/core/detail/sp_thread_pause.hpp deleted file mode 100644 index 67738e2..0000000 --- a/include/boost/core/detail/sp_thread_pause.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED -#define BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// boost/core/detail/sp_thread_pause.hpp -// -// inline void bost::core::sp_thread_pause(); -// -// Emits a "pause" instruction. -// -// Copyright 2008, 2020, 2023 Peter Dimov -// Distributed under the Boost Software License, Version 1.0 -// https://www.boost.org/LICENSE_1_0.txt - -#include - -#if defined(__has_builtin) -# if __has_builtin(__builtin_ia32_pause) && !defined(__INTEL_COMPILER) -# define BOOST_CORE_HAS_BUILTIN_IA32_PAUSE -# endif -#endif - -#if defined(BOOST_CORE_HAS_BUILTIN_IA32_PAUSE) - -# define BOOST_CORE_SP_PAUSE() __builtin_ia32_pause() - -#elif defined(_MSC_VER) && ( defined(_M_IX86) || defined(_M_X64) ) - -# include -# define BOOST_CORE_SP_PAUSE() _mm_pause() - -#elif defined(_MSC_VER) && ( defined(_M_ARM) || defined(_M_ARM64) ) - -# include -# define BOOST_CORE_SP_PAUSE() __yield() - -#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) - -# define BOOST_CORE_SP_PAUSE() __asm__ __volatile__( "rep; nop" : : : "memory" ) - -#elif defined(__GNUC__) && ( (defined(__ARM_ARCH) && __ARM_ARCH >= 8) || defined(__ARM_ARCH_8A__) || defined(__aarch64__) ) - -# define BOOST_CORE_SP_PAUSE() __asm__ __volatile__( "yield" : : : "memory" ) - -#else - -# define BOOST_CORE_SP_PAUSE() ((void)0) - -#endif - -namespace boost -{ -namespace core -{ - -BOOST_FORCEINLINE void sp_thread_pause() noexcept -{ - BOOST_CORE_SP_PAUSE(); -} - -} // namespace core -} // namespace boost - -#undef BOOST_CORE_SP_PAUSE - -#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED diff --git a/include/boost/core/detail/sp_thread_sleep.hpp b/include/boost/core/detail/sp_thread_sleep.hpp deleted file mode 100644 index 66f9eb2..0000000 --- a/include/boost/core/detail/sp_thread_sleep.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED -#define BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// boost/core/detail/sp_thread_sleep.hpp -// -// inline void bost::core::sp_thread_sleep(); -// -// Cease execution for a while to yield to other threads, -// as if by calling nanosleep() with an appropriate interval. -// -// Copyright 2008, 2020, 2023 Peter Dimov -// Distributed under the Boost Software License, Version 1.0 -// https://www.boost.org/LICENSE_1_0.txt - -#include - -#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - BOOST_PRAGMA_MESSAGE("Using Sleep(1) in sp_thread_sleep") -#endif - -#include - -namespace boost -{ -namespace core -{ -namespace detail -{ - -inline void sp_thread_sleep() noexcept -{ - Sleep( 1 ); -} - -} // namespace detail - -using boost::core::detail::sp_thread_sleep; - -} // namespace core -} // namespace boost - -#elif defined(BOOST_HAS_NANOSLEEP) - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - BOOST_PRAGMA_MESSAGE("Using nanosleep() in sp_thread_sleep") -#endif - -#include - -#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) -# include -#endif - -namespace boost -{ -namespace core -{ - -inline void sp_thread_sleep() noexcept -{ -#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) - - int oldst; - pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldst ); - -#endif - - // g++ -Wextra warns on {} or {0} - struct timespec rqtp = { 0, 0 }; - - // POSIX says that timespec has tv_sec and tv_nsec - // But it doesn't guarantee order or placement - - rqtp.tv_sec = 0; - rqtp.tv_nsec = 1000; - - nanosleep( &rqtp, 0 ); - -#if defined(BOOST_HAS_PTHREADS) && !defined(__ANDROID__) - - pthread_setcancelstate( oldst, &oldst ); - -#endif - -} - -} // namespace core -} // namespace boost - -#else - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - BOOST_PRAGMA_MESSAGE("Using sp_thread_yield() in sp_thread_sleep") -#endif - -#include - -namespace boost -{ -namespace core -{ - -inline void sp_thread_sleep() noexcept -{ - sp_thread_yield(); -} - -} // namespace core -} // namespace boost - -#endif - -#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED diff --git a/include/boost/core/detail/sp_thread_yield.hpp b/include/boost/core/detail/sp_thread_yield.hpp deleted file mode 100644 index 72c3066..0000000 --- a/include/boost/core/detail/sp_thread_yield.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED -#define BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// boost/core/detail/sp_thread_yield.hpp -// -// inline void bost::core::sp_thread_yield(); -// -// Gives up the remainder of the time slice, -// as if by calling sched_yield(). -// -// Copyright 2008, 2020 Peter Dimov -// Distributed under the Boost Software License, Version 1.0 -// https://www.boost.org/LICENSE_1_0.txt - -#include - -#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - BOOST_PRAGMA_MESSAGE("Using SwitchToThread() in sp_thread_yield") -#endif - -#include - -namespace boost -{ -namespace core -{ -namespace detail -{ - -inline void sp_thread_yield() noexcept -{ - SwitchToThread(); -} - -} // namespace detail - -using boost::core::detail::sp_thread_yield; - -} // namespace core -} // namespace boost - -#elif defined(BOOST_HAS_SCHED_YIELD) - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - BOOST_PRAGMA_MESSAGE("Using sched_yield() in sp_thread_yield") -#endif - -#ifndef _AIX -# include -#else - // AIX's sched.h defines ::var which sometimes conflicts with Lambda's var - extern "C" int sched_yield(void); -#endif - -namespace boost -{ -namespace core -{ - -inline void sp_thread_yield() noexcept -{ - sched_yield(); -} - -} // namespace core -} // namespace boost - -#else - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - BOOST_PRAGMA_MESSAGE("Using sp_thread_pause() in sp_thread_yield") -#endif - -#include - -namespace boost -{ -namespace core -{ - -inline void sp_thread_yield() noexcept -{ - sp_thread_pause(); -} - -} // namespace core -} // namespace boost - -#endif - -#endif // #ifndef BOOST_CORE_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED diff --git a/include/boost/core/detail/sp_win32_sleep.hpp b/include/boost/core/detail/sp_win32_sleep.hpp deleted file mode 100644 index adec53e..0000000 --- a/include/boost/core/detail/sp_win32_sleep.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED -#define BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// boost/core/detail/sp_win32_sleep.hpp -// -// Declares the Win32 Sleep() function. -// -// Copyright 2008, 2020 Peter Dimov -// Distributed under the Boost Software License, Version 1.0 -// https://www.boost.org/LICENSE_1_0.txt - -#if defined( BOOST_USE_WINDOWS_H ) -# include -#endif - -namespace boost -{ -namespace core -{ -namespace detail -{ - -#if !defined( BOOST_USE_WINDOWS_H ) - -#if defined(__clang__) && defined(__x86_64__) -// clang x64 warns that __stdcall is ignored -# define BOOST_CORE_SP_STDCALL -#else -# define BOOST_CORE_SP_STDCALL __stdcall -#endif - -#if defined(__LP64__) // Cygwin 64 - extern "C" __declspec(dllimport) void BOOST_CORE_SP_STDCALL Sleep( unsigned int ms ); -#else - extern "C" __declspec(dllimport) void BOOST_CORE_SP_STDCALL Sleep( unsigned long ms ); -#endif - -extern "C" __declspec(dllimport) int BOOST_CORE_SP_STDCALL SwitchToThread(); - -#undef BOOST_CORE_SP_STDCALL - -#endif // !defined( BOOST_USE_WINDOWS_H ) - -} // namespace detail -} // namespace core -} // namespace boost - -#endif // #ifndef BOOST_CORE_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED diff --git a/include/boost/core/yield_primitives.hpp b/include/boost/core/yield_primitives.hpp deleted file mode 100644 index 899453e..0000000 --- a/include/boost/core/yield_primitives.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED -#define BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED - -// Copyright 2023 Peter Dimov -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#include -#include -#include - -#endif // #ifndef BOOST_CORE_YIELD_PRIMITIVES_HPP_INCLUDED diff --git a/include/boost/unordered/detail/foa/core.hpp b/include/boost/unordered/detail/foa/core.hpp index ca6779b..cb3bb11 100644 --- a/include/boost/unordered/detail/foa/core.hpp +++ b/include/boost/unordered/detail/foa/core.hpp @@ -35,9 +35,6 @@ #include #include -#if defined(BOOST_UNORDERED_ENABLE_STATS) -#include -#endif #if !defined(BOOST_UNORDERED_DISABLE_SSE2) #if defined(BOOST_UNORDERED_ENABLE_SSE2)|| \ @@ -1130,44 +1127,6 @@ struct table_arrays value_type_pointer elements_; }; -#if defined(BOOST_UNORDERED_ENABLE_STATS) -/* stats support */ - -struct table_core_cumulative_stats -{ - concurrent_cumulative_stats<1> insertion; - concurrent_cumulative_stats<2> successful_lookup, - unsuccessful_lookup; -}; - -struct table_core_insertion_stats -{ - std::size_t count; - sequence_stats_summary probe_length; -}; - -struct table_core_lookup_stats -{ - std::size_t count; - sequence_stats_summary probe_length; - sequence_stats_summary num_comparisons; -}; - -struct table_core_stats -{ - table_core_insertion_stats insertion; - table_core_lookup_stats successful_lookup, - unsuccessful_lookup; -}; - -#define BOOST_UNORDERED_ADD_STATS(stats,args) stats.add args -#define BOOST_UNORDERED_SWAP_STATS(stats1,stats2) std::swap(stats1,stats2) -#define BOOST_UNORDERED_COPY_STATS(stats1,stats2) stats1=stats2 -#define BOOST_UNORDERED_RESET_STATS_OF(x) x.reset_stats() -#define BOOST_UNORDERED_STATS_COUNTER(name) std::size_t name=0 -#define BOOST_UNORDERED_INCREMENT_STATS_COUNTER(name) ++name - -#else #define BOOST_UNORDERED_ADD_STATS(stats,args) ((void)0) #define BOOST_UNORDERED_SWAP_STATS(stats1,stats2) ((void)0) @@ -1176,7 +1135,6 @@ struct table_core_stats #define BOOST_UNORDERED_STATS_COUNTER(name) ((void)0) #define BOOST_UNORDERED_INCREMENT_STATS_COUNTER(name) ((void)0) -#endif struct if_constexpr_void_else{void operator()()const{}}; @@ -1441,10 +1399,6 @@ table_core:empty_value,empty_value,empty_value using locator=table_locator; using arrays_holder_type=arrays_holder; -#if defined(BOOST_UNORDERED_ENABLE_STATS) - using cumulative_stats=table_core_cumulative_stats; - using stats=table_core_stats; -#endif #if defined(BOOST_GCC) #pragma GCC diagnostic push @@ -1820,37 +1774,6 @@ table_core:empty_value,empty_value,empty_value rehash(std::size_t(std::ceil(float(n)/mlf))); } -#if defined(BOOST_UNORDERED_ENABLE_STATS) - stats get_stats()const - { - auto insertion=cstats.insertion.get_summary(); - auto successful_lookup=cstats.successful_lookup.get_summary(); - auto unsuccessful_lookup=cstats.unsuccessful_lookup.get_summary(); - return{ - { - insertion.count, - insertion.sequence_summary[0] - }, - { - successful_lookup.count, - successful_lookup.sequence_summary[0], - successful_lookup.sequence_summary[1] - }, - { - unsuccessful_lookup.count, - unsuccessful_lookup.sequence_summary[0], - unsuccessful_lookup.sequence_summary[1] - }, - }; - } - - void reset_stats()noexcept - { - cstats.insertion.reset(); - cstats.successful_lookup.reset(); - cstats.unsuccessful_lookup.reset(); - } -#endif friend bool operator==(const table_core& x,const table_core& y) { @@ -2062,9 +1985,6 @@ table_core:empty_value,empty_value,empty_value arrays_type arrays; size_ctrl_type size_ctrl; -#if defined(BOOST_UNORDERED_ENABLE_STATS) - mutable cumulative_stats cstats; -#endif private: template< diff --git a/include/boost/unordered/detail/foa/cumulative_stats.hpp b/include/boost/unordered/detail/foa/cumulative_stats.hpp deleted file mode 100644 index 78678be..0000000 --- a/include/boost/unordered/detail/foa/cumulative_stats.hpp +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright 2024 Joaquin M Lopez Munoz. - * 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) - * - * See https://www.boost.org/libs/unordered for library home page. - */ - -#ifndef BOOST_UNORDERED_DETAIL_FOA_CUMULATIVE_STATS_HPP -#define BOOST_UNORDERED_DETAIL_FOA_CUMULATIVE_STATS_HPP - -#include -#include -#include -#include - -#if defined(BOOST_HAS_THREADS) -#include -#include -#endif - -namespace boost{ -namespace unordered{ -namespace detail{ -namespace foa{ - -/* Cumulative one-pass calculation of the average, variance and deviation of - * running sequences. - */ - -struct sequence_stats_data -{ - double m=0.0; - double m_prior=0.0; - double s=0.0; -}; - -struct welfords_algorithm /* 0-based */ -{ - template - int operator()(T&& x,sequence_stats_data& d)const noexcept - { - static_assert( - noexcept(static_cast(x)), - "Argument conversion to double must not throw."); - - d.m_prior=d.m; - d.m+=(static_cast(x)-d.m)/static_cast(n); - d.s+=(n!=1)* - (static_cast(x)-d.m_prior)*(static_cast(x)-d.m); - - return 0; /* mp11::tuple_transform requires that return type not be void */ - } - - std::size_t n; -}; - -struct sequence_stats_summary -{ - double average; - double variance; - double deviation; -}; - -/* Stats calculated jointly for N same-sized sequences to save the space - * for count. - */ - -template -class cumulative_stats -{ -public: - struct summary - { - std::size_t count; - std::array sequence_summary; - }; - - void reset()noexcept{*this=cumulative_stats();} - - template - void add(Ts&&... xs)noexcept - { - static_assert( - sizeof...(Ts)==N,"A sample must be provided for each sequence."); - - if(BOOST_UNLIKELY(++n==0)){ /* wraparound */ - reset(); - n=1; - } - mp11::tuple_transform( - welfords_algorithm{n}, - std::forward_as_tuple(std::forward(xs)...), - data); - } - - summary get_summary()const noexcept - { - summary res; - res.count=n; - for(std::size_t i=0;i(n):0.0, /* biased */ - deviation=std::sqrt(variance); - res.sequence_summary[i]={average,variance,deviation}; - } - return res; - } - -private: - std::size_t n=0; - std::array data; -}; - -#if defined(BOOST_HAS_THREADS) - -template -class concurrent_cumulative_stats:cumulative_stats -{ - using super=cumulative_stats; - using lock_guard=std::lock_guard; - -public: - using summary=typename super::summary; - - concurrent_cumulative_stats()noexcept:super{}{} - concurrent_cumulative_stats(const concurrent_cumulative_stats& x)noexcept: - concurrent_cumulative_stats{x,lock_guard{x.mut}}{} - - concurrent_cumulative_stats& - operator=(const concurrent_cumulative_stats& x)noexcept - { - auto x1=x; - lock_guard lck{mut}; - static_cast(*this)=x1; - return *this; - } - - void reset()noexcept - { - lock_guard lck{mut}; - super::reset(); - } - - template - void add(Ts&&... xs)noexcept - { - lock_guard lck{mut}; - super::add(std::forward(xs)...); - } - - summary get_summary()const noexcept - { - lock_guard lck{mut}; - return super::get_summary(); - } - -private: - concurrent_cumulative_stats(const super& x,lock_guard&&):super{x}{} - - mutable rw_spinlock mut; -}; - -#else - -template -using concurrent_cumulative_stats=cumulative_stats; - -#endif - -} /* namespace foa */ -} /* namespace detail */ -} /* namespace unordered */ -} /* namespace boost */ - -#endif diff --git a/include/boost/unordered/detail/foa/rw_spinlock.hpp b/include/boost/unordered/detail/foa/rw_spinlock.hpp deleted file mode 100644 index 8437fd3..0000000 --- a/include/boost/unordered/detail/foa/rw_spinlock.hpp +++ /dev/null @@ -1,179 +0,0 @@ -#ifndef BOOST_UNORDERED_DETAIL_FOA_RW_SPINLOCK_HPP_INCLUDED -#define BOOST_UNORDERED_DETAIL_FOA_RW_SPINLOCK_HPP_INCLUDED - -// Copyright 2023 Peter Dimov -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#include -#include -#include - -namespace boost{ -namespace unordered{ -namespace detail{ -namespace foa{ - -class rw_spinlock -{ -private: - - // bit 31: locked exclusive - // bit 30: writer pending - // bit 29..0: reader lock count - - static constexpr std::uint32_t locked_exclusive_mask = 1u << 31; // 0x8000'0000 - static constexpr std::uint32_t writer_pending_mask = 1u << 30; // 0x4000'0000 - static constexpr std::uint32_t reader_lock_count_mask = writer_pending_mask - 1; // 0x3FFF'FFFF - - std::atomic state_ = {}; - -private: - - // Effects: Provides a hint to the implementation that the current thread - // has been unable to make progress for k+1 iterations. - - static void yield( unsigned k ) noexcept - { - unsigned const sleep_every = 1024; // see below - - k %= sleep_every; - - if( k < 5 ) - { - // Intel recommendation from the Optimization Reference Manual - // Exponentially increase number of PAUSE instructions each - // iteration until reaching a maximum which is approximately - // one timeslice long (2^4 == 16 in our case) - - unsigned const pause_count = 1u << k; - - for( unsigned i = 0; i < pause_count; ++i ) - { - boost::core::sp_thread_pause(); - } - } - else if( k < sleep_every - 1 ) - { - // Once the maximum number of PAUSE instructions is reached, - // we switch to yielding the timeslice immediately - - boost::core::sp_thread_yield(); - } - else - { - // After `sleep_every` iterations of no progress, we sleep, - // to avoid a deadlock if a lower priority thread has the lock - - boost::core::sp_thread_sleep(); - } - } - -public: - - bool try_lock_shared() noexcept - { - std::uint32_t st = state_.load( std::memory_order_relaxed ); - - if( st >= reader_lock_count_mask ) - { - // either bit 31 set, bit 30 set, or reader count is max - return false; - } - - std::uint32_t newst = st + 1; - return state_.compare_exchange_strong( st, newst, std::memory_order_acquire, std::memory_order_relaxed ); - } - - void lock_shared() noexcept - { - for( unsigned k = 0; ; ++k ) - { - std::uint32_t st = state_.load( std::memory_order_relaxed ); - - if( st < reader_lock_count_mask ) - { - std::uint32_t newst = st + 1; - if( state_.compare_exchange_weak( st, newst, std::memory_order_acquire, std::memory_order_relaxed ) ) return; - } - - yield( k ); - } - } - - void unlock_shared() noexcept - { - // pre: locked shared, not locked exclusive - - state_.fetch_sub( 1, std::memory_order_release ); - - // if the writer pending bit is set, there's a writer waiting - // let it acquire the lock; it will clear the bit on unlock - } - - bool try_lock() noexcept - { - std::uint32_t st = state_.load( std::memory_order_relaxed ); - - if( st & locked_exclusive_mask ) - { - // locked exclusive - return false; - } - - if( st & reader_lock_count_mask ) - { - // locked shared - return false; - } - - std::uint32_t newst = locked_exclusive_mask; - return state_.compare_exchange_strong( st, newst, std::memory_order_acquire, std::memory_order_relaxed ); - } - - void lock() noexcept - { - for( unsigned k = 0; ; ++k ) - { - std::uint32_t st = state_.load( std::memory_order_relaxed ); - - if( st & locked_exclusive_mask ) - { - // locked exclusive, spin - } - else if( ( st & reader_lock_count_mask ) == 0 ) - { - // not locked exclusive, not locked shared, try to lock - - std::uint32_t newst = locked_exclusive_mask; - if( state_.compare_exchange_weak( st, newst, std::memory_order_acquire, std::memory_order_relaxed ) ) return; - } - else if( st & writer_pending_mask ) - { - // writer pending bit already set, nothing to do - } - else - { - // locked shared, set writer pending bit - - std::uint32_t newst = st | writer_pending_mask; - state_.compare_exchange_weak( st, newst, std::memory_order_relaxed, std::memory_order_relaxed ); - } - - yield( k ); - } - } - - void unlock() noexcept - { - // pre: locked exclusive, not locked shared - state_.store( 0, std::memory_order_release ); - } -}; - -} /* namespace foa */ -} /* namespace detail */ -} /* namespace unordered */ -} /* namespace boost */ - -#endif // BOOST_UNORDERED_DETAIL_FOA_RW_SPINLOCK_HPP_INCLUDED diff --git a/include/boost/unordered/detail/foa/table.hpp b/include/boost/unordered/detail/foa/table.hpp index 1ccaf91..5976fc8 100644 --- a/include/boost/unordered/detail/foa/table.hpp +++ b/include/boost/unordered/detail/foa/table.hpp @@ -352,9 +352,6 @@ class table:table_core_impl const_iterator>::type; using erase_return_type=table_erase_return_type; -#if defined(BOOST_UNORDERED_ENABLE_STATS) - using stats=typename super::stats; -#endif table( std::size_t n=default_bucket_count,const Hash& h_=Hash(), @@ -537,10 +534,6 @@ class table:table_core_impl using super::rehash; using super::reserve; -#if defined(BOOST_UNORDERED_ENABLE_STATS) - using super::get_stats; - using super::reset_stats; -#endif template friend std::size_t erase_if(table& x,Predicate& pr) diff --git a/include/boost/unordered/unordered_flat_map.hpp b/include/boost/unordered/unordered_flat_map.hpp index 71ec734..e9a20a6 100644 --- a/include/boost/unordered/unordered_flat_map.hpp +++ b/include/boost/unordered/unordered_flat_map.hpp @@ -73,9 +73,6 @@ namespace boost { using iterator = typename table_type::iterator; using const_iterator = typename table_type::const_iterator; -#if defined(BOOST_UNORDERED_ENABLE_STATS) - using stats = typename table_type::stats; -#endif unordered_flat_map() : unordered_flat_map(0) {} @@ -663,13 +660,6 @@ namespace boost { void reserve(size_type n) { table_.reserve(n); } -#if defined(BOOST_UNORDERED_ENABLE_STATS) - /// Stats - /// - stats get_stats() const { return table_.get_stats(); } - - void reset_stats() noexcept { table_.reset_stats(); } -#endif /// Observers /// diff --git a/include/boost/unordered/unordered_flat_set.hpp b/include/boost/unordered/unordered_flat_set.hpp index 8cabd28..838b4a5 100644 --- a/include/boost/unordered/unordered_flat_set.hpp +++ b/include/boost/unordered/unordered_flat_set.hpp @@ -69,9 +69,6 @@ namespace boost { using iterator = typename table_type::iterator; using const_iterator = typename table_type::const_iterator; -#if defined(BOOST_UNORDERED_ENABLE_STATS) - using stats = typename table_type::stats; -#endif unordered_flat_set() : unordered_flat_set(0) {} @@ -483,13 +480,6 @@ namespace boost { void reserve(size_type n) { table_.reserve(n); } -#if defined(BOOST_UNORDERED_ENABLE_STATS) - /// Stats - /// - stats get_stats() const { return table_.get_stats(); } - - void reset_stats() noexcept { table_.reset_stats(); } -#endif /// Observers /// diff --git a/include/boost/unordered/unordered_node_map.hpp b/include/boost/unordered/unordered_node_map.hpp index 701d1b7..95e973a 100644 --- a/include/boost/unordered/unordered_node_map.hpp +++ b/include/boost/unordered/unordered_node_map.hpp @@ -80,9 +80,6 @@ namespace boost { using insert_return_type = detail::foa::insert_return_type; -#if defined(BOOST_UNORDERED_ENABLE_STATS) - using stats = typename table_type::stats; -#endif unordered_node_map() : unordered_node_map(0) {} @@ -737,13 +734,6 @@ namespace boost { void reserve(size_type n) { table_.reserve(n); } -#if defined(BOOST_UNORDERED_ENABLE_STATS) - /// Stats - /// - stats get_stats() const { return table_.get_stats(); } - - void reset_stats() noexcept { table_.reset_stats(); } -#endif /// Observers /// diff --git a/include/boost/unordered/unordered_node_set.hpp b/include/boost/unordered/unordered_node_set.hpp index 8cc23e4..e28fadf 100644 --- a/include/boost/unordered/unordered_node_set.hpp +++ b/include/boost/unordered/unordered_node_set.hpp @@ -78,9 +78,6 @@ namespace boost { using insert_return_type = detail::foa::insert_return_type; -#if defined(BOOST_UNORDERED_ENABLE_STATS) - using stats = typename table_type::stats; -#endif unordered_node_set() : unordered_node_set(0) {} @@ -559,13 +556,6 @@ namespace boost { void reserve(size_type n) { table_.reserve(n); } -#if defined(BOOST_UNORDERED_ENABLE_STATS) - /// Stats - /// - stats get_stats() const { return table_.get_stats(); } - - void reset_stats() noexcept { table_.reset_stats(); } -#endif /// Observers /// diff --git a/make_unordered.sh b/make_unordered.sh index 05214a4..ea009c0 100755 --- a/make_unordered.sh +++ b/make_unordered.sh @@ -1,7 +1,7 @@ #wget https://boostorg.jfrog.io/artifactory/main/release/1.85.0/source/boost_1_87_0.tar.gz #tar -xvf boost_1_87_0.tar.gz mkdir temp_boost -bcp --boost=boost_1_87_0 boost/unordered/unordered_flat_map.hpp boost/unordered/unordered_flat_set.hpp boost/unordered/unordered_node_map.hpp boost/unordered/unordered_node_set.hpp temp_boost +bcp --boost=../boost_1_87_0 boost/unordered/unordered_flat_map.hpp boost/unordered/unordered_flat_set.hpp boost/unordered/unordered_node_map.hpp boost/unordered/unordered_node_set.hpp temp_boost cd temp_boost/boost rm version.hpp @@ -31,7 +31,7 @@ rm -rf mp11 cp ../../include/boost/minconfig.hpp . -coan source -R '-DBOOST_WORKAROUND(a,b)=0' -DBOOST_HAS_PRAGMA_ONCE -UBOOST_NO_CXX11_DEFAULTED_FUNCTIONS -UBOOST_NO_CXX11_RVALUE_REFERENCES -UBOOST_NO_CXX11_VARIADIC_TEMPLATES -UBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION . +coan source -R '-DBOOST_WORKAROUND(a,b)=0' -DBOOST_HAS_PRAGMA_ONCE -UBOOST_NO_CXX11_DEFAULTED_FUNCTIONS -UBOOST_NO_CXX11_RVALUE_REFERENCES -UBOOST_NO_CXX11_VARIADIC_TEMPLATES -UBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -UBOOST_UNORDERED_ENABLE_STATS . find . -name '*.hpp' -exec gsed -i 's///g' {} \; @@ -49,8 +49,6 @@ find . -name '*.hpp' -exec gsed -i '/serialize_tracked_address.hpp/d' {} \; find . -name '*.hpp' -exec gsed -i '/serialize_container.hpp/d' {} \; find . -name '*.hpp' -exec gsed -i '/friend class boost::serialization/d' {} \; find . -name '*.hpp' -exec gsed -i '/detail::serialize_container/d' {} \; -find . -name '*.hpp' -exec gsed -i '/boost\/mp11\/tuple.hpp/d' {} \; -find . -name '*.hpp' -exec gsed -i '/boost\/config\/pragma_message.hpp/d' {} \; find . -name '*.hpp' -exec gsed -i 's/BOOST_CONSTEXPR/constexpr/g' {} \; find . -name '*.hpp' -exec gsed -i 's/BOOST_CXX14_CONSTEXPR/constexpr/g' {} \;