From f8dcf5f6f4e20f3d39ee7574b95c10290ce955d6 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 6 Jun 2020 16:54:57 +0300 Subject: [PATCH 01/20] Use BOOST_SMT_PAUSE starting from the first iteration --- include/boost/smart_ptr/detail/yield_k.hpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index fa25917..82d1675 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -74,15 +74,12 @@ namespace detail inline void yield( unsigned k ) BOOST_NOEXCEPT { - if( k < 4 ) + if( k < 16 ) { - } #if defined( BOOST_SMT_PAUSE ) - else if( k < 16 ) - { BOOST_SMT_PAUSE - } #endif + } else if( k < 32 ) { Sleep( 0 ); @@ -102,8 +99,8 @@ inline void yield( unsigned k ) BOOST_NOEXCEPT #ifndef _AIX #include #else - // AIX's sched.h defines ::var which sometimes conflicts with Lambda's var - extern "C" int sched_yield(void); + // AIX's sched.h defines ::var which sometimes conflicts with Lambda's var + extern "C" int sched_yield(void); #endif #include @@ -116,15 +113,12 @@ namespace detail inline void yield( unsigned k ) { - if( k < 4 ) + if( k < 16 ) { - } #if defined( BOOST_SMT_PAUSE ) - else if( k < 16 ) - { BOOST_SMT_PAUSE - } #endif + } else if( k < 32 || k & 1 ) { sched_yield(); From d08bdc86e52a2c40342f36f9f78d24126cbf3086 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 6 Jun 2020 16:59:36 +0300 Subject: [PATCH 02/20] Remove unused files --- .../smart_ptr/detail/atomic_count_solaris.hpp | 66 ------- .../detail/sp_counted_base_cw_x86.hpp | 168 ------------------ .../detail/sp_counted_base_solaris.hpp | 123 ------------- 3 files changed, 357 deletions(-) delete mode 100644 include/boost/smart_ptr/detail/atomic_count_solaris.hpp delete mode 100644 include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp delete mode 100644 include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp diff --git a/include/boost/smart_ptr/detail/atomic_count_solaris.hpp b/include/boost/smart_ptr/detail/atomic_count_solaris.hpp deleted file mode 100644 index fb80d0a..0000000 --- a/include/boost/smart_ptr/detail/atomic_count_solaris.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED -#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED - -// -// boost/detail/atomic_count_solaris.hpp -// based on: boost/detail/atomic_count_win32.hpp -// -// Copyright (c) 2001-2005 Peter Dimov -// Copyright (c) 2006 Michael van der Westhuizen -// -// 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) -// - -#include - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - -#include -BOOST_PRAGMA_MESSAGE("Using Solaris atomic_count") - -#endif - -namespace boost -{ - -namespace detail -{ - -class atomic_count -{ -public: - - explicit atomic_count( uint32_t v ): value_( v ) - { - } - - long operator++() - { - return atomic_inc_32_nv( &value_ ); - } - - long operator--() - { - return atomic_dec_32_nv( &value_ ); - } - - operator uint32_t() const - { - return static_cast( value_ ); - } - -private: - - atomic_count( atomic_count const & ); - atomic_count & operator=( atomic_count const & ); - - uint32_t value_; -}; - -} // namespace detail - -} // namespace boost - -#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp deleted file mode 100644 index 297f055..0000000 --- a/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED -#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// -// detail/sp_counted_base_cw_x86.hpp - CodeWarrion on 486+ -// -// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. -// Copyright 2004-2005 Peter Dimov -// Copyright 2005 Rene Rivera -// -// 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) -// -// -// Lock-free algorithm by Alexander Terekhov -// -// Thanks to Ben Hitchings for the #weak + (#shared != 0) -// formulation -// - -#include -#include - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - -#include -BOOST_PRAGMA_MESSAGE("Using CodeWarrior/x86 sp_counted_base") - -#endif - -namespace boost -{ - -namespace detail -{ - -inline int atomic_exchange_and_add( int * pw, int dv ) -{ - // int r = *pw; - // *pw += dv; - // return r; - - asm - { - mov esi, [pw] - mov eax, dv - lock xadd dword ptr [esi], eax - } -} - -inline void atomic_increment( int * pw ) -{ - //atomic_exchange_and_add( pw, 1 ); - - asm - { - mov esi, [pw] - lock inc dword ptr [esi] - } -} - -inline int atomic_conditional_increment( int * pw ) -{ - // int rv = *pw; - // if( rv != 0 ) ++*pw; - // return rv; - - asm - { - mov esi, [pw] - mov eax, dword ptr [esi] - L0: - test eax, eax - je L1 - mov ebx, eax - inc ebx - lock cmpxchg dword ptr [esi], ebx - jne L0 - L1: - } -} - -class BOOST_SYMBOL_VISIBLE sp_counted_base -{ -private: - - sp_counted_base( sp_counted_base const & ); - sp_counted_base & operator= ( sp_counted_base const & ); - - int use_count_; // #shared - int weak_count_; // #weak + (#shared != 0) - -public: - - sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) - { - } - - virtual ~sp_counted_base() // nothrow - { - } - - // dispose() is called when use_count_ drops to zero, to release - // the resources managed by *this. - - virtual void dispose() = 0; // nothrow - - // destroy() is called when weak_count_ drops to zero. - - virtual void destroy() // nothrow - { - delete this; - } - - virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; - virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; - virtual void * get_untyped_deleter() = 0; - - void add_ref_copy() - { - atomic_increment( &use_count_ ); - } - - bool add_ref_lock() // true on success - { - return atomic_conditional_increment( &use_count_ ) != 0; - } - - void release() // nothrow - { - if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) - { - dispose(); - weak_release(); - } - } - - void weak_add_ref() // nothrow - { - atomic_increment( &weak_count_ ); - } - - void weak_release() // nothrow - { - if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 ) - { - destroy(); - } - } - - long use_count() const // nothrow - { - return static_cast( use_count_ ); - } -}; - -} // namespace detail - -} // namespace boost - -#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp b/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp deleted file mode 100644 index 4ad6b5e..0000000 --- a/include/boost/smart_ptr/detail/sp_counted_base_solaris.hpp +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED -#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED - -// -// detail/sp_counted_base_solaris.hpp -// based on: detail/sp_counted_base_w32.hpp -// -// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. -// Copyright 2004-2005 Peter Dimov -// Copyright 2006 Michael van der Westhuizen -// -// 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) -// -// -// Lock-free algorithm by Alexander Terekhov -// -// Thanks to Ben Hitchings for the #weak + (#shared != 0) -// formulation -// - -#include -#include -#include - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - -#include -BOOST_PRAGMA_MESSAGE("Using Solaris sp_counted_base") - -#endif - -namespace boost -{ - -namespace detail -{ - -class BOOST_SYMBOL_VISIBLE sp_counted_base -{ -private: - - sp_counted_base( sp_counted_base const & ); - sp_counted_base & operator= ( sp_counted_base const & ); - - uint32_t use_count_; // #shared - uint32_t weak_count_; // #weak + (#shared != 0) - -public: - - sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) - { - } - - virtual ~sp_counted_base() // nothrow - { - } - - // dispose() is called when use_count_ drops to zero, to release - // the resources managed by *this. - - virtual void dispose() = 0; // nothrow - - // destroy() is called when weak_count_ drops to zero. - - virtual void destroy() // nothrow - { - delete this; - } - - virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; - virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; - virtual void * get_untyped_deleter() = 0; - - void add_ref_copy() - { - atomic_inc_32( &use_count_ ); - } - - bool add_ref_lock() // true on success - { - for( ;; ) - { - uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ ); - if( tmp == 0 ) return false; - if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true; - } - } - - void release() // nothrow - { - if( atomic_dec_32_nv( &use_count_ ) == 0 ) - { - dispose(); - weak_release(); - } - } - - void weak_add_ref() // nothrow - { - atomic_inc_32( &weak_count_ ); - } - - void weak_release() // nothrow - { - if( atomic_dec_32_nv( &weak_count_ ) == 0 ) - { - destroy(); - } - } - - long use_count() const // nothrow - { - return static_cast( use_count_ ); - } -}; - -} // namespace detail - -} // namespace boost - -#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED From 108a86cdbdd991354716f7a892ed6b2bb5312156 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 6 Jun 2020 17:11:28 +0300 Subject: [PATCH 03/20] Rename sp_has_sync.hpp to sp_has_sync_intrinsics.hpp --- .../boost/smart_ptr/detail/atomic_count.hpp | 4 +-- .../smart_ptr/detail/sp_counted_base.hpp | 4 +-- ...as_sync.hpp => sp_has_sync_intrinsics.hpp} | 30 +++++++++---------- include/boost/smart_ptr/detail/spinlock.hpp | 4 +-- 4 files changed, 21 insertions(+), 21 deletions(-) rename include/boost/smart_ptr/detail/{sp_has_sync.hpp => sp_has_sync_intrinsics.hpp} (58%) diff --git a/include/boost/smart_ptr/detail/atomic_count.hpp b/include/boost/smart_ptr/detail/atomic_count.hpp index 6e4f71a..e0cbe26 100644 --- a/include/boost/smart_ptr/detail/atomic_count.hpp +++ b/include/boost/smart_ptr/detail/atomic_count.hpp @@ -44,7 +44,7 @@ // #include -#include +#include #if defined( BOOST_AC_DISABLE_THREADS ) # include @@ -79,7 +79,7 @@ #elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ ) # include -#elif defined( BOOST_SP_HAS_SYNC ) +#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS ) # include #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp index 4386137..f9a5c14 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp @@ -18,7 +18,7 @@ // #include -#include +#include #if !defined( __c2__ ) && defined( __clang__ ) && defined( __has_extension ) # if __has_extension( __c_atomic__ ) @@ -71,7 +71,7 @@ #elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__) && !defined( __mips16 ) # include -#elif defined( BOOST_SP_HAS_SYNC ) +#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS ) # include #elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) ) diff --git a/include/boost/smart_ptr/detail/sp_has_sync.hpp b/include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp similarity index 58% rename from include/boost/smart_ptr/detail/sp_has_sync.hpp rename to include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp index e1debf0..92684be 100644 --- a/include/boost/smart_ptr/detail/sp_has_sync.hpp +++ b/include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp @@ -8,7 +8,7 @@ #endif // -// boost/smart_ptr/detail/sp_has_sync.hpp +// boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp // // Copyright (c) 2008, 2009 Peter Dimov // @@ -16,50 +16,50 @@ // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics +// Defines the BOOST_SP_HAS_SYNC_INTRINSICS macro if the __sync_* intrinsics // are available. // -#ifndef BOOST_SP_NO_SYNC +#if !defined( BOOST_SP_NO_SYNC_INTRINSICS ) && !defined( BOOST_SP_NO_SYNC ) -#if !defined( __c2__ ) && defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) +#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) && !defined( __c2__ ) -# define BOOST_SP_HAS_SYNC +# define BOOST_SP_HAS_SYNC_INTRINSICS #elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) && !defined( __COMPILER_VER__ ) -# define BOOST_SP_HAS_SYNC +# define BOOST_SP_HAS_SYNC_INTRINSICS -#elif !defined( __c2__ ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) +#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __c2__ ) -#define BOOST_SP_HAS_SYNC +#define BOOST_SP_HAS_SYNC_INTRINSICS #if defined( __arm__ ) || defined( __armel__ ) -#undef BOOST_SP_HAS_SYNC +#undef BOOST_SP_HAS_SYNC_INTRINSICS #endif #if defined( __hppa ) || defined( __hppa__ ) -#undef BOOST_SP_HAS_SYNC +#undef BOOST_SP_HAS_SYNC_INTRINSICS #endif #if defined( __m68k__ ) -#undef BOOST_SP_HAS_SYNC +#undef BOOST_SP_HAS_SYNC_INTRINSICS #endif #if defined( __sh__ ) -#undef BOOST_SP_HAS_SYNC +#undef BOOST_SP_HAS_SYNC_INTRINSICS #endif #if defined( __sparc__ ) -#undef BOOST_SP_HAS_SYNC +#undef BOOST_SP_HAS_SYNC_INTRINSICS #endif #if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 ) -#undef BOOST_SP_HAS_SYNC +#undef BOOST_SP_HAS_SYNC_INTRINSICS #endif #if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9)) -#undef BOOST_SP_HAS_SYNC +#undef BOOST_SP_HAS_SYNC_INTRINSICS #endif #endif diff --git a/include/boost/smart_ptr/detail/spinlock.hpp b/include/boost/smart_ptr/detail/spinlock.hpp index 0b618df..1466dd1 100644 --- a/include/boost/smart_ptr/detail/spinlock.hpp +++ b/include/boost/smart_ptr/detail/spinlock.hpp @@ -29,7 +29,7 @@ // #include -#include +#include #if defined( BOOST_SP_USE_STD_ATOMIC ) # if !defined( __clang__ ) @@ -49,7 +49,7 @@ #elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ ) # include -#elif defined( BOOST_SP_HAS_SYNC ) +#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS ) # include #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) From a0d08b17e0292df4060ba6e943f6689abec8244e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 6 Jun 2020 17:13:56 +0300 Subject: [PATCH 04/20] Fix include guards --- include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp b/include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp index 92684be..875d869 100644 --- a/include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp +++ b/include/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp @@ -1,5 +1,5 @@ -#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED -#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED +#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED // MS compatible compilers support #pragma once @@ -64,6 +64,6 @@ #endif -#endif // #ifndef BOOST_SP_NO_SYNC +#endif // #if !defined( BOOST_SP_NO_SYNC_INTRINSICS ) && !defined( BOOST_SP_NO_SYNC ) -#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED From 7e9d8c39a3bb2ca7c0b482cdb689f731de4cd2b9 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 6 Jun 2020 20:43:08 +0300 Subject: [PATCH 05/20] Add sp_has_gcc_intrinsics.hpp, sp_counted_base_gcc_atomic.hpp --- .../smart_ptr/detail/sp_counted_base.hpp | 28 ++-- .../detail/sp_counted_base_gcc_atomic.hpp | 148 ++++++++++++++++++ .../detail/sp_has_gcc_intrinsics.hpp | 27 ++++ 3 files changed, 187 insertions(+), 16 deletions(-) create mode 100644 include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp create mode 100644 include/boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp diff --git a/include/boost/smart_ptr/detail/sp_counted_base.hpp b/include/boost/smart_ptr/detail/sp_counted_base.hpp index f9a5c14..536926a 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base.hpp @@ -17,14 +17,9 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include +#include #include - -#if !defined( __c2__ ) && defined( __clang__ ) && defined( __has_extension ) -# if __has_extension( __c_atomic__ ) -# define BOOST_SP_HAS_CLANG_C11_ATOMICS -# endif -#endif +#include #if defined( BOOST_SP_DISABLE_THREADS ) # include @@ -41,18 +36,24 @@ #elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 ) # include -#elif defined( BOOST_SP_HAS_CLANG_C11_ATOMICS ) -# include +#elif defined( BOOST_SP_HAS_GCC_INTRINSICS ) +# include #elif !defined( BOOST_NO_CXX11_HDR_ATOMIC ) # include -#elif defined( __SNC__ ) -# include +#elif defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) +# include #elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__) # include +#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS ) +# include + +#elif defined( __SNC__ ) +# include + #elif defined(__HP_aCC) && defined(__ia64) # include @@ -71,9 +72,6 @@ #elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__) && !defined( __mips16 ) # include -#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS ) -# include - #elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) ) # include @@ -91,6 +89,4 @@ #endif -#undef BOOST_SP_HAS_CLANG_C11_ATOMICS - #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp new file mode 100644 index 0000000..c2172e9 --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp @@ -0,0 +1,148 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_gc_atomic.hpp - g++ 4.7+ __atomic intrinsics +// +// Copyright 2007, 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + +#include +BOOST_PRAGMA_MESSAGE("Using __atomic sp_counted_base") + +#endif + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( boost::uint_least32_t * pw ) +{ + __atomic_fetch_add( pw, 1, __ATOMIC_RELAXED ); +} + +inline boost::uint_least32_t atomic_decrement( boost::uint_least32_t * pw ) +{ + return __atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL ); +} + +inline boost::uint_least32_t atomic_conditional_increment( boost::uint_least32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + boost::uint_least32_t r = __atomic_load_n( pw, __ATOMIC_RELAXED ); + + for( ;; ) + { + if( r == 0 ) + { + return r; + } + + if( __atomic_compare_exchange_n( pw, &r, r + 1, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) ) + { + return r; + } + } +} + +inline boost::uint_least32_t atomic_load( boost::uint_least32_t const * pw ) +{ + return __atomic_load_n( pw, __ATOMIC_ACQUIRE ); +} + +class BOOST_SYMBOL_VISIBLE sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + boost::uint_least32_t use_count_; // #shared + boost::uint_least32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0; + virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0; + virtual void * get_untyped_deleter() = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return atomic_load( &use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp b/include/boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp new file mode 100644 index 0000000..2e15f79 --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp @@ -0,0 +1,27 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + + +// boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp +// +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// Defines the BOOST_SP_HAS_GCC_INTRINSICS macro if the __atomic_* +// intrinsics are available. + + +#if defined( __ATOMIC_RELAXED ) && defined( __ATOMIC_ACQUIRE ) && defined( __ATOMIC_RELEASE ) && defined( __ATOMIC_ACQ_REL ) + +# define BOOST_SP_HAS_GCC_INTRINSICS + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED From c66c4f5ed180dee28f913052bf22948ec0fdb83d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2020 02:04:42 +0300 Subject: [PATCH 06/20] Mark platform-specific implementations as obsolete --- .../detail/sp_counted_base_acc_ia64.hpp | 3 ++ .../detail/sp_counted_base_cw_ppc.hpp | 3 ++ .../detail/sp_counted_base_gcc_ia64.hpp | 3 ++ .../detail/sp_counted_base_gcc_mips.hpp | 3 ++ .../detail/sp_counted_base_gcc_ppc.hpp | 3 ++ .../detail/sp_counted_base_gcc_sparc.hpp | 3 ++ .../detail/sp_counted_base_gcc_x86.hpp | 3 ++ .../detail/sp_counted_base_snc_ps3.hpp | 3 ++ .../detail/sp_counted_base_vacpp_ppc.hpp | 3 ++ .../boost/smart_ptr/detail/sp_obsolete.hpp | 32 +++++++++++++++++++ 10 files changed, 59 insertions(+) create mode 100644 include/boost/smart_ptr/detail/sp_obsolete.hpp diff --git a/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp index b31997d..8482515 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp @@ -16,6 +16,7 @@ // #include +#include #include #include @@ -26,6 +27,8 @@ BOOST_PRAGMA_MESSAGE("Using HP aCC++/HP-UX/IA64 sp_counted_base") #endif +BOOST_SP_OBSOLETE() + namespace boost { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp index f9df68a..81387ce 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp @@ -25,6 +25,7 @@ // #include +#include #include #if defined(BOOST_SP_REPORT_IMPLEMENTATION) @@ -34,6 +35,8 @@ BOOST_PRAGMA_MESSAGE("Using CodeWarrior/PowerPC sp_counted_base") #endif +BOOST_SP_OBSOLETE() + namespace boost { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp index 0c8d172..a6492ec 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp @@ -17,6 +17,7 @@ // #include +#include #include #if defined(BOOST_SP_REPORT_IMPLEMENTATION) @@ -26,6 +27,8 @@ BOOST_PRAGMA_MESSAGE("Using g++/IA64 sp_counted_base") #endif +BOOST_SP_OBSOLETE() + namespace boost { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp index 5cc5de9..3d3c7d3 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -21,6 +21,7 @@ // #include +#include #include #if defined(BOOST_SP_REPORT_IMPLEMENTATION) @@ -30,6 +31,8 @@ BOOST_PRAGMA_MESSAGE("Using g++/MIPS sp_counted_base") #endif +BOOST_SP_OBSOLETE() + namespace boost { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp index c5f84f5..12c8774 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp @@ -25,6 +25,7 @@ // #include +#include #include #if defined(BOOST_SP_REPORT_IMPLEMENTATION) @@ -34,6 +35,8 @@ BOOST_PRAGMA_MESSAGE("Using g++/PowerPC sp_counted_base") #endif +BOOST_SP_OBSOLETE() + namespace boost { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp index 8062487..a30e2a7 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @@ -20,6 +20,7 @@ // Thanks to Michael van der Westhuizen #include +#include #include #include // int32_t @@ -30,6 +31,8 @@ BOOST_PRAGMA_MESSAGE("Using g++/Sparc sp_counted_base") #endif +BOOST_SP_OBSOLETE() + namespace boost { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp index 1c55918..420265d 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp @@ -25,6 +25,7 @@ // #include +#include #include #if defined(BOOST_SP_REPORT_IMPLEMENTATION) @@ -34,6 +35,8 @@ BOOST_PRAGMA_MESSAGE("Using g++/x86 sp_counted_base") #endif +BOOST_SP_OBSOLETE() + namespace boost { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp index d60dd75..fc84ec1 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp @@ -20,6 +20,7 @@ // Thanks to Michael van der Westhuizen #include +#include #include #include // uint32_t @@ -30,6 +31,8 @@ BOOST_PRAGMA_MESSAGE("Using PS3 sp_counted_base") #endif +BOOST_SP_OBSOLETE() + namespace boost { diff --git a/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp index e08536d..d3e5442 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp @@ -22,6 +22,7 @@ // #include +#include #include #if defined(BOOST_SP_REPORT_IMPLEMENTATION) @@ -31,6 +32,8 @@ BOOST_PRAGMA_MESSAGE("Using xlC/PowerPC sp_counted_base") #endif +BOOST_SP_OBSOLETE() + extern "builtin" void __lwsync(void); extern "builtin" void __isync(void); extern "builtin" int __fetch_and_add(volatile int* addr, int val); diff --git a/include/boost/smart_ptr/detail/sp_obsolete.hpp b/include/boost/smart_ptr/detail/sp_obsolete.hpp new file mode 100644 index 0000000..021e72e --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_obsolete.hpp @@ -0,0 +1,32 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_OBSOLETE_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_OBSOLETE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + + +// boost/smart_ptr/detail/sp_obsolete.hpp +// +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// +// Defines the BOOST_SP_OBSOLETE macro that emits a deprecation +// message. + +#include + +#if !defined( BOOST_SP_NO_OBSOLETE_MESSAGE ) + +#define BOOST_SP_OBSOLETE() BOOST_PRAGMA_MESSAGE("This platform-specific implementation is presumed obsolete and is slated for removal. If you want it retained, please open an issue in https://github.com/boostorg/smart_ptr.") + +#else + +#define BOOST_SP_OBSOLETE() + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_OBSOLETE_HPP_INCLUDED From 15ffd7852b995efed7707e16c3d6c9e712714f59 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2020 02:05:55 +0300 Subject: [PATCH 07/20] Remove Clang C11 implementation; no longer used --- .../detail/sp_counted_base_clang.hpp | 168 ------------------ 1 file changed, 168 deletions(-) delete mode 100644 include/boost/smart_ptr/detail/sp_counted_base_clang.hpp diff --git a/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp b/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp deleted file mode 100644 index 3a2ab0e..0000000 --- a/include/boost/smart_ptr/detail/sp_counted_base_clang.hpp +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED -#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// detail/sp_counted_base_clang.hpp - __c11 clang intrinsics -// -// Copyright (c) 2007, 2013, 2015 Peter Dimov -// -// 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 - -#include -#include -#include -#include - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - -#include -BOOST_PRAGMA_MESSAGE("Using Clang/C11 sp_counted_base") - -#endif - -namespace boost -{ - -namespace detail -{ - -#if defined(__clang__) -# pragma clang diagnostic push -#endif - -#if defined(__clang__) && defined(__has_warning) -# if __has_warning( "-Wc11-extensions" ) -# pragma clang diagnostic ignored "-Wc11-extensions" -# endif -#endif - -typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t; - -inline void atomic_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT -{ - __c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED ); -} - -inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT -{ - return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL ); -} - -inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT -{ - // long r = *pw; - // if( r != 0 ) ++*pw; - // return r; - - boost::int_least32_t r = __c11_atomic_load( pw, __ATOMIC_RELAXED ); - - for( ;; ) - { - if( r == 0 ) - { - return r; - } - - if( __c11_atomic_compare_exchange_weak( pw, &r, r + 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) ) - { - return r; - } - } -} - -#if defined(__clang__) -# pragma clang diagnostic ignored "-Wweak-vtables" -#endif - -class BOOST_SYMBOL_VISIBLE sp_counted_base -{ -private: - - sp_counted_base( sp_counted_base const & ); - sp_counted_base & operator= ( sp_counted_base const & ); - - atomic_int_least32_t use_count_; // #shared - atomic_int_least32_t weak_count_; // #weak + (#shared != 0) - -public: - - sp_counted_base() BOOST_SP_NOEXCEPT - { - __c11_atomic_init( &use_count_, 1 ); - __c11_atomic_init( &weak_count_, 1 ); - } - - virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/ - { - } - - // dispose() is called when use_count_ drops to zero, to release - // the resources managed by *this. - - virtual void dispose() BOOST_SP_NOEXCEPT = 0; // nothrow - - // destroy() is called when weak_count_ drops to zero. - - virtual void destroy() BOOST_SP_NOEXCEPT // nothrow - { - delete this; - } - - virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0; - virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0; - virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0; - - void add_ref_copy() BOOST_SP_NOEXCEPT - { - atomic_increment( &use_count_ ); - } - - bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success - { - return atomic_conditional_increment( &use_count_ ) != 0; - } - - void release() BOOST_SP_NOEXCEPT - { - if( atomic_decrement( &use_count_ ) == 1 ) - { - dispose(); - weak_release(); - } - } - - void weak_add_ref() BOOST_SP_NOEXCEPT - { - atomic_increment( &weak_count_ ); - } - - void weak_release() BOOST_SP_NOEXCEPT - { - if( atomic_decrement( &weak_count_ ) == 1 ) - { - destroy(); - } - } - - long use_count() const BOOST_SP_NOEXCEPT - { - return __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE ); - } -}; - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif - -} // namespace detail - -} // namespace boost - -#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED From 914b93430afa5cee3dc5e8125dbbdcecea160f5d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2020 04:10:49 +0300 Subject: [PATCH 08/20] Change spinlock_sync.hpp to use a single byte --- include/boost/smart_ptr/detail/spinlock_sync.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/smart_ptr/detail/spinlock_sync.hpp b/include/boost/smart_ptr/detail/spinlock_sync.hpp index 854cc7e..cbfdd94 100644 --- a/include/boost/smart_ptr/detail/spinlock_sync.hpp +++ b/include/boost/smart_ptr/detail/spinlock_sync.hpp @@ -38,7 +38,7 @@ class spinlock { public: - int v_; + unsigned char v_; public: From 00db1e02c63c0320839f90653766972c0ef5431a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2020 05:00:03 +0300 Subject: [PATCH 09/20] Add spinlock_gcc_atomic.hpp --- include/boost/smart_ptr/detail/spinlock.hpp | 14 ++- .../smart_ptr/detail/spinlock_gcc_atomic.hpp | 90 +++++++++++++++++++ 2 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp diff --git a/include/boost/smart_ptr/detail/spinlock.hpp b/include/boost/smart_ptr/detail/spinlock.hpp index 1466dd1..26e1b08 100644 --- a/include/boost/smart_ptr/detail/spinlock.hpp +++ b/include/boost/smart_ptr/detail/spinlock.hpp @@ -28,21 +28,19 @@ // #define BOOST_DETAIL_SPINLOCK_INIT // -#include +#include #include +#include #if defined( BOOST_SP_USE_STD_ATOMIC ) -# if !defined( __clang__ ) -# include -# else -// Clang (at least up to 3.4) can't compile spinlock_pool when -// using std::atomic, so substitute the __sync implementation instead. -# include -# endif +# include #elif defined( BOOST_SP_USE_PTHREADS ) # include +#elif defined( BOOST_SP_HAS_GCC_INTRINSICS ) +# include + #elif !defined( BOOST_NO_CXX11_HDR_ATOMIC ) # include diff --git a/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp b/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp new file mode 100644 index 0000000..c899a59 --- /dev/null +++ b/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp @@ -0,0 +1,90 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2008 Peter Dimov +// +// 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) +// + +#include + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + +#include +BOOST_PRAGMA_MESSAGE("Using __atomic spinlock") + +#endif + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + unsigned char v_; + +public: + + bool try_lock() + { + int r = __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ); + return r == 0; + } + + void lock() + { + for( unsigned k = 0; !try_lock(); ++k ) + { + boost::detail::yield( k ); + } + } + + void unlock() + { + __atomic_clear( &v_, __ATOMIC_RELEASE ); + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT {0} + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ATOMIC_HPP_INCLUDED From 7c01e640f7b2a68579e3410cf65d48f2ba655eca Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2020 06:05:17 +0300 Subject: [PATCH 10/20] Use int_least32_t in atomic_count_sync; prefer it to atomic_count_gcc_x86; mark latter obsolete --- include/boost/smart_ptr/detail/atomic_count.hpp | 6 +++--- include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp | 4 ++++ include/boost/smart_ptr/detail/atomic_count_sync.hpp | 8 ++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/include/boost/smart_ptr/detail/atomic_count.hpp b/include/boost/smart_ptr/detail/atomic_count.hpp index e0cbe26..456b2db 100644 --- a/include/boost/smart_ptr/detail/atomic_count.hpp +++ b/include/boost/smart_ptr/detail/atomic_count.hpp @@ -76,12 +76,12 @@ #elif !defined( BOOST_NO_CXX11_HDR_ATOMIC ) # include -#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ ) -# include - #elif defined( BOOST_SP_HAS_SYNC_INTRINSICS ) # include +#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ ) +# include + #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) # include diff --git a/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp b/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp index 100c9cf..30a73e3 100644 --- a/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp +++ b/include/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp @@ -13,6 +13,8 @@ // http://www.boost.org/LICENSE_1_0.txt) // +#include + #if defined(BOOST_SP_REPORT_IMPLEMENTATION) #include @@ -20,6 +22,8 @@ BOOST_PRAGMA_MESSAGE("Using g++/x86 atomic_count") #endif +BOOST_SP_OBSOLETE() + namespace boost { diff --git a/include/boost/smart_ptr/detail/atomic_count_sync.hpp b/include/boost/smart_ptr/detail/atomic_count_sync.hpp index 81d7d65..c65d1e9 100644 --- a/include/boost/smart_ptr/detail/atomic_count_sync.hpp +++ b/include/boost/smart_ptr/detail/atomic_count_sync.hpp @@ -15,6 +15,8 @@ // http://www.boost.org/LICENSE_1_0.txt) // +#include + #if defined( __ia64__ ) && defined( __INTEL_COMPILER ) # include #endif @@ -36,7 +38,9 @@ class atomic_count { public: - explicit atomic_count( long v ) : value_( v ) {} + explicit atomic_count( long v ) : value_( static_cast< boost::int_least32_t >( v ) ) + { + } long operator++() { @@ -58,7 +62,7 @@ private: atomic_count(atomic_count const &); atomic_count & operator=(atomic_count const &); - mutable long value_; + mutable boost::int_least32_t value_; }; } // namespace detail From d0655ab145ab7d1c6049ceae13a7fd439ab2d893 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2020 06:29:14 +0300 Subject: [PATCH 11/20] Add atomic_count_gcc_atomic.hpp --- .../boost/smart_ptr/detail/atomic_count.hpp | 6 +- .../detail/atomic_count_gcc_atomic.hpp | 63 +++++++++++++++++++ .../smart_ptr/detail/atomic_count_sync.hpp | 2 +- 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 include/boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp diff --git a/include/boost/smart_ptr/detail/atomic_count.hpp b/include/boost/smart_ptr/detail/atomic_count.hpp index 456b2db..749b3f0 100644 --- a/include/boost/smart_ptr/detail/atomic_count.hpp +++ b/include/boost/smart_ptr/detail/atomic_count.hpp @@ -43,8 +43,9 @@ // Memory Ordering: acquire/release // -#include +#include #include +#include #if defined( BOOST_AC_DISABLE_THREADS ) # include @@ -73,6 +74,9 @@ #elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 ) # include +#elif defined( BOOST_SP_HAS_GCC_INTRINSICS ) +# include + #elif !defined( BOOST_NO_CXX11_HDR_ATOMIC ) # include diff --git a/include/boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp b/include/boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp new file mode 100644 index 0000000..801a7cb --- /dev/null +++ b/include/boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp @@ -0,0 +1,63 @@ +#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED + +// boost/detail/atomic_count_gcc_atomic.hpp +// +// atomic_count for g++ 4.7+ +// +// Copyright 2007, 2020 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + +#include +BOOST_PRAGMA_MESSAGE("Using __atomic atomic_count") + +#endif + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +public: + + explicit atomic_count( long v ): value_( static_cast< boost::int_least32_t >( v ) ) + { + } + + long operator++() + { + return __atomic_add_fetch( &value_, +1, __ATOMIC_ACQ_REL ); + } + + long operator--() + { + return __atomic_add_fetch( &value_, -1, __ATOMIC_ACQ_REL ); + } + + operator long() const + { + return __atomic_load_n( &value_, __ATOMIC_ACQUIRE ); + } + +private: + + atomic_count(atomic_count const &); + atomic_count & operator=(atomic_count const &); + + boost::int_least32_t value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_ATOMIC_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/atomic_count_sync.hpp b/include/boost/smart_ptr/detail/atomic_count_sync.hpp index c65d1e9..65b42c8 100644 --- a/include/boost/smart_ptr/detail/atomic_count_sync.hpp +++ b/include/boost/smart_ptr/detail/atomic_count_sync.hpp @@ -38,7 +38,7 @@ class atomic_count { public: - explicit atomic_count( long v ) : value_( static_cast< boost::int_least32_t >( v ) ) + explicit atomic_count( long v ): value_( static_cast< boost::int_least32_t >( v ) ) { } From 3db4ad9a15b1afaddb909e109c29e21bb91813fb Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2020 17:59:55 +0300 Subject: [PATCH 12/20] Use a relaxed load before test_and_set to not lock cache line on contention (AMD spinlock recommendation per ) --- .../boost/smart_ptr/detail/spinlock_gcc_atomic.hpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp b/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp index c899a59..f2c77f0 100644 --- a/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp +++ b/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp @@ -7,13 +7,9 @@ # pragma once #endif -// -// Copyright (c) 2008 Peter Dimov -// -// 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 2008, 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt #include @@ -40,8 +36,7 @@ public: bool try_lock() { - int r = __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ); - return r == 0; + return __atomic_load_n( &v_, __ATOMIC_RELAXED ) == 0 && __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ) == 0; } void lock() From 5d31c1c443da153c002104b03a3bc1177ca3ed56 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2020 20:40:41 +0300 Subject: [PATCH 13/20] Refactor yield_k.hpp --- include/boost/smart_ptr/detail/yield_k.hpp | 107 ++++++++++++++------- 1 file changed, 70 insertions(+), 37 deletions(-) diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index 82d1675..367e022 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -24,6 +24,7 @@ // #include +#include // BOOST_SMT_PAUSE @@ -37,6 +38,10 @@ extern "C" void _mm_pause(); #define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" ); +#else + +#define BOOST_SMT_PAUSE + #endif // @@ -72,22 +77,18 @@ namespace detail #endif // !defined( BOOST_USE_WINDOWS_H ) -inline void yield( unsigned k ) BOOST_NOEXCEPT -{ - if( k < 16 ) - { -#if defined( BOOST_SMT_PAUSE ) - BOOST_SMT_PAUSE +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using Win32 yield_k") #endif - } - else if( k < 32 ) - { - Sleep( 0 ); - } - else - { - Sleep( 1 ); - } + +inline void sp_thread_yield() +{ + Sleep( 0 ); +} + +inline void sp_thread_sleep() +{ + Sleep( 1 ); } } // namespace detail @@ -111,31 +112,27 @@ namespace boost namespace detail { -inline void yield( unsigned k ) -{ - if( k < 16 ) - { -#if defined( BOOST_SMT_PAUSE ) - BOOST_SMT_PAUSE +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using POSIX yield_k") #endif - } - else if( k < 32 || k & 1 ) - { - sched_yield(); - } - else - { - // 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 +inline void sp_thread_yield() +{ + sched_yield(); +} - rqtp.tv_sec = 0; - rqtp.tv_nsec = 1000; +inline void sp_thread_sleep() +{ + // g++ -Wextra warns on {} or {0} + struct timespec rqtp = { 0, 0 }; - nanosleep( &rqtp, 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 ); } } // namespace detail @@ -144,14 +141,24 @@ inline void yield( unsigned k ) #else +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using empty yield_k") +#endif + namespace boost { namespace detail { -inline void yield( unsigned ) +inline void sp_thread_yield() { + BOOST_SMT_PAUSE +} + +inline void sp_thread_sleep() +{ + BOOST_SMT_PAUSE } } // namespace detail @@ -160,4 +167,30 @@ inline void yield( unsigned ) #endif +namespace boost +{ + +namespace detail +{ + +inline void yield( unsigned k ) BOOST_NOEXCEPT +{ + if( k < 16 ) + { + BOOST_SMT_PAUSE + } + else if( k < 32 ) + { + sp_thread_yield(); + } + else + { + sp_thread_sleep(); + } +} + +} // namespace detail + +} // namespace boost + #endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED From 8afe162910d08a29712582f2b4f13a051a4d8599 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2020 21:07:35 +0300 Subject: [PATCH 14/20] Use a relaxed load before XCHG to not lock cache line on contention (AMD spinlock recommendation per ) --- include/boost/smart_ptr/detail/spinlock_w32.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/boost/smart_ptr/detail/spinlock_w32.hpp b/include/boost/smart_ptr/detail/spinlock_w32.hpp index 39092ce..ddaf4ff 100644 --- a/include/boost/smart_ptr/detail/spinlock_w32.hpp +++ b/include/boost/smart_ptr/detail/spinlock_w32.hpp @@ -66,6 +66,11 @@ public: bool try_lock() { + if( *const_cast< long const volatile* >( &v_ ) != 0 ) + { + return false; + } + long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 ); BOOST_COMPILER_FENCE From 72ca834ae8a86cef59035a05042988298715269c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 7 Jun 2020 21:24:21 +0300 Subject: [PATCH 15/20] Change yield_k to not use sp_thread_yield; using sp_thread_sleep is always strictly superior, at least on Windows --- include/boost/smart_ptr/detail/yield_k.hpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index 367e022..8f52a58 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -175,14 +175,17 @@ namespace detail inline void yield( unsigned k ) BOOST_NOEXCEPT { - if( k < 16 ) + // Experiments show that a simple sp_thread_sleep() here is best; + // leave a few pause instructions out of mostly superstition. + // (These are verified to not degrade performance.) + // + // There seems to be no benefit from calling sp_thread_yield() + // at any time. + + if( k < 8 ) { BOOST_SMT_PAUSE } - else if( k < 32 ) - { - sp_thread_yield(); - } else { sp_thread_sleep(); From d35cf29b995fd4bebb4a4890229fac2fd7431810 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 10 Jun 2020 18:18:35 +0300 Subject: [PATCH 16/20] Revert "Use a relaxed load before XCHG to not lock cache line on contention (AMD spinlock recommendation per )" This reverts commit 8afe162910d08a29712582f2b4f13a051a4d8599. --- include/boost/smart_ptr/detail/spinlock_w32.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/boost/smart_ptr/detail/spinlock_w32.hpp b/include/boost/smart_ptr/detail/spinlock_w32.hpp index ddaf4ff..39092ce 100644 --- a/include/boost/smart_ptr/detail/spinlock_w32.hpp +++ b/include/boost/smart_ptr/detail/spinlock_w32.hpp @@ -66,11 +66,6 @@ public: bool try_lock() { - if( *const_cast< long const volatile* >( &v_ ) != 0 ) - { - return false; - } - long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 ); BOOST_COMPILER_FENCE From 8d79ceaf8abb111fa87d6a8189d34e5807eb8c20 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 10 Jun 2020 18:20:33 +0300 Subject: [PATCH 17/20] Revert using a relaxed load before test_and_set; not necessary, and slower, with a proper yielding strategy as opposed to just pause-spinning --- include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp b/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp index f2c77f0..8cd7179 100644 --- a/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp +++ b/include/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp @@ -36,7 +36,7 @@ public: bool try_lock() { - return __atomic_load_n( &v_, __ATOMIC_RELAXED ) == 0 && __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ) == 0; + return __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ) == 0; } void lock() From 7c0dcd338aa64b586650361e0a43e39956d236aa Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 10 Jun 2020 18:58:08 +0300 Subject: [PATCH 18/20] Refactor yield_k.hpp --- .../smart_ptr/detail/sp_thread_pause.hpp | 51 +++++ .../smart_ptr/detail/sp_thread_sleep.hpp | 104 +++++++++++ .../smart_ptr/detail/sp_thread_yield.hpp | 100 ++++++++++ .../boost/smart_ptr/detail/sp_win32_sleep.hpp | 49 +++++ include/boost/smart_ptr/detail/yield_k.hpp | 176 ++---------------- 5 files changed, 318 insertions(+), 162 deletions(-) create mode 100644 include/boost/smart_ptr/detail/sp_thread_pause.hpp create mode 100644 include/boost/smart_ptr/detail/sp_thread_sleep.hpp create mode 100644 include/boost/smart_ptr/detail/sp_thread_yield.hpp create mode 100644 include/boost/smart_ptr/detail/sp_win32_sleep.hpp diff --git a/include/boost/smart_ptr/detail/sp_thread_pause.hpp b/include/boost/smart_ptr/detail/sp_thread_pause.hpp new file mode 100644 index 0000000..2cddd90 --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_thread_pause.hpp @@ -0,0 +1,51 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/smart_ptr/detail/sp_thread_pause.hpp +// +// inline void bost::detail::sp_thread_pause(); +// +// Emits a "pause" instruction. +// +// Copyright 2008, 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0 +// https://www.boost.org/LICENSE_1_0.txt + +#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) && !defined(__c2__) + +extern "C" void _mm_pause(); + +#define BOOST_SP_PAUSE _mm_pause(); + +#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) + +#define BOOST_SP_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" ); + +#else + +#define BOOST_SP_PAUSE + +#endif + +namespace boost +{ +namespace detail +{ + +inline void sp_thread_pause() +{ + BOOST_SP_PAUSE +} + +} // namespace detail +} // namespace boost + +#undef BOOST_SP_PAUSE + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_PAUSE_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/sp_thread_sleep.hpp b/include/boost/smart_ptr/detail/sp_thread_sleep.hpp new file mode 100644 index 0000000..ff1d168 --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_thread_sleep.hpp @@ -0,0 +1,104 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/smart_ptr/detail/sp_thread_sleep.hpp +// +// inline void bost::detail::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 Peter Dimov +// Distributed under the Boost Software License, Version 1.0 +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined( WIN32 ) || 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 detail +{ + +inline void sp_thread_sleep() +{ + Sleep( 1 ); +} + +} // namespace detail + +} // namespace boost + +#elif defined(BOOST_HAS_NANOSLEEP) + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using nanosleep() in sp_thread_sleep") +#endif + +#include + +namespace boost +{ + +namespace detail +{ + +inline void sp_thread_sleep() +{ + // 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 ); +} + +} // namespace detail + +} // 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 detail +{ + +inline void sp_thread_sleep() +{ + sp_thread_yield(); +} + +} // namespace detail + +} // namespace boost + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_SLEEP_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/sp_thread_yield.hpp b/include/boost/smart_ptr/detail/sp_thread_yield.hpp new file mode 100644 index 0000000..9a221cc --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_thread_yield.hpp @@ -0,0 +1,100 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/smart_ptr/detail/sp_thread_yield.hpp +// +// inline void bost::detail::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 +#include + +#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +#if defined(BOOST_SP_REPORT_IMPLEMENTATION) + BOOST_PRAGMA_MESSAGE("Using Sleep(0) in sp_thread_yield") +#endif + +#include + +namespace boost +{ + +namespace detail +{ + +inline void sp_thread_yield() +{ + Sleep( 0 ); +} + +} // namespace detail + +} // 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 detail +{ + +inline void sp_thread_yield() +{ + sched_yield(); +} + +} // namespace detail + +} // 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 detail +{ + +inline void sp_thread_yield() +{ + sp_thread_pause(); +} + +} // namespace detail + +} // namespace boost + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_THREAD_YIELD_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/sp_win32_sleep.hpp b/include/boost/smart_ptr/detail/sp_win32_sleep.hpp new file mode 100644 index 0000000..139a569 --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_win32_sleep.hpp @@ -0,0 +1,49 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/smart_ptr/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 detail +{ + +#if !defined( BOOST_USE_WINDOWS_H ) + +#if defined(__clang__) && defined(__x86_64__) +// clang x64 warns that __stdcall is ignored +# define BOOST_SP_STDCALL +#else +# define BOOST_SP_STDCALL __stdcall +#endif + +#if defined(__LP64__) // Cygwin 64 + extern "C" __declspec(dllimport) void BOOST_SP_STDCALL Sleep( unsigned int ms ); +#else + extern "C" __declspec(dllimport) void BOOST_SP_STDCALL Sleep( unsigned long ms ); +#endif + +#undef BOOST_SP_STDCALL + +#endif // !defined( BOOST_USE_WINDOWS_H ) + +} // namespace detail +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_WIN32_SLEEP_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/yield_k.hpp b/include/boost/smart_ptr/detail/yield_k.hpp index 8f52a58..d9a1b46 100644 --- a/include/boost/smart_ptr/detail/yield_k.hpp +++ b/include/boost/smart_ptr/detail/yield_k.hpp @@ -7,50 +7,21 @@ # pragma once #endif +// boost/smart_ptr/detail/yield_k.hpp // -// yield_k.hpp +// Copyright 2008, 2020 Peter Dimov // -// Copyright (c) 2008 Peter Dimov +// inline void boost::detail::yield( unsigned k ); // -// void yield( unsigned k ); -// -// Typical use: -// -// for( unsigned k = 0; !try_lock(); ++k ) yield( k ); -// -// 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 +// Typical use: +// for( unsigned k = 0; !try_lock(); ++k ) yield( k ); // +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +#include +#include #include -#include - -// BOOST_SMT_PAUSE - -#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) && !defined(__c2__) - -extern "C" void _mm_pause(); - -#define BOOST_SMT_PAUSE _mm_pause(); - -#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) - -#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" ); - -#else - -#define BOOST_SMT_PAUSE - -#endif - -// - -#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) - -#if defined( BOOST_USE_WINDOWS_H ) -# include -#endif namespace boost { @@ -58,133 +29,14 @@ namespace boost namespace detail { -#if !defined( BOOST_USE_WINDOWS_H ) - -#if defined(__clang__) && defined(__x86_64__) -// clang x64 warns that __stdcall is ignored -# define BOOST_SP_STDCALL -#else -# define BOOST_SP_STDCALL __stdcall -#endif - -#if defined(__LP64__) // Cygwin 64 - extern "C" __declspec(dllimport) void BOOST_SP_STDCALL Sleep( unsigned int ms ); -#else - extern "C" __declspec(dllimport) void BOOST_SP_STDCALL Sleep( unsigned long ms ); -#endif - -#undef BOOST_SP_STDCALL - -#endif // !defined( BOOST_USE_WINDOWS_H ) - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - BOOST_PRAGMA_MESSAGE("Using Win32 yield_k") -#endif - -inline void sp_thread_yield() +inline void yield( unsigned k ) { - Sleep( 0 ); -} + // Experiments on Windows and Fedora 32 show that a single pause, + // followed by an immediate sp_thread_sleep(), is best. -inline void sp_thread_sleep() -{ - Sleep( 1 ); -} - -} // namespace detail - -} // namespace boost - -#elif defined( BOOST_HAS_PTHREADS ) - -#ifndef _AIX -#include -#else - // AIX's sched.h defines ::var which sometimes conflicts with Lambda's var - extern "C" int sched_yield(void); -#endif - -#include - -namespace boost -{ - -namespace detail -{ - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - BOOST_PRAGMA_MESSAGE("Using POSIX yield_k") -#endif - -inline void sp_thread_yield() -{ - sched_yield(); -} - -inline void sp_thread_sleep() -{ - // 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 ); -} - -} // namespace detail - -} // namespace boost - -#else - -#if defined(BOOST_SP_REPORT_IMPLEMENTATION) - BOOST_PRAGMA_MESSAGE("Using empty yield_k") -#endif - -namespace boost -{ - -namespace detail -{ - -inline void sp_thread_yield() -{ - BOOST_SMT_PAUSE -} - -inline void sp_thread_sleep() -{ - BOOST_SMT_PAUSE -} - -} // namespace detail - -} // namespace boost - -#endif - -namespace boost -{ - -namespace detail -{ - -inline void yield( unsigned k ) BOOST_NOEXCEPT -{ - // Experiments show that a simple sp_thread_sleep() here is best; - // leave a few pause instructions out of mostly superstition. - // (These are verified to not degrade performance.) - // - // There seems to be no benefit from calling sp_thread_yield() - // at any time. - - if( k < 8 ) + if( k == 0 ) { - BOOST_SMT_PAUSE + sp_thread_pause(); } else { From 6e8c15c02fca67d75c6ded154fb5673827ab2f09 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 10 Jun 2020 21:59:48 +0300 Subject: [PATCH 19/20] Fix typo, trailing whitespace --- include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp b/include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp index c2172e9..99ded0d 100644 --- a/include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp +++ b/include/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp @@ -7,7 +7,7 @@ # pragma once #endif -// detail/sp_counted_base_gc_atomic.hpp - g++ 4.7+ __atomic intrinsics +// detail/sp_counted_base_gcc_atomic.hpp - g++ 4.7+ __atomic intrinsics // // Copyright 2007, 2020 Peter Dimov // Distributed under the Boost Software License, Version 1.0. @@ -59,7 +59,7 @@ inline boost::uint_least32_t atomic_conditional_increment( boost::uint_least32_t { return r; } - } + } } inline boost::uint_least32_t atomic_load( boost::uint_least32_t const * pw ) From d1295a9974923e15d2bfd35aaae488325d348b20 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 11 Jun 2020 17:19:17 +0300 Subject: [PATCH 20/20] Remove boost_install call from CMakeLists.txt --- .travis.yml | 1 + CMakeLists.txt | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 06dfc9b..bcdbeab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -394,6 +394,7 @@ matrix: - os: linux env: CMAKE_INSTALL_TEST=1 script: + - pip install --user cmake - mkdir __build__ && cd __build__ - cmake -DBOOST_ENABLE_CMAKE=1 -DBoost_VERBOSE=1 -DBOOST_INCLUDE_LIBRARIES=smart_ptr -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=~/.local .. - cmake --build . --target install diff --git a/CMakeLists.txt b/CMakeLists.txt index bbb6a48..31c012d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,13 +22,6 @@ target_link_libraries(boost_smart_ptr Boost::type_traits ) -if(BOOST_SUPERPROJECT_VERSION) - - include(BoostInstall) - boost_install(TARGETS boost_smart_ptr HEADER_DIRECTORY include/) - -endif() - if(BUILD_TESTING) add_subdirectory(test)