Merge branch 'develop'

This commit is contained in:
Peter Dimov
2020-06-19 19:17:05 +03:00
30 changed files with 701 additions and 652 deletions

View File

@@ -43,8 +43,9 @@
// Memory Ordering: acquire/release
//
#include <boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp>
#include <boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp>
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
#if defined( BOOST_AC_DISABLE_THREADS )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
@@ -73,15 +74,18 @@
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
#elif defined( BOOST_SP_HAS_GCC_INTRINSICS )
# include <boost/smart_ptr/detail/atomic_count_gcc_atomic.hpp>
#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS )
# include <boost/smart_ptr/detail/atomic_count_sync.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ )
# include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
# include <boost/smart_ptr/detail/atomic_count_sync.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
# include <boost/smart_ptr/detail/atomic_count_win32.hpp>

View File

@@ -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 <boost/cstdint.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
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

View File

@@ -13,6 +13,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
@@ -20,6 +22,8 @@ BOOST_PRAGMA_MESSAGE("Using g++/x86 atomic_count")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{

View File

@@ -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 <atomic.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
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<uint32_t const volatile &>( 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

View File

@@ -15,6 +15,8 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/cstdint.hpp>
#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
# include <ia64intrin.h>
#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

View File

@@ -17,14 +17,9 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp>
#include <boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp>
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
#if !defined( __c2__ ) && defined( __clang__ ) && defined( __has_extension )
# if __has_extension( __c_atomic__ )
# define BOOST_SP_HAS_CLANG_C11_ATOMICS
# endif
#endif
#if defined( BOOST_SP_DISABLE_THREADS )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
@@ -41,18 +36,24 @@
#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
#elif defined( BOOST_SP_HAS_CLANG_C11_ATOMICS )
# include <boost/smart_ptr/detail/sp_counted_base_clang.hpp>
#elif defined( BOOST_SP_HAS_GCC_INTRINSICS )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp>
#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
#elif defined( __SNC__ )
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
#elif defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS )
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
#elif defined( __SNC__ )
# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
#elif defined(__HP_aCC) && defined(__ia64)
# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
@@ -71,9 +72,6 @@
#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__) && !defined( __mips16 )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
# include <boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp>
@@ -91,6 +89,4 @@
#endif
#undef BOOST_SP_HAS_CLANG_C11_ATOMICS
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED

View File

@@ -16,6 +16,7 @@
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#include <machine/sys/inline.h>
@@ -26,6 +27,8 @@ BOOST_PRAGMA_MESSAGE("Using HP aCC++/HP-UX/IA64 sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{

View File

@@ -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 <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
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

View File

@@ -25,6 +25,7 @@
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#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
{

View File

@@ -1,5 +1,5 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
#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
@@ -7,31 +7,20 @@
# pragma once
#endif
// detail/sp_counted_base_gcc_atomic.hpp - g++ 4.7+ __atomic intrinsics
//
// 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
//
// Copyright 2007, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using CodeWarrior/x86 sp_counted_base")
BOOST_PRAGMA_MESSAGE("Using __atomic sp_counted_base")
#endif
@@ -41,50 +30,41 @@ namespace boost
namespace detail
{
inline int atomic_exchange_and_add( int * pw, int dv )
inline void atomic_increment( boost::uint_least32_t * pw )
{
// int r = *pw;
// *pw += dv;
__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;
asm
boost::uint_least32_t r = __atomic_load_n( pw, __ATOMIC_RELAXED );
for( ;; )
{
mov esi, [pw]
mov eax, dv
lock xadd dword ptr [esi], eax
if( r == 0 )
{
return r;
}
if( __atomic_compare_exchange_n( pw, &r, r + 1, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) )
{
return r;
}
}
}
inline void atomic_increment( int * pw )
inline boost::uint_least32_t atomic_load( boost::uint_least32_t const * 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:
}
return __atomic_load_n( pw, __ATOMIC_ACQUIRE );
}
class BOOST_SYMBOL_VISIBLE sp_counted_base
@@ -94,8 +74,8 @@ 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)
boost::uint_least32_t use_count_; // #shared
boost::uint_least32_t weak_count_; // #weak + (#shared != 0)
public:
@@ -135,7 +115,7 @@ public:
void release() // nothrow
{
if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
if( atomic_decrement( &use_count_ ) == 1 )
{
dispose();
weak_release();
@@ -149,7 +129,7 @@ public:
void weak_release() // nothrow
{
if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
if( atomic_decrement( &weak_count_ ) == 1 )
{
destroy();
}
@@ -157,7 +137,7 @@ public:
long use_count() const // nothrow
{
return static_cast<int const volatile &>( use_count_ );
return atomic_load( &use_count_ );
}
};
@@ -165,4 +145,4 @@ public:
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED

View File

@@ -17,6 +17,7 @@
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#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
{

View File

@@ -21,6 +21,7 @@
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#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
{

View File

@@ -25,6 +25,7 @@
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#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
{

View File

@@ -20,6 +20,7 @@
// Thanks to Michael van der Westhuizen
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#include <inttypes.h> // int32_t
@@ -30,6 +31,8 @@ BOOST_PRAGMA_MESSAGE("Using g++/Sparc sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{

View File

@@ -25,6 +25,7 @@
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#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
{

View File

@@ -20,6 +20,7 @@
// Thanks to Michael van der Westhuizen
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#include <inttypes.h> // uint32_t
@@ -30,6 +31,8 @@ BOOST_PRAGMA_MESSAGE("Using PS3 sp_counted_base")
#endif
BOOST_SP_OBSOLETE()
namespace boost
{

View File

@@ -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 <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/config.hpp>
#include <atomic.h>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
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<long const volatile &>( use_count_ );
}
};
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED

View File

@@ -22,6 +22,7 @@
//
#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
#include <boost/smart_ptr/detail/sp_obsolete.hpp>
#include <boost/config.hpp>
#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);

View File

@@ -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

View File

@@ -1,69 +0,0 @@
#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/smart_ptr/detail/sp_has_sync.hpp
//
// Copyright (c) 2008, 2009 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)
//
// Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics
// are available.
//
#ifndef BOOST_SP_NO_SYNC
#if !defined( __c2__ ) && defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
# define BOOST_SP_HAS_SYNC
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) && !defined( __COMPILER_VER__ )
# define BOOST_SP_HAS_SYNC
#elif !defined( __c2__ ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
#define BOOST_SP_HAS_SYNC
#if defined( __arm__ ) || defined( __armel__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __hppa ) || defined( __hppa__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __m68k__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __sh__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __sparc__ )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
#undef BOOST_SP_HAS_SYNC
#endif
#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
#undef BOOST_SP_HAS_SYNC
#endif
#endif
#endif // #ifndef BOOST_SP_NO_SYNC
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED

View File

@@ -0,0 +1,69 @@
#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
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp
//
// Copyright (c) 2008, 2009 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)
//
// Defines the BOOST_SP_HAS_SYNC_INTRINSICS macro if the __sync_* intrinsics
// are available.
//
#if !defined( BOOST_SP_NO_SYNC_INTRINSICS ) && !defined( BOOST_SP_NO_SYNC )
#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 ) && !defined( __c2__ )
# define BOOST_SP_HAS_SYNC_INTRINSICS
#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 ) && !defined( __COMPILER_VER__ )
# define BOOST_SP_HAS_SYNC_INTRINSICS
#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) && !defined( __c2__ )
#define BOOST_SP_HAS_SYNC_INTRINSICS
#if defined( __arm__ ) || defined( __armel__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __hppa ) || defined( __hppa__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __m68k__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __sh__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __sparc__ )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
#undef BOOST_SP_HAS_SYNC_INTRINSICS
#endif
#endif
#endif // #if !defined( BOOST_SP_NO_SYNC_INTRINSICS ) && !defined( BOOST_SP_NO_SYNC )
#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_INTRINSICS_HPP_INCLUDED

View File

@@ -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 <boost/config/pragma_message.hpp>
#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

View File

@@ -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

View File

@@ -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 <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#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 <boost/smart_ptr/detail/sp_win32_sleep.hpp>
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 <time.h>
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 <boost/smart_ptr/detail/sp_thread_yield.hpp>
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

View File

@@ -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 <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#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 <boost/smart_ptr/detail/sp_win32_sleep.hpp>
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 <sched.h>
#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 <boost/smart_ptr/detail/sp_thread_pause.hpp>
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

View File

@@ -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 <windows.h>
#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

View File

@@ -28,28 +28,26 @@
// #define BOOST_DETAIL_SPINLOCK_INIT <unspecified>
//
#include <boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp>
#include <boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp>
#include <boost/config.hpp>
#include <boost/smart_ptr/detail/sp_has_sync.hpp>
#if defined( BOOST_SP_USE_STD_ATOMIC )
# if !defined( __clang__ )
# include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
# else
// Clang (at least up to 3.4) can't compile spinlock_pool when
// using std::atomic, so substitute the __sync implementation instead.
# include <boost/smart_ptr/detail/spinlock_sync.hpp>
# endif
# include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
#elif defined( BOOST_SP_USE_PTHREADS )
# include <boost/smart_ptr/detail/spinlock_pt.hpp>
#elif defined( BOOST_SP_HAS_GCC_INTRINSICS )
# include <boost/smart_ptr/detail/spinlock_gcc_atomic.hpp>
#elif !defined( BOOST_NO_CXX11_HDR_ATOMIC )
# include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
# include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
#elif defined( BOOST_SP_HAS_SYNC )
#elif defined( BOOST_SP_HAS_SYNC_INTRINSICS )
# include <boost/smart_ptr/detail/spinlock_sync.hpp>
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)

View File

@@ -0,0 +1,85 @@
#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 2008, 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/smart_ptr/detail/yield_k.hpp>
#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("Using __atomic spinlock")
#endif
namespace boost
{
namespace detail
{
class spinlock
{
public:
unsigned char v_;
public:
bool try_lock()
{
return __atomic_test_and_set( &v_, __ATOMIC_ACQUIRE ) == 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

View File

@@ -38,7 +38,7 @@ class spinlock
{
public:
int v_;
unsigned char v_;
public:

View File

@@ -7,107 +7,22 @@
# 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 <boost/smart_ptr/detail/sp_thread_pause.hpp>
#include <boost/smart_ptr/detail/sp_thread_sleep.hpp>
#include <boost/config.hpp>
// 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" );
#endif
//
#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
#if defined( BOOST_USE_WINDOWS_H )
# include <windows.h>
#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 )
inline void yield( unsigned k ) BOOST_NOEXCEPT
{
if( k < 4 )
{
}
#if defined( BOOST_SMT_PAUSE )
else if( k < 16 )
{
BOOST_SMT_PAUSE
}
#endif
else if( k < 32 )
{
Sleep( 0 );
}
else
{
Sleep( 1 );
}
}
} // namespace detail
} // namespace boost
#elif defined( BOOST_HAS_PTHREADS )
#ifndef _AIX
#include <sched.h>
#else
// AIX's sched.h defines ::var which sometimes conflicts with Lambda's var
extern "C" int sched_yield(void);
#endif
#include <time.h>
namespace boost
{
@@ -116,31 +31,16 @@ namespace detail
inline void yield( unsigned k )
{
if( k < 4 )
// Experiments on Windows and Fedora 32 show that a single pause,
// followed by an immediate sp_thread_sleep(), is best.
if( k == 0 )
{
}
#if defined( BOOST_SMT_PAUSE )
else if( k < 16 )
{
BOOST_SMT_PAUSE
}
#endif
else if( k < 32 || k & 1 )
{
sched_yield();
sp_thread_pause();
}
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
rqtp.tv_sec = 0;
rqtp.tv_nsec = 1000;
nanosleep( &rqtp, 0 );
sp_thread_sleep();
}
}
@@ -148,22 +48,4 @@ inline void yield( unsigned k )
} // namespace boost
#else
namespace boost
{
namespace detail
{
inline void yield( unsigned )
{
}
} // namespace detail
} // namespace boost
#endif
#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED