mirror of
				https://github.com/boostorg/smart_ptr.git
				synced 2025-10-26 21:31:43 +01:00 
			
		
		
		
	Compare commits
	
		
			19 Commits
		
	
	
		
			feature/qu
			...
			develop
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8688d747ae | ||
|  | 6e1365d7f5 | ||
|  | 341fdb46e4 | ||
|  | c420499c2e | ||
|  | 94202f9337 | ||
|  | 790c9f90b7 | ||
|  | 0989086658 | ||
|  | bfe49f8f4e | ||
|  | 78ec99da57 | ||
|  | fac91cbe3f | ||
|  | 0c171cfbbb | ||
|  | 7828024b8f | ||
|  | 9f5a48ab3b | ||
|  | 50a0e2e364 | ||
|  | 6b003aafa9 | ||
|  | b1e032396d | ||
|  | 456161d9e2 | ||
|  | 51e1a51b8a | ||
|  | d7533d9c83 | 
| @@ -98,17 +98,17 @@ local windows_pipeline(name, image, environment, arch = "amd64") = | ||||
|  | ||||
| [ | ||||
|     linux_pipeline( | ||||
|         "Linux 14.04 GCC 4.8*", | ||||
|         "cppalliance/droneubuntu1404:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11' }, | ||||
|         "Linux 16.04 GCC 4.8", | ||||
|         "cppalliance/droneubuntu1604:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-4.8', CXXSTD: '11' }, | ||||
|         "g++-4.8", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 14.04 GCC 4.9", | ||||
|         "cppalliance/droneubuntu1404:1", | ||||
|         "Linux 16.04 GCC 4.9", | ||||
|         "cppalliance/droneubuntu1604:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '11' }, | ||||
|         "g++-4.9", | ||||
|         [ "ppa:ubuntu-toolchain-r/test" ], | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
| @@ -213,17 +213,17 @@ local windows_pipeline(name, image, environment, arch = "amd64") = | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 16.04 Clang 3.5", | ||||
|         "cppalliance/droneubuntu1604:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-3.5', CXXSTD: '11' }, | ||||
|         "clang-3.5", | ||||
|         "Linux 25.04 GCC 15 UBSAN", | ||||
|         "cppalliance/droneubuntu2504:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-15', CXXSTD: '11,14,17,20,23,2c' } + ubsan, | ||||
|         "g++-15-multilib", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|         "Linux 16.04 Clang 3.6", | ||||
|         "cppalliance/droneubuntu1604:1", | ||||
|         { TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '11,14' }, | ||||
|         "clang-3.6", | ||||
|         "Linux 25.04 GCC 15 ASAN", | ||||
|         "cppalliance/droneubuntu2504:1", | ||||
|         { TOOLSET: 'gcc', COMPILER: 'g++-15', CXXSTD: '11,14,17,20,23,2c' } + asan, | ||||
|         "g++-15-multilib", | ||||
|     ), | ||||
|  | ||||
|     linux_pipeline( | ||||
|   | ||||
| @@ -43,10 +43,7 @@ | ||||
| //    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/smart_ptr/detail/deprecated_macros.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined( BOOST_AC_DISABLE_THREADS ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_nt.hpp> | ||||
| @@ -54,50 +51,11 @@ | ||||
| #elif defined( BOOST_AC_USE_STD_ATOMIC ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp> | ||||
|  | ||||
| #elif defined( BOOST_AC_USE_SPINLOCK ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_spin.hpp> | ||||
|  | ||||
| #elif defined( BOOST_AC_USE_PTHREADS ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_pt.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_DISABLE_THREADS ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_nt.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_USE_STD_ATOMIC ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_USE_SPINLOCK ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_spin.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_USE_PTHREADS ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_pt.hpp> | ||||
|  | ||||
| #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(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) | ||||
| # include <boost/smart_ptr/detail/atomic_count_win32.hpp> | ||||
|  | ||||
| #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) | ||||
| # include <boost/smart_ptr/detail/atomic_count_gcc.hpp> | ||||
|  | ||||
| #elif !defined( BOOST_HAS_THREADS ) | ||||
| # include <boost/smart_ptr/detail/atomic_count_nt.hpp> | ||||
|  | ||||
| #else | ||||
| # include <boost/smart_ptr/detail/atomic_count_spin.hpp> | ||||
| # include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp> | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -1,79 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  boost/detail/atomic_count_gcc.hpp | ||||
| // | ||||
| //  atomic_count for GNU libstdc++ v3 | ||||
| // | ||||
| //  http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html | ||||
| // | ||||
| //  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright (c) 2002 Lars Gullik Bjønnes <larsbj@lyx.org> | ||||
| //  Copyright 2003-2005 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) | ||||
| // | ||||
|  | ||||
| #if __GNUC__ * 100 + __GNUC_MINOR__ >= 402 | ||||
| # include <ext/atomicity.h>  | ||||
| #else  | ||||
| # include <bits/atomicity.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using libstdc++ atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| #if defined(__GLIBCXX__) // g++ 3.4+ | ||||
|  | ||||
| using __gnu_cxx::__atomic_add; | ||||
| using __gnu_cxx::__exchange_and_add; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| class atomic_count | ||||
| { | ||||
| public: | ||||
|  | ||||
|     explicit atomic_count( long v ) : value_( v ) {} | ||||
|  | ||||
|     long operator++() | ||||
|     { | ||||
|         return __exchange_and_add( &value_, +1 ) + 1; | ||||
|     } | ||||
|  | ||||
|     long operator--() | ||||
|     { | ||||
|         return __exchange_and_add( &value_, -1 ) - 1; | ||||
|     } | ||||
|  | ||||
|     operator long() const | ||||
|     { | ||||
|         return __exchange_and_add( &value_, 0 ); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     atomic_count(atomic_count const &); | ||||
|     atomic_count & operator=(atomic_count const &); | ||||
|  | ||||
|     mutable _Atomic_word value_; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED | ||||
| @@ -1,63 +0,0 @@ | ||||
| #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 | ||||
| @@ -1,88 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  boost/detail/atomic_count_gcc_x86.hpp | ||||
| // | ||||
| //  atomic_count for g++ on 486+/AMD64 | ||||
| // | ||||
| //  Copyright 2007 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_obsolete.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/x86 atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class atomic_count | ||||
| { | ||||
| public: | ||||
|  | ||||
|     explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {} | ||||
|  | ||||
|     long operator++() | ||||
|     { | ||||
|         return atomic_exchange_and_add( &value_, +1 ) + 1; | ||||
|     } | ||||
|  | ||||
|     long operator--() | ||||
|     { | ||||
|         return atomic_exchange_and_add( &value_, -1 ) - 1; | ||||
|     } | ||||
|  | ||||
|     operator long() const | ||||
|     { | ||||
|         return atomic_exchange_and_add( &value_, 0 ); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     atomic_count(atomic_count const &); | ||||
|     atomic_count & operator=(atomic_count const &); | ||||
|  | ||||
|     mutable int value_; | ||||
|  | ||||
| private: | ||||
|  | ||||
|     static int atomic_exchange_and_add( int * pw, int dv ) | ||||
|     { | ||||
|         // int r = *pw; | ||||
|         // *pw += dv; | ||||
|         // return r; | ||||
|  | ||||
|         int r; | ||||
|  | ||||
|         __asm__ __volatile__ | ||||
|         ( | ||||
|             "lock\n\t" | ||||
|             "xadd %1, %0": | ||||
|             "+m"( *pw ), "=r"( r ): // outputs (%0, %1) | ||||
|             "1"( dv ): // inputs (%2 == %1) | ||||
|             "memory", "cc" // clobbers | ||||
|         ); | ||||
|  | ||||
|         return r; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED | ||||
| @@ -1,104 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  boost/detail/atomic_count_pthreads.hpp | ||||
| // | ||||
| //  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. | ||||
| // | ||||
| // 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/assert.hpp> | ||||
| #include <pthread.h> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using pthread_mutex atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  The generic pthread_mutex-based implementation sometimes leads to | ||||
| //    inefficiencies. Example: a class with two atomic_count members | ||||
| //    can get away with a single mutex. | ||||
| // | ||||
| //  Users can detect this situation by checking BOOST_AC_USE_PTHREADS. | ||||
| // | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class atomic_count | ||||
| { | ||||
| private: | ||||
|  | ||||
|     class scoped_lock | ||||
|     { | ||||
|     public: | ||||
|  | ||||
|         scoped_lock(pthread_mutex_t & m): m_(m) | ||||
|         { | ||||
|             BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         } | ||||
|  | ||||
|         ~scoped_lock() | ||||
|         { | ||||
|             BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         pthread_mutex_t & m_; | ||||
|     }; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     explicit atomic_count(long v): value_(v) | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_init( &mutex_, 0 ) == 0 ); | ||||
|     } | ||||
|  | ||||
|     ~atomic_count() | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_destroy( &mutex_ ) == 0 ); | ||||
|     } | ||||
|  | ||||
|     long operator++() | ||||
|     { | ||||
|         scoped_lock lock(mutex_); | ||||
|         return ++value_; | ||||
|     } | ||||
|  | ||||
|     long operator--() | ||||
|     { | ||||
|         scoped_lock lock(mutex_); | ||||
|         return --value_; | ||||
|     } | ||||
|  | ||||
|     operator long() const | ||||
|     { | ||||
|         scoped_lock lock(mutex_); | ||||
|         return value_; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     atomic_count(atomic_count const &); | ||||
|     atomic_count & operator=(atomic_count const &); | ||||
|  | ||||
|     mutable pthread_mutex_t mutex_; | ||||
|     long value_; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED | ||||
| @@ -1,69 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  boost/detail/atomic_count_spin.hpp | ||||
| // | ||||
| //  Copyright (c) 2013 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/spinlock_pool.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using spinlock-based atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class atomic_count | ||||
| { | ||||
| private: | ||||
|  | ||||
| public: | ||||
|  | ||||
|     explicit atomic_count( long v ): value_( v ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     long operator++() | ||||
|     { | ||||
|         spinlock_pool<0>::scoped_lock lock( &value_ ); | ||||
|         return ++value_; | ||||
|     } | ||||
|  | ||||
|     long operator--() | ||||
|     { | ||||
|         spinlock_pool<0>::scoped_lock lock( &value_ ); | ||||
|         return --value_; | ||||
|     } | ||||
|  | ||||
|     operator long() const | ||||
|     { | ||||
|         spinlock_pool<0>::scoped_lock lock( &value_ ); | ||||
|         return value_; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     atomic_count(atomic_count const &); | ||||
|     atomic_count & operator=(atomic_count const &); | ||||
|  | ||||
|     long value_; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SPIN_HPP_INCLUDED | ||||
| @@ -1,72 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  boost/detail/atomic_count_sync.hpp | ||||
| // | ||||
| //  atomic_count for g++ 4.1+ | ||||
| // | ||||
| //  http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html | ||||
| // | ||||
| //  Copyright 2007 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/cstdint.hpp> | ||||
|  | ||||
| #if defined( __ia64__ ) && defined( __INTEL_COMPILER ) | ||||
| # include <ia64intrin.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using __sync 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 __sync_add_and_fetch( &value_, 1 ); | ||||
|     } | ||||
|  | ||||
|     long operator--() | ||||
|     { | ||||
|         return __sync_add_and_fetch( &value_, -1 ); | ||||
|     } | ||||
|  | ||||
|     operator long() const | ||||
|     { | ||||
|         return __sync_fetch_and_add( &value_, 0 ); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     atomic_count(atomic_count const &); | ||||
|     atomic_count & operator=(atomic_count const &); | ||||
|  | ||||
|     mutable boost::int_least32_t value_; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED | ||||
| @@ -1,70 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  boost/detail/atomic_count_win32.hpp | ||||
| // | ||||
| //  Copyright (c) 2001-2005 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_interlocked.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using Win32 atomic_count") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class atomic_count | ||||
| { | ||||
| public: | ||||
|  | ||||
|     explicit atomic_count( long v ): value_( v ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     long operator++() | ||||
|     { | ||||
|         return BOOST_SP_INTERLOCKED_INCREMENT( &value_ ); | ||||
|     } | ||||
|  | ||||
|     long operator--() | ||||
|     { | ||||
|         return BOOST_SP_INTERLOCKED_DECREMENT( &value_ ); | ||||
|     } | ||||
|  | ||||
|     operator long() const | ||||
|     { | ||||
|         return static_cast<long const volatile &>( value_ ); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     atomic_count( atomic_count const & ); | ||||
|     atomic_count & operator=( atomic_count const & ); | ||||
|  | ||||
|     long value_; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED | ||||
| @@ -27,25 +27,25 @@ BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_QUICK_ALLOCATOR has been deprecated | ||||
|  | ||||
| #if defined(BOOST_AC_USE_SPINLOCK) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_AC_USE_SPINLOCK has been deprecated in 1.87 and support for it will be removed.") | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_AC_USE_SPINLOCK has been deprecated in 1.87 and support for it was removed in 1.90.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_AC_USE_PTHREADS) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_AC_USE_PTHREADS has been deprecated in 1.87 and support for it will be removed.") | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_AC_USE_PTHREADS has been deprecated in 1.87 and support for it was removed in 1.90.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_USE_SPINLOCK) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_SPINLOCK has been deprecated in 1.87 and support for it will be removed.") | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_SPINLOCK has been deprecated in 1.87 and support for it was removed in 1.90.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_USE_PTHREADS) | ||||
|  | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_PTHREADS has been deprecated in 1.87 and support for it will be removed.") | ||||
| BOOST_PRAGMA_MESSAGE("The macro BOOST_SP_USE_PTHREADS has been deprecated in 1.87 and support for it was removed in 1.90.") | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -23,17 +23,9 @@ | ||||
| // | ||||
| //  http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex | ||||
| // | ||||
| //  It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX. | ||||
| //  It's obsoleted by std::mutex. | ||||
| // | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if !defined(BOOST_NO_CXX11_HDR_MUTEX ) | ||||
| #  include <boost/smart_ptr/detail/lwm_std_mutex.hpp> | ||||
| #elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) | ||||
| #  include <boost/smart_ptr/detail/lwm_win32_cs.hpp> | ||||
| #else | ||||
| #  include <boost/smart_ptr/detail/lwm_pthreads.hpp> | ||||
| #endif | ||||
| #include <boost/smart_ptr/detail/lwm_std_mutex.hpp> | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED | ||||
|   | ||||
| @@ -21,141 +21,33 @@ | ||||
| //  template<class F> int lw_thread_create( lw_thread_t & th, F f ); | ||||
| //  void lw_thread_join( lw_thread_t th ); | ||||
|  | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <memory> | ||||
| #include <cerrno> | ||||
|  | ||||
| #if defined( BOOST_HAS_PTHREADS ) | ||||
|  | ||||
| #include <pthread.h> | ||||
| #include <thread> | ||||
| #include <exception> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| typedef ::pthread_t lw_thread_t; | ||||
| using lw_thread_t = std::thread*; | ||||
|  | ||||
| inline int lw_thread_create_( lw_thread_t* thread, const pthread_attr_t* attr, void* (*start_routine)( void* ), void* arg ) | ||||
| template<class F> int lw_thread_create( lw_thread_t& th, F f ) | ||||
| { | ||||
|     return ::pthread_create( thread, attr, start_routine, arg ); | ||||
| } | ||||
|  | ||||
| inline void lw_thread_join( lw_thread_t th ) | ||||
| { | ||||
|     ::pthread_join( th, 0 ); | ||||
| } | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #else // defined( BOOST_HAS_PTHREADS ) | ||||
|  | ||||
| #include <windows.h> | ||||
| #include <process.h> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| typedef HANDLE lw_thread_t; | ||||
|  | ||||
| inline int lw_thread_create_( lw_thread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg ) | ||||
| { | ||||
|     HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 ); | ||||
|  | ||||
|     if( h != 0 ) | ||||
|     try | ||||
|     { | ||||
|         *thread = h; | ||||
|         th = new std::thread( f ); | ||||
|         return 0; | ||||
|     } | ||||
|     else | ||||
|     catch( std::exception const& ) | ||||
|     { | ||||
|         return EAGAIN; | ||||
|         return -1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| inline void lw_thread_join( lw_thread_t thread ) | ||||
| void lw_thread_join( lw_thread_t th ) | ||||
| { | ||||
|     ::WaitForSingleObject( thread, INFINITE ); | ||||
|     ::CloseHandle( thread ); | ||||
| } | ||||
|  | ||||
| } // namespace detail | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // defined( BOOST_HAS_PTHREADS ) | ||||
|  | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class lw_abstract_thread | ||||
| { | ||||
| public: | ||||
|  | ||||
|     virtual ~lw_abstract_thread() {} | ||||
|     virtual void run() = 0; | ||||
| }; | ||||
|  | ||||
| #if defined( BOOST_HAS_PTHREADS ) | ||||
|  | ||||
| extern "C" inline void * lw_thread_routine( void * pv ) | ||||
| { | ||||
|     std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) ); | ||||
|  | ||||
|     pt->run(); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| inline unsigned __stdcall lw_thread_routine( void * pv ) | ||||
| { | ||||
|     std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) ); | ||||
|  | ||||
|     pt->run(); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| template<class F> class lw_thread_impl: public lw_abstract_thread | ||||
| { | ||||
| public: | ||||
|  | ||||
|     explicit lw_thread_impl( F f ): f_( f ) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     void run() | ||||
|     { | ||||
|         f_(); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     F f_; | ||||
| }; | ||||
|  | ||||
| template<class F> int lw_thread_create( lw_thread_t & th, F f ) | ||||
| { | ||||
|     std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) ); | ||||
|  | ||||
|     int r = lw_thread_create_( &th, 0, lw_thread_routine, p.get() ); | ||||
|  | ||||
|     if( r == 0 ) | ||||
|     { | ||||
|         p.release(); | ||||
|     } | ||||
|  | ||||
|     return r; | ||||
|     th->join(); | ||||
|     delete th; | ||||
| } | ||||
|  | ||||
| } // namespace detail | ||||
|   | ||||
| @@ -1,87 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  boost/detail/lwm_pthreads.hpp | ||||
| // | ||||
| //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd. | ||||
| // | ||||
| // 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/assert.hpp> | ||||
| #include <pthread.h> | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class lightweight_mutex | ||||
| { | ||||
| private: | ||||
|  | ||||
|     pthread_mutex_t m_; | ||||
|  | ||||
|     lightweight_mutex(lightweight_mutex const &); | ||||
|     lightweight_mutex & operator=(lightweight_mutex const &); | ||||
|  | ||||
| public: | ||||
|  | ||||
|     lightweight_mutex() | ||||
|     { | ||||
|  | ||||
| // HPUX 10.20 / DCE has a nonstandard pthread_mutex_init | ||||
|  | ||||
| #if defined(__hpux) && defined(_DECTHREADS_) | ||||
|         BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 ); | ||||
| #else | ||||
|         BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 ); | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     ~lightweight_mutex() | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 ); | ||||
|     } | ||||
|  | ||||
|     class scoped_lock; | ||||
|     friend class scoped_lock; | ||||
|  | ||||
|     class scoped_lock | ||||
|     { | ||||
|     private: | ||||
|  | ||||
|         pthread_mutex_t & m_; | ||||
|  | ||||
|         scoped_lock(scoped_lock const &); | ||||
|         scoped_lock & operator=(scoped_lock const &); | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         scoped_lock(lightweight_mutex & m): m_(m.m_) | ||||
|         { | ||||
|             BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         } | ||||
|  | ||||
|         ~scoped_lock() | ||||
|         { | ||||
|             BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|         } | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED | ||||
| @@ -1,123 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  boost/detail/lwm_win32_cs.hpp | ||||
| // | ||||
| //  Copyright (c) 2002, 2003 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) | ||||
| // | ||||
|  | ||||
| #ifdef BOOST_USE_WINDOWS_H | ||||
|  | ||||
| #include <windows.h> | ||||
|  | ||||
| #else | ||||
|  | ||||
| struct _RTL_CRITICAL_SECTION; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| #ifndef BOOST_USE_WINDOWS_H | ||||
|  | ||||
| struct critical_section | ||||
| { | ||||
|     struct critical_section_debug * DebugInfo; | ||||
|     long LockCount; | ||||
|     long RecursionCount; | ||||
|     void * OwningThread; | ||||
|     void * LockSemaphore; | ||||
| #if defined(_WIN64) | ||||
|     unsigned __int64 SpinCount; | ||||
| #else | ||||
|     unsigned long SpinCount; | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *); | ||||
| extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *); | ||||
| extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *); | ||||
| extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *); | ||||
|  | ||||
| typedef ::_RTL_CRITICAL_SECTION rtl_critical_section; | ||||
|  | ||||
| #else // #ifndef BOOST_USE_WINDOWS_H | ||||
|  | ||||
| typedef ::CRITICAL_SECTION critical_section; | ||||
|  | ||||
| using ::InitializeCriticalSection; | ||||
| using ::EnterCriticalSection; | ||||
| using ::LeaveCriticalSection; | ||||
| using ::DeleteCriticalSection; | ||||
|  | ||||
| typedef ::CRITICAL_SECTION rtl_critical_section; | ||||
|  | ||||
| #endif // #ifndef BOOST_USE_WINDOWS_H | ||||
|  | ||||
| class lightweight_mutex | ||||
| { | ||||
| private: | ||||
|  | ||||
|     critical_section cs_; | ||||
|  | ||||
|     lightweight_mutex(lightweight_mutex const &); | ||||
|     lightweight_mutex & operator=(lightweight_mutex const &); | ||||
|  | ||||
| public: | ||||
|  | ||||
|     lightweight_mutex() | ||||
|     { | ||||
|         boost::detail::InitializeCriticalSection(reinterpret_cast< rtl_critical_section* >(&cs_)); | ||||
|     } | ||||
|  | ||||
|     ~lightweight_mutex() | ||||
|     { | ||||
|         boost::detail::DeleteCriticalSection(reinterpret_cast< rtl_critical_section* >(&cs_)); | ||||
|     } | ||||
|  | ||||
|     class scoped_lock; | ||||
|     friend class scoped_lock; | ||||
|  | ||||
|     class scoped_lock | ||||
|     { | ||||
|     private: | ||||
|  | ||||
|         lightweight_mutex & m_; | ||||
|  | ||||
|         scoped_lock(scoped_lock const &); | ||||
|         scoped_lock & operator=(scoped_lock const &); | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         explicit scoped_lock(lightweight_mutex & m): m_(m) | ||||
|         { | ||||
|             boost::detail::EnterCriticalSection(reinterpret_cast< rtl_critical_section* >(&m_.cs_)); | ||||
|         } | ||||
|  | ||||
|         ~scoped_lock() | ||||
|         { | ||||
|             boost::detail::LeaveCriticalSection(reinterpret_cast< rtl_critical_section* >(&m_.cs_)); | ||||
|         } | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED | ||||
| @@ -28,7 +28,7 @@ | ||||
| #include <boost/core/addressof.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/config/workaround.hpp> | ||||
| #include <boost/cstdint.hpp> | ||||
| #include <cstdint> | ||||
| #include <memory>            // std::auto_ptr | ||||
| #include <functional>        // std::less | ||||
| #include <cstddef>           // std::size_t | ||||
| @@ -91,7 +91,7 @@ template< class D > struct sp_convert_reference< D& > | ||||
|  | ||||
| template<class T> std::size_t sp_hash_pointer( T* p ) noexcept | ||||
| { | ||||
|     boost::uintptr_t v = reinterpret_cast<boost::uintptr_t>( p ); | ||||
|     std::uintptr_t v = reinterpret_cast<std::uintptr_t>( p ); | ||||
|  | ||||
|     // match boost::hash<T*> | ||||
|     return static_cast<std::size_t>( v + ( v >> 3 ) ); | ||||
|   | ||||
| @@ -17,76 +17,13 @@ | ||||
| // 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/smart_ptr/detail/deprecated_macros.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined( BOOST_SP_DISABLE_THREADS ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_nt.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_USE_STD_ATOMIC ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_USE_SPINLOCK ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_spin.hpp> | ||||
|  | ||||
| #elif defined( BOOST_SP_USE_PTHREADS ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_pt.hpp> | ||||
|  | ||||
| #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_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( __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> | ||||
|  | ||||
| #elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp> | ||||
|  | ||||
| #elif defined( __IBMCPP__ ) && defined( __powerpc ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp> | ||||
|  | ||||
| #elif defined( __MWERKS__ ) && defined( __POWERPC__ ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp> | ||||
|  | ||||
| #elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp> | ||||
|  | ||||
| #elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__) && !defined( __mips16 ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp> | ||||
|  | ||||
| #elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp> | ||||
|  | ||||
| #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_w32.hpp> | ||||
|  | ||||
| #elif defined( _AIX ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_aix.hpp> | ||||
|  | ||||
| #elif !defined( BOOST_HAS_THREADS ) | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_nt.hpp> | ||||
|  | ||||
| #else | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_spin.hpp> | ||||
| # include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp> | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -1,163 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64 | ||||
| // | ||||
| //  Copyright 2007 Baruch Zilber | ||||
| //  Copyright 2007 Boris Gubenko | ||||
| // | ||||
| //  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 | ||||
| // | ||||
|  | ||||
| #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> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using HP aCC++/HP-UX/IA64 sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void atomic_increment( int * pw ) | ||||
| { | ||||
|     // ++*pw; | ||||
|  | ||||
|     _Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE); | ||||
| }  | ||||
|  | ||||
| inline int atomic_decrement( int * pw ) | ||||
| { | ||||
|     // return --*pw; | ||||
|  | ||||
|     int r = static_cast<int>(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE)); | ||||
|     if (1 == r) | ||||
|     { | ||||
|         _Asm_mf(); | ||||
|     } | ||||
|      | ||||
|     return r - 1; | ||||
| } | ||||
|  | ||||
| inline int atomic_conditional_increment( int * pw ) | ||||
| { | ||||
|     // if( *pw != 0 ) ++*pw; | ||||
|     // return *pw; | ||||
|  | ||||
|     int v = *pw; | ||||
|      | ||||
|     for (;;) | ||||
|     { | ||||
|         if (0 == v) | ||||
|         { | ||||
|             return 0; | ||||
|         } | ||||
|          | ||||
|         _Asm_mov_to_ar(_AREG_CCV, | ||||
|                        v, | ||||
|                        (_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE)); | ||||
|         int r = static_cast<int>(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE)); | ||||
|         if (r == v) | ||||
|         { | ||||
|             return r + 1; | ||||
|         } | ||||
|          | ||||
|         v = r; | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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_decrement( &use_count_ ) == 0 ) | ||||
|         { | ||||
|             dispose(); | ||||
|             weak_release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 0 ) | ||||
|         { | ||||
|             destroy(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     { | ||||
|         return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED | ||||
| @@ -1,152 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_aix.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 <builtins.h> | ||||
| #include <sys/atomic_op.h> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using AIX sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void atomic_increment( int32_t* pw ) | ||||
| { | ||||
|     // ++*pw; | ||||
|  | ||||
|     fetch_and_add( pw, 1 ); | ||||
| } | ||||
|  | ||||
| inline int32_t atomic_decrement( int32_t * pw ) | ||||
| { | ||||
|     // return --*pw; | ||||
|  | ||||
|     int32_t originalValue; | ||||
|  | ||||
|     __lwsync(); | ||||
|     originalValue = fetch_and_add( pw, -1 ); | ||||
|     __isync(); | ||||
|  | ||||
|     return (originalValue - 1); | ||||
| } | ||||
|  | ||||
| inline int32_t atomic_conditional_increment( int32_t * pw ) | ||||
| { | ||||
|     // if( *pw != 0 ) ++*pw; | ||||
|     // return *pw; | ||||
|  | ||||
|     int32_t tmp = fetch_and_add( pw, 0 ); | ||||
|     for( ;; ) | ||||
|     { | ||||
|         if( tmp == 0 ) return 0; | ||||
|         if( compare_and_swap( pw, &tmp, tmp + 1 ) ) return (tmp + 1); | ||||
|     } | ||||
| } | ||||
|  | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
|     sp_counted_base( sp_counted_base const & ); | ||||
|     sp_counted_base & operator= ( sp_counted_base const & ); | ||||
|  | ||||
|     int32_t use_count_;        // #shared | ||||
|     int32_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_ ) == 0 ) | ||||
|         { | ||||
|             dispose(); | ||||
|             weak_release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 0 ) | ||||
|         { | ||||
|             destroy(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     { | ||||
|         return fetch_and_add( const_cast<int32_t*>(&use_count_), 0 ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_AIX_HPP_INCLUDED | ||||
| @@ -1,185 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC | ||||
| // | ||||
| //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright 2004-2005 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) | ||||
| // | ||||
| // | ||||
| //  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/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using CodeWarrior/PowerPC sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void atomic_increment( register long * pw ) | ||||
| { | ||||
|     register int a; | ||||
|  | ||||
|     asm | ||||
|     { | ||||
| loop: | ||||
|  | ||||
|     lwarx   a, 0, pw | ||||
|     addi    a, a, 1 | ||||
|     stwcx.  a, 0, pw | ||||
|     bne-    loop | ||||
|     } | ||||
| } | ||||
|  | ||||
| inline long atomic_decrement( register long * pw ) | ||||
| { | ||||
|     register int a; | ||||
|  | ||||
|     asm | ||||
|     { | ||||
| #if defined(__PPCZen__) || defined(__PPCe500__) || defined(__PPCe500v2__) | ||||
|     msync | ||||
| #else | ||||
|     sync | ||||
| #endif | ||||
|  | ||||
| loop: | ||||
|  | ||||
|     lwarx   a, 0, pw | ||||
|     addi    a, a, -1 | ||||
|     stwcx.  a, 0, pw | ||||
|     bne-    loop | ||||
|  | ||||
|     isync | ||||
|     } | ||||
|  | ||||
|     return a; | ||||
| } | ||||
|  | ||||
| inline long atomic_conditional_increment( register long * pw ) | ||||
| { | ||||
|     register int a; | ||||
|  | ||||
|     asm | ||||
|     { | ||||
| loop: | ||||
|  | ||||
|     lwarx   a, 0, pw | ||||
|     cmpwi   a, 0 | ||||
|     beq     store | ||||
|  | ||||
|     addi    a, a, 1 | ||||
|  | ||||
| store: | ||||
|  | ||||
|     stwcx.  a, 0, pw | ||||
|     bne-    loop | ||||
|     } | ||||
|  | ||||
|     return a; | ||||
| } | ||||
|  | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
|     sp_counted_base( sp_counted_base const & ); | ||||
|     sp_counted_base & operator= ( sp_counted_base const & ); | ||||
|  | ||||
|     long use_count_;        // #shared | ||||
|     long 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_ ) == 0 ) | ||||
|         { | ||||
|             dispose(); | ||||
|             weak_release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     { | ||||
|         if( atomic_decrement( &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_CW_PPC_HPP_INCLUDED | ||||
| @@ -1,148 +0,0 @@ | ||||
| #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_gcc_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 <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 __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 static_cast<long>( atomic_load( &use_count_ ) ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED | ||||
| @@ -1,170 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64 | ||||
| // | ||||
| //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright 2004-2006 Peter Dimov | ||||
| //  Copyright 2005 Ben Hutchings | ||||
| // | ||||
| //  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 | ||||
| // | ||||
|  | ||||
| #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) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/IA64 sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void atomic_increment( int * pw ) | ||||
| { | ||||
|     // ++*pw; | ||||
|  | ||||
|     int tmp; | ||||
|  | ||||
|     // No barrier is required here but fetchadd always has an acquire or | ||||
|     // release barrier associated with it.  We choose release as it should be | ||||
|     // cheaper. | ||||
|     __asm__ ("fetchadd4.rel %0=%1,1" : | ||||
|          "=r"(tmp), "=m"(*pw) : | ||||
|          "m"( *pw )); | ||||
| } | ||||
|  | ||||
| inline int atomic_decrement( int * pw ) | ||||
| { | ||||
|     // return --*pw; | ||||
|  | ||||
|     int rv; | ||||
|  | ||||
|     __asm__ ("     fetchadd4.rel %0=%1,-1 ;; \n" | ||||
|              "     cmp.eq        p7,p0=1,%0 ;; \n" | ||||
|              "(p7) ld4.acq       %0=%1    " : | ||||
|              "=&r"(rv), "=m"(*pw) : | ||||
|              "m"( *pw ) : | ||||
|              "p7"); | ||||
|  | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| inline int atomic_conditional_increment( int * pw ) | ||||
| { | ||||
|     // if( *pw != 0 ) ++*pw; | ||||
|     // return *pw; | ||||
|  | ||||
|     int rv, tmp, tmp2; | ||||
|  | ||||
|     __asm__ ("0:   ld4          %0=%3           ;; \n" | ||||
|          "     cmp.eq       p7,p0=0,%0        ;; \n" | ||||
|          "(p7) br.cond.spnt 1f                \n" | ||||
|          "     mov          ar.ccv=%0         \n" | ||||
|          "     add          %1=1,%0           ;; \n" | ||||
|          "     cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n" | ||||
|          "     cmp.ne       p7,p0=%0,%2       ;; \n" | ||||
|          "(p7) br.cond.spnt 0b                \n" | ||||
|          "     mov          %0=%1             ;; \n" | ||||
|          "1:" :  | ||||
|          "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) : | ||||
|          "m"( *pw ) : | ||||
|          "ar.ccv", "p7"); | ||||
|  | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| 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_decrement( &use_count_ ) == 0 ) | ||||
|         { | ||||
|             dispose(); | ||||
|             weak_release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 0 ) | ||||
|         { | ||||
|             destroy(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     { | ||||
|         return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED | ||||
| @@ -1,200 +0,0 @@ | ||||
| #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED | ||||
| #define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS | ||||
| // | ||||
| //  Copyright (c) 2009, Spirent Communications, Inc. | ||||
| // | ||||
| //  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 | ||||
| // | ||||
|  | ||||
| #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) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/MIPS sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void atomic_increment( int * pw ) | ||||
| { | ||||
|     // ++*pw; | ||||
|  | ||||
|     int tmp; | ||||
|  | ||||
|     __asm__ __volatile__ | ||||
|     ( | ||||
|         "0:\n\t" | ||||
|         ".set push\n\t" | ||||
| #if !defined(__mips_isa_rev) || (__mips_isa_rev < 6) | ||||
|         ".set mips2\n\t" | ||||
| #endif | ||||
|         "ll %0, %1\n\t" | ||||
|         "addiu %0, 1\n\t" | ||||
|         "sc %0, %1\n\t" | ||||
|         ".set pop\n\t" | ||||
|         "beqz %0, 0b": | ||||
|         "=&r"( tmp ), "=m"( *pw ): | ||||
|         "m"( *pw ) | ||||
|     ); | ||||
| } | ||||
|  | ||||
| inline int atomic_decrement( int * pw ) | ||||
| { | ||||
|     // return --*pw; | ||||
|  | ||||
|     int rv, tmp; | ||||
|  | ||||
|     __asm__ __volatile__ | ||||
|     ( | ||||
|         "0:\n\t" | ||||
|         ".set push\n\t" | ||||
| #if !defined(__mips_isa_rev) || (__mips_isa_rev < 6) | ||||
|         ".set mips2\n\t" | ||||
| #endif | ||||
|         "ll %1, %2\n\t" | ||||
|         "addiu %0, %1, -1\n\t" | ||||
|         "sc %0, %2\n\t" | ||||
|         ".set pop\n\t" | ||||
|         "beqz %0, 0b\n\t" | ||||
|         "addiu %0, %1, -1": | ||||
|         "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ): | ||||
|         "m"( *pw ): | ||||
|         "memory" | ||||
|     ); | ||||
|  | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| inline int atomic_conditional_increment( int * pw ) | ||||
| { | ||||
|     // if( *pw != 0 ) ++*pw; | ||||
|     // return *pw; | ||||
|  | ||||
|     int rv, tmp; | ||||
|  | ||||
|     __asm__ __volatile__ | ||||
|     ( | ||||
|         "0:\n\t" | ||||
|         ".set push\n\t" | ||||
| #if !defined(__mips_isa_rev) || (__mips_isa_rev < 6) | ||||
|         ".set mips2\n\t" | ||||
| #endif | ||||
|         "ll %0, %2\n\t" | ||||
|         "beqz %0, 1f\n\t" | ||||
|         "addiu %1, %0, 1\n\t" | ||||
|         "sc %1, %2\n\t" | ||||
|         ".set pop\n\t" | ||||
|         "beqz %1, 0b\n\t" | ||||
|         "addiu %0, %0, 1\n\t" | ||||
|         "1:": | ||||
|         "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ): | ||||
|         "m"( *pw ): | ||||
|         "memory" | ||||
|     ); | ||||
|  | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| 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_decrement( &use_count_ ) == 0 ) | ||||
|         { | ||||
|             dispose(); | ||||
|             weak_release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 0 ) | ||||
|         { | ||||
|             destroy(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     { | ||||
|         return static_cast<int const volatile &>( use_count_ ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED | ||||
| @@ -1,194 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC | ||||
| // | ||||
| //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright 2004-2005 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) | ||||
| // | ||||
| // | ||||
| //  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/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/PowerPC sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void atomic_increment( int * pw ) | ||||
| { | ||||
|     // ++*pw; | ||||
|  | ||||
|     int tmp; | ||||
|  | ||||
|     __asm__ | ||||
|     ( | ||||
|         "0:\n\t" | ||||
|         "lwarx %1, 0, %2\n\t" | ||||
|         "addi %1, %1, 1\n\t" | ||||
|         "stwcx. %1, 0, %2\n\t" | ||||
|         "bne- 0b": | ||||
|  | ||||
|         "=m"( *pw ), "=&b"( tmp ): | ||||
|         "r"( pw ), "m"( *pw ): | ||||
|         "cc" | ||||
|     ); | ||||
| } | ||||
|  | ||||
| inline int atomic_decrement( int * pw ) | ||||
| { | ||||
|     // return --*pw; | ||||
|  | ||||
|     int rv; | ||||
|  | ||||
|     __asm__ __volatile__ | ||||
|     ( | ||||
|         "sync\n\t" | ||||
|         "0:\n\t" | ||||
|         "lwarx %1, 0, %2\n\t" | ||||
|         "addi %1, %1, -1\n\t" | ||||
|         "stwcx. %1, 0, %2\n\t" | ||||
|         "bne- 0b\n\t" | ||||
|         "isync": | ||||
|  | ||||
|         "=m"( *pw ), "=&b"( rv ): | ||||
|         "r"( pw ), "m"( *pw ): | ||||
|         "memory", "cc" | ||||
|     ); | ||||
|  | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| inline int atomic_conditional_increment( int * pw ) | ||||
| { | ||||
|     // if( *pw != 0 ) ++*pw; | ||||
|     // return *pw; | ||||
|  | ||||
|     int rv; | ||||
|  | ||||
|     __asm__ | ||||
|     ( | ||||
|         "0:\n\t" | ||||
|         "lwarx %1, 0, %2\n\t" | ||||
|         "cmpwi %1, 0\n\t" | ||||
|         "beq 1f\n\t" | ||||
|         "addi %1, %1, 1\n\t" | ||||
|         "1:\n\t" | ||||
|         "stwcx. %1, 0, %2\n\t" | ||||
|         "bne- 0b": | ||||
|  | ||||
|         "=m"( *pw ), "=&b"( rv ): | ||||
|         "r"( pw ), "m"( *pw ): | ||||
|         "cc" | ||||
|     ); | ||||
|  | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| 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_decrement( &use_count_ ) == 0 ) | ||||
|         { | ||||
|             dispose(); | ||||
|             weak_release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 0 ) | ||||
|         { | ||||
|             destroy(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     { | ||||
|         return static_cast<int const volatile &>( use_count_ ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED | ||||
| @@ -1,179 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| //  detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+ | ||||
| // | ||||
| //  Copyright (c) 2006 Piotr Wyderski | ||||
| //  Copyright (c) 2006 Tomas Puverle | ||||
| //  Copyright (c) 2006 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 | ||||
| // | ||||
| //  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 | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/Sparc sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ ) | ||||
| { | ||||
|     __asm__ __volatile__( "cas [%1], %2, %0" | ||||
|                         : "+r" (swap_) | ||||
|                         : "r" (dest_), "r" (compare_) | ||||
|                         : "memory" ); | ||||
|  | ||||
|     return swap_; | ||||
| } | ||||
|  | ||||
| inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv ) | ||||
| { | ||||
|     // long r = *pw; | ||||
|     // *pw += dv; | ||||
|     // return r; | ||||
|  | ||||
|     for( ;; ) | ||||
|     { | ||||
|         int32_t r = *pw; | ||||
|  | ||||
|         if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) ) | ||||
|         { | ||||
|             return r; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| inline void atomic_increment( int32_t * pw ) | ||||
| { | ||||
|     atomic_fetch_and_add( pw, 1 ); | ||||
| } | ||||
|  | ||||
| inline int32_t atomic_decrement( int32_t * pw ) | ||||
| { | ||||
|     return atomic_fetch_and_add( pw, -1 ); | ||||
| } | ||||
|  | ||||
| inline int32_t atomic_conditional_increment( int32_t * pw ) | ||||
| { | ||||
|     // long r = *pw; | ||||
|     // if( r != 0 ) ++*pw; | ||||
|     // return r; | ||||
|  | ||||
|     for( ;; ) | ||||
|     { | ||||
|         int32_t r = *pw; | ||||
|  | ||||
|         if( r == 0 ) | ||||
|         { | ||||
|             return r; | ||||
|         } | ||||
|  | ||||
|         if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) ) | ||||
|         { | ||||
|             return r; | ||||
|         } | ||||
|     }     | ||||
| } | ||||
|  | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
|     sp_counted_base( sp_counted_base const & ); | ||||
|     sp_counted_base & operator= ( sp_counted_base const & ); | ||||
|  | ||||
|     int32_t use_count_;        // #shared | ||||
|     int32_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 const_cast< int32_t const volatile & >( use_count_ ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED | ||||
| @@ -1,186 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64 | ||||
| // | ||||
| //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright 2004-2005 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) | ||||
| // | ||||
| // | ||||
| //  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/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/x86 sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline int atomic_exchange_and_add( int * pw, int dv ) | ||||
| { | ||||
|     // int r = *pw; | ||||
|     // *pw += dv; | ||||
|     // return r; | ||||
|  | ||||
|     int r; | ||||
|  | ||||
|     __asm__ __volatile__ | ||||
|     ( | ||||
|         "lock\n\t" | ||||
|         "xadd %1, %0": | ||||
|         "=m"( *pw ), "=r"( r ): // outputs (%0, %1) | ||||
|         "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1) | ||||
|         "memory", "cc" // clobbers | ||||
|     ); | ||||
|  | ||||
|     return r; | ||||
| } | ||||
|  | ||||
| inline void atomic_increment( int * pw ) | ||||
| { | ||||
|     //atomic_exchange_and_add( pw, 1 ); | ||||
|  | ||||
|     __asm__ | ||||
|     ( | ||||
|         "lock\n\t" | ||||
|         "incl %0": | ||||
|         "=m"( *pw ): // output (%0) | ||||
|         "m"( *pw ): // input (%1) | ||||
|         "cc" // clobbers | ||||
|     ); | ||||
| } | ||||
|  | ||||
| inline int atomic_conditional_increment( int * pw ) | ||||
| { | ||||
|     // int rv = *pw; | ||||
|     // if( rv != 0 ) ++*pw; | ||||
|     // return rv; | ||||
|  | ||||
|     int rv, tmp; | ||||
|  | ||||
|     __asm__ | ||||
|     ( | ||||
|         "movl %0, %%eax\n\t" | ||||
|         "0:\n\t" | ||||
|         "test %%eax, %%eax\n\t" | ||||
|         "je 1f\n\t" | ||||
|         "movl %%eax, %2\n\t" | ||||
|         "incl %2\n\t" | ||||
|         "lock\n\t" | ||||
|         "cmpxchgl %2, %0\n\t" | ||||
|         "jne 0b\n\t" | ||||
|         "1:": | ||||
|         "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2) | ||||
|         "m"( *pw ): // input (%3) | ||||
|         "cc" // clobbers | ||||
|     ); | ||||
|  | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| 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<int const volatile &>( use_count_ ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED | ||||
| @@ -20,7 +20,7 @@ | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/cstdint.hpp> | ||||
| #include <cstdint> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| @@ -42,8 +42,8 @@ private: | ||||
|     sp_counted_base( sp_counted_base const & ); | ||||
|     sp_counted_base & operator= ( sp_counted_base const & ); | ||||
|  | ||||
|     boost::int_least32_t use_count_;        // #shared | ||||
|     boost::int_least32_t weak_count_;       // #weak + (#shared != 0) | ||||
|     std::int_least32_t use_count_;        // #shared | ||||
|     std::int_least32_t weak_count_;       // #weak + (#shared != 0) | ||||
|  | ||||
| public: | ||||
|  | ||||
|   | ||||
| @@ -1,147 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_pt.hpp | ||||
| // | ||||
| //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright 2004-2005 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/assert.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/cstdint.hpp> | ||||
| #include <pthread.h> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using pthread_mutex 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 & ); | ||||
|  | ||||
|     boost::int_least32_t use_count_;        // #shared | ||||
|     boost::int_least32_t weak_count_;       // #weak + (#shared != 0) | ||||
|  | ||||
|     mutable pthread_mutex_t m_; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) | ||||
|     { | ||||
| // HPUX 10.20 / DCE has a nonstandard pthread_mutex_init | ||||
|  | ||||
| #if defined(__hpux) && defined(_DECTHREADS_) | ||||
|         BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 ); | ||||
| #else | ||||
|         BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 ); | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     virtual ~sp_counted_base() // nothrow | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 ); | ||||
|     } | ||||
|  | ||||
|     // 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() | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         ++use_count_; | ||||
|         BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|     } | ||||
|  | ||||
|     bool add_ref_lock() // true on success | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         bool r = use_count_ == 0? false: ( ++use_count_, true ); | ||||
|         BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|         return r; | ||||
|     } | ||||
|  | ||||
|     void release() // nothrow | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         boost::int_least32_t new_use_count = --use_count_; | ||||
|         BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|  | ||||
|         if( new_use_count == 0 ) | ||||
|         { | ||||
|             dispose(); | ||||
|             weak_release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         ++weak_count_; | ||||
|         BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         boost::int_least32_t new_weak_count = --weak_count_; | ||||
|         BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|  | ||||
|         if( new_weak_count == 0 ) | ||||
|         { | ||||
|             destroy(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     { | ||||
|         BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); | ||||
|         boost::int_least32_t r = use_count_; | ||||
|         BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); | ||||
|  | ||||
|         return r; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED | ||||
| @@ -1,174 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| //  detail/sp_counted_base_gcc_snc_ps3.hpp - PS3 Cell | ||||
| // | ||||
| //  Copyright (c) 2006 Piotr Wyderski | ||||
| //  Copyright (c) 2006 Tomas Puverle | ||||
| //  Copyright (c) 2006 Peter Dimov | ||||
| //  Copyright (c) 2011 Emil Dotchevski | ||||
| // | ||||
| //  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 | ||||
| // | ||||
| //  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 | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using PS3 sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| BOOST_SP_OBSOLETE() | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline uint32_t compare_and_swap( uint32_t * dest_, uint32_t compare_, uint32_t swap_ ) | ||||
| { | ||||
|     return __builtin_cellAtomicCompareAndSwap32(dest_,compare_,swap_); | ||||
| } | ||||
|  | ||||
| inline uint32_t atomic_fetch_and_add( uint32_t * pw, uint32_t dv ) | ||||
| { | ||||
|     // long r = *pw; | ||||
|     // *pw += dv; | ||||
|     // return r; | ||||
|  | ||||
|     for( ;; ) | ||||
|     { | ||||
|         uint32_t r = *pw; | ||||
|  | ||||
|         if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) ) | ||||
|         { | ||||
|             return r; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| inline void atomic_increment( uint32_t * pw ) | ||||
| { | ||||
|     (void) __builtin_cellAtomicIncr32( pw ); | ||||
| } | ||||
|  | ||||
| inline uint32_t atomic_decrement( uint32_t * pw ) | ||||
| { | ||||
|     return __builtin_cellAtomicDecr32( pw ); | ||||
| } | ||||
|  | ||||
| inline uint32_t atomic_conditional_increment( uint32_t * pw ) | ||||
| { | ||||
|     // long r = *pw; | ||||
|     // if( r != 0 ) ++*pw; | ||||
|     // return r; | ||||
|  | ||||
|     for( ;; ) | ||||
|     { | ||||
|         uint32_t r = *pw; | ||||
|  | ||||
|         if( r == 0 ) | ||||
|         { | ||||
|             return r; | ||||
|         } | ||||
|  | ||||
|         if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) ) | ||||
|         { | ||||
|             return r; | ||||
|         } | ||||
|     }     | ||||
| } | ||||
|  | ||||
| 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_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 const_cast< uint32_t const volatile & >( use_count_ ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SNC_PS3_HPP_INCLUDED | ||||
| @@ -1,141 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation | ||||
| // | ||||
| //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright 2004-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 <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/smart_ptr/detail/spinlock_pool.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using spinlock-based sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline int atomic_exchange_and_add( int * pw, int dv ) | ||||
| { | ||||
|     spinlock_pool<1>::scoped_lock lock( pw ); | ||||
|  | ||||
|     int r = *pw; | ||||
|     *pw += dv; | ||||
|     return r; | ||||
| } | ||||
|  | ||||
| inline void atomic_increment( int * pw ) | ||||
| { | ||||
|     spinlock_pool<1>::scoped_lock lock( pw ); | ||||
|     ++*pw; | ||||
| } | ||||
|  | ||||
| inline int atomic_conditional_increment( int * pw ) | ||||
| { | ||||
|     spinlock_pool<1>::scoped_lock lock( pw ); | ||||
|  | ||||
|     int rv = *pw; | ||||
|     if( rv != 0 ) ++*pw; | ||||
|     return rv; | ||||
| } | ||||
|  | ||||
| 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 | ||||
|     { | ||||
|         spinlock_pool<1>::scoped_lock lock( &use_count_ ); | ||||
|         return use_count_; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED | ||||
| @@ -1,165 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| //  detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics | ||||
| // | ||||
| //  Copyright (c) 2007 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/config.hpp> | ||||
| #include <limits.h> | ||||
|  | ||||
| #if defined( __ia64__ ) && defined( __INTEL_COMPILER ) | ||||
| # include <ia64intrin.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using __sync sp_counted_base") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| #if INT_MAX >= 2147483647 | ||||
|  | ||||
| typedef int sp_int32_t; | ||||
|  | ||||
| #else | ||||
|  | ||||
| typedef long sp_int32_t; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| inline void atomic_increment( sp_int32_t * pw ) | ||||
| { | ||||
|     __sync_fetch_and_add( pw, 1 ); | ||||
| } | ||||
|  | ||||
| inline sp_int32_t atomic_decrement( sp_int32_t * pw ) | ||||
| { | ||||
|     return __sync_fetch_and_add( pw, -1 ); | ||||
| } | ||||
|  | ||||
| inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw ) | ||||
| { | ||||
|     // long r = *pw; | ||||
|     // if( r != 0 ) ++*pw; | ||||
|     // return r; | ||||
|  | ||||
|     sp_int32_t r = *pw; | ||||
|  | ||||
|     for( ;; ) | ||||
|     { | ||||
|         if( r == 0 ) | ||||
|         { | ||||
|             return r; | ||||
|         } | ||||
|  | ||||
|         sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 ); | ||||
|  | ||||
|         if( r2 == r ) | ||||
|         { | ||||
|             return r; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             r = r2; | ||||
|         } | ||||
|     }     | ||||
| } | ||||
|  | ||||
| class BOOST_SYMBOL_VISIBLE sp_counted_base | ||||
| { | ||||
| private: | ||||
|  | ||||
|     sp_counted_base( sp_counted_base const & ); | ||||
|     sp_counted_base & operator= ( sp_counted_base const & ); | ||||
|  | ||||
|     sp_int32_t use_count_;        // #shared | ||||
|     sp_int32_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 const_cast< sp_int32_t const volatile & >( use_count_ ); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED | ||||
| @@ -1,163 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER | ||||
| //   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 | ||||
| //  Copyright 2012 IBM Corp. | ||||
| // | ||||
| //  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/smart_ptr/detail/sp_obsolete.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| 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); | ||||
| extern "builtin" int __compare_and_swap(volatile int*, int*, int); | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| inline void atomic_increment( int *pw ) | ||||
| { | ||||
|    // ++*pw; | ||||
|    __lwsync(); | ||||
|    __fetch_and_add(pw, 1); | ||||
|    __isync(); | ||||
| }  | ||||
|  | ||||
| inline int atomic_decrement( int *pw ) | ||||
| { | ||||
|    // return --*pw; | ||||
|    __lwsync(); | ||||
|    int originalValue = __fetch_and_add(pw, -1); | ||||
|    __isync(); | ||||
|  | ||||
|    return (originalValue - 1); | ||||
| } | ||||
|  | ||||
| inline int atomic_conditional_increment( int *pw ) | ||||
| { | ||||
|    // if( *pw != 0 ) ++*pw; | ||||
|    // return *pw; | ||||
|  | ||||
|    __lwsync(); | ||||
|    int v = *const_cast<volatile int*>(pw); | ||||
|    for (;;) | ||||
|    // loop until state is known | ||||
|    { | ||||
|       if (v == 0) return 0; | ||||
|       if (__compare_and_swap(pw, &v, v + 1)) | ||||
|       { | ||||
|          __isync(); return (v + 1); | ||||
|       } | ||||
|    } | ||||
| } | ||||
|  | ||||
| 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) | ||||
|     char pad[64] __attribute__((__aligned__(64))); | ||||
|             // pad to prevent false sharing | ||||
| 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_ ) == 0 ) | ||||
|         { | ||||
|             dispose(); | ||||
|             weak_release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     { | ||||
|         atomic_increment( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     { | ||||
|         if( atomic_decrement( &weak_count_ ) == 0 ) | ||||
|         { | ||||
|             destroy(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     long use_count() const // nothrow | ||||
|     { | ||||
|         return *const_cast<volatile int*>(&use_count_);  | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED | ||||
| @@ -1,129 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  detail/sp_counted_base_w32.hpp | ||||
| // | ||||
| //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. | ||||
| //  Copyright 2004-2005 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) | ||||
| // | ||||
| // | ||||
| //  Lock-free algorithm by Alexander Terekhov | ||||
| // | ||||
| //  Thanks to Ben Hitchings for the #weak + (#shared != 0) | ||||
| //  formulation | ||||
| // | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_interlocked.hpp> | ||||
| #include <boost/smart_ptr/detail/sp_typeinfo_.hpp> | ||||
| #include <boost/config/workaround.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using Win32 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 & ); | ||||
|  | ||||
|     long use_count_;        // #shared | ||||
|     long 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() | ||||
|     { | ||||
|         BOOST_SP_INTERLOCKED_INCREMENT( &use_count_ ); | ||||
|     } | ||||
|  | ||||
|     bool add_ref_lock() // true on success | ||||
|     { | ||||
|         for( ;; ) | ||||
|         { | ||||
|             long tmp = static_cast< long const volatile& >( use_count_ ); | ||||
|             if( tmp == 0 ) return false; | ||||
|  | ||||
|             if( BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void release() // nothrow | ||||
|     { | ||||
|         if( BOOST_SP_INTERLOCKED_DECREMENT( &use_count_ ) == 0 ) | ||||
|         { | ||||
|             dispose(); | ||||
|             weak_release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void weak_add_ref() // nothrow | ||||
|     { | ||||
|         BOOST_SP_INTERLOCKED_INCREMENT( &weak_count_ ); | ||||
|     } | ||||
|  | ||||
|     void weak_release() // nothrow | ||||
|     { | ||||
|         if( BOOST_SP_INTERLOCKED_DECREMENT( &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_W32_HPP_INCLUDED | ||||
| @@ -1,30 +0,0 @@ | ||||
| #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. | ||||
|  | ||||
| // Libraries (e.g. Kokkos) sometimes define the __ATOMIC_RELAXED macros, | ||||
| // leading to errors under MSVC (https://github.com/boostorg/smart_ptr/pull/112) | ||||
|  | ||||
| #if defined( __ATOMIC_RELAXED ) && defined( __ATOMIC_ACQUIRE ) && defined( __ATOMIC_RELEASE ) && defined( __ATOMIC_ACQ_REL ) \ | ||||
|     && !( defined(_MSC_VER) && !defined(__clang__) ) | ||||
|  | ||||
| # define BOOST_SP_HAS_GCC_INTRINSICS | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_GCC_INTRINSICS_HPP_INCLUDED | ||||
| @@ -1,69 +0,0 @@ | ||||
| #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 | ||||
| @@ -1,173 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED | ||||
|  | ||||
| // MS compatible compilers support #pragma once | ||||
|  | ||||
| #if defined(_MSC_VER) && (_MSC_VER >= 1020) | ||||
| # pragma once | ||||
| #endif | ||||
|  | ||||
| // | ||||
| //  boost/detail/sp_interlocked.hpp | ||||
| // | ||||
| //  Copyright 2005, 2014 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/config.hpp> | ||||
|  | ||||
| // BOOST_SP_HAS_INTRIN_H | ||||
|  | ||||
| // VC9 has intrin.h, but it collides with <utility> | ||||
| #if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600 | ||||
|  | ||||
| # define BOOST_SP_HAS_INTRIN_H | ||||
|  | ||||
| // Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets. | ||||
| #elif defined( __MINGW64_VERSION_MAJOR ) | ||||
|  | ||||
| // MinGW-w64 provides intrin.h for both 32 and 64-bit targets. | ||||
| # define BOOST_SP_HAS_INTRIN_H | ||||
|  | ||||
| #elif defined( __LP64__ ) | ||||
|  | ||||
| // We have to use intrin.h on Cygwin 64 | ||||
| # define BOOST_SP_HAS_INTRIN_H | ||||
|  | ||||
| // Intel C++ on Windows on VC10+ stdlib | ||||
| #elif defined( BOOST_INTEL_WIN ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520 | ||||
|  | ||||
| # define BOOST_SP_HAS_INTRIN_H | ||||
|  | ||||
| // clang-cl on Windows on VC10+ stdlib | ||||
| #elif defined( __clang__ ) && defined( _MSC_VER ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520 | ||||
|  | ||||
| # define BOOST_SP_HAS_INTRIN_H | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined( BOOST_USE_WINDOWS_H ) | ||||
|  | ||||
| # include <windows.h> | ||||
|  | ||||
| # define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement | ||||
| # define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement | ||||
| # define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd | ||||
|  | ||||
| #elif defined( BOOST_USE_INTRIN_H ) || defined( BOOST_SP_HAS_INTRIN_H ) | ||||
|  | ||||
| #include <intrin.h> | ||||
|  | ||||
| # define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement | ||||
| # define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement | ||||
| # define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd | ||||
|  | ||||
| #elif defined( _WIN32_WCE ) | ||||
|  | ||||
| #if _WIN32_WCE >= 0x600 | ||||
|  | ||||
| extern "C" long __cdecl _InterlockedIncrement( long volatile * ); | ||||
| extern "C" long __cdecl _InterlockedDecrement( long volatile * ); | ||||
| extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); | ||||
| extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); | ||||
| extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); | ||||
|  | ||||
| # define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement | ||||
| # define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement | ||||
| # define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd | ||||
|  | ||||
| #else | ||||
|  | ||||
| // under Windows CE we still have old-style Interlocked* functions | ||||
|  | ||||
| extern "C" long __cdecl InterlockedIncrement( long* ); | ||||
| extern "C" long __cdecl InterlockedDecrement( long* ); | ||||
| extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); | ||||
| extern "C" long __cdecl InterlockedExchange( long*, long ); | ||||
| extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); | ||||
|  | ||||
| # define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement | ||||
| # define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement | ||||
| # define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) | ||||
|  | ||||
| #if defined( __CLRCALL_PURE_OR_CDECL ) | ||||
|  | ||||
| extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * ); | ||||
| extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * ); | ||||
| extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long ); | ||||
| extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long ); | ||||
| extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long ); | ||||
|  | ||||
| #else | ||||
|  | ||||
| extern "C" long __cdecl _InterlockedIncrement( long volatile * ); | ||||
| extern "C" long __cdecl _InterlockedDecrement( long volatile * ); | ||||
| extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); | ||||
| extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); | ||||
| extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); | ||||
|  | ||||
| # if defined( BOOST_MSVC ) && BOOST_MSVC == 1310 | ||||
| //From MSDN, Visual Studio .NET 2003 spedific: To declare one of the interlocked functions | ||||
| //for use as an intrinsic, the function must be declared with the leading underscore and | ||||
| //the new function must appear in a #pragma intrinsic statement. | ||||
| #  pragma intrinsic( _InterlockedIncrement ) | ||||
| #  pragma intrinsic( _InterlockedDecrement ) | ||||
| #  pragma intrinsic( _InterlockedCompareExchange ) | ||||
| #  pragma intrinsic( _InterlockedExchange ) | ||||
| #  pragma intrinsic( _InterlockedExchangeAdd ) | ||||
| # endif | ||||
|  | ||||
| #endif | ||||
|  | ||||
| # define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement | ||||
| # define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement | ||||
| # define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd | ||||
|  | ||||
| #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * ); | ||||
| extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); | ||||
| extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); | ||||
| extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); | ||||
| extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long ); | ||||
|  | ||||
| } // namespace detail | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| # define BOOST_SP_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement | ||||
| # define BOOST_SP_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement | ||||
| # define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange | ||||
| # define BOOST_SP_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd | ||||
|  | ||||
| #else | ||||
|  | ||||
| # error "Interlocked intrinsics not available" | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED | ||||
| @@ -1,32 +0,0 @@ | ||||
| #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 | ||||
| @@ -28,40 +28,7 @@ | ||||
| //  #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/smart_ptr/detail/deprecated_macros.hpp> | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| #if defined( BOOST_SP_USE_STD_ATOMIC ) | ||||
| #  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_INTRINSICS ) | ||||
| #  include <boost/smart_ptr/detail/spinlock_sync.hpp> | ||||
|  | ||||
| #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) | ||||
| #  include <boost/smart_ptr/detail/spinlock_w32.hpp> | ||||
|  | ||||
| #elif defined(BOOST_HAS_PTHREADS) | ||||
| #  include <boost/smart_ptr/detail/spinlock_pt.hpp> | ||||
|  | ||||
| #elif !defined(BOOST_HAS_THREADS) | ||||
| #  include <boost/smart_ptr/detail/spinlock_nt.hpp> | ||||
|  | ||||
| #else | ||||
| #  error Unrecognized threading platform | ||||
| #endif | ||||
| #include <boost/smart_ptr/detail/spinlock_std_atomic.hpp> | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED | ||||
|   | ||||
| @@ -1,128 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED | ||||
|  | ||||
| // | ||||
| //  Copyright (c) 2008, 2011 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/yield_k.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using g++/ARM spinlock") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__) | ||||
|  | ||||
| # define BOOST_SP_ARM_BARRIER "dmb" | ||||
| # define BOOST_SP_ARM_HAS_LDREX | ||||
|  | ||||
| #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) | ||||
|  | ||||
| # define BOOST_SP_ARM_BARRIER "mcr p15, 0, r0, c7, c10, 5" | ||||
| # define BOOST_SP_ARM_HAS_LDREX | ||||
|  | ||||
| #else | ||||
|  | ||||
| # define BOOST_SP_ARM_BARRIER "" | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class spinlock | ||||
| { | ||||
| public: | ||||
|  | ||||
|     int v_; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     bool try_lock() | ||||
|     { | ||||
|         int r; | ||||
|  | ||||
| #ifdef BOOST_SP_ARM_HAS_LDREX | ||||
|  | ||||
|         __asm__ __volatile__( | ||||
|             "ldrex %0, [%2]; \n" | ||||
|             "cmp %0, %1; \n" | ||||
|             "strexne %0, %1, [%2]; \n" | ||||
|             BOOST_SP_ARM_BARRIER : | ||||
|             "=&r"( r ): // outputs | ||||
|             "r"( 1 ), "r"( &v_ ): // inputs | ||||
|             "memory", "cc" ); | ||||
|  | ||||
| #else | ||||
|  | ||||
|         __asm__ __volatile__( | ||||
|             "swp %0, %1, [%2];\n" | ||||
|             BOOST_SP_ARM_BARRIER : | ||||
|             "=&r"( r ): // outputs | ||||
|             "r"( 1 ), "r"( &v_ ): // inputs | ||||
|             "memory", "cc" ); | ||||
|  | ||||
| #endif | ||||
|  | ||||
|         return r == 0; | ||||
|     } | ||||
|  | ||||
|     void lock() | ||||
|     { | ||||
|         for( unsigned k = 0; !try_lock(); ++k ) | ||||
|         { | ||||
|             boost::detail::yield( k ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void unlock() | ||||
|     { | ||||
|         __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" ); | ||||
|         *const_cast< int volatile* >( &v_ ) = 0; | ||||
|         __asm__ __volatile__( BOOST_SP_ARM_BARRIER ::: "memory" ); | ||||
|     } | ||||
|  | ||||
| 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} | ||||
|  | ||||
| #undef BOOST_SP_ARM_BARRIER | ||||
| #undef BOOST_SP_ARM_HAS_LDREX | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED | ||||
| @@ -1,94 +0,0 @@ | ||||
| #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: | ||||
|  | ||||
|     // `bool` alignment is required for Apple PPC32 | ||||
|     // https://github.com/boostorg/smart_ptr/issues/105 | ||||
|     // https://github.com/PurpleI2P/i2pd/issues/1726 | ||||
|     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107590 | ||||
|  | ||||
|     union | ||||
|     { | ||||
|         unsigned char v_; | ||||
|         bool align_; | ||||
|     }; | ||||
|  | ||||
| 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 | ||||
| @@ -1,96 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_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 <boost/assert.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using single-threaded spinlock emulation") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class spinlock | ||||
| { | ||||
| public: | ||||
|  | ||||
|     bool locked_; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     inline bool try_lock() | ||||
|     { | ||||
|         if( locked_ ) | ||||
|         { | ||||
|             return false; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             locked_ = true; | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     inline void lock() | ||||
|     { | ||||
|         BOOST_ASSERT( !locked_ ); | ||||
|         locked_ = true; | ||||
|     } | ||||
|  | ||||
|     inline void unlock() | ||||
|     { | ||||
|         BOOST_ASSERT( locked_ ); | ||||
|         locked_ = false; | ||||
|     } | ||||
|  | ||||
| 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 { false } | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED | ||||
| @@ -1,86 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_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 <pthread.h> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using pthread_mutex spinlock emulation") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class spinlock | ||||
| { | ||||
| public: | ||||
|  | ||||
|     pthread_mutex_t v_; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     bool try_lock() | ||||
|     { | ||||
|         return pthread_mutex_trylock( &v_ ) == 0; | ||||
|     } | ||||
|  | ||||
|     void lock() | ||||
|     { | ||||
|         pthread_mutex_lock( &v_ ); | ||||
|     } | ||||
|  | ||||
|     void unlock() | ||||
|     { | ||||
|         pthread_mutex_unlock( &v_ ); | ||||
|     } | ||||
|  | ||||
| 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 { PTHREAD_MUTEX_INITIALIZER } | ||||
|  | ||||
| #endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED | ||||
| @@ -1,94 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_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 <boost/smart_ptr/detail/yield_k.hpp> | ||||
|  | ||||
| #if defined( __ia64__ ) && defined( __INTEL_COMPILER ) | ||||
| # include <ia64intrin.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using __sync spinlock") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class spinlock | ||||
| { | ||||
| public: | ||||
|  | ||||
|     unsigned char v_; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     bool try_lock() | ||||
|     { | ||||
|         int r = __sync_lock_test_and_set( &v_, 1 ); | ||||
|         return r == 0; | ||||
|     } | ||||
|  | ||||
|     void lock() | ||||
|     { | ||||
|         for( unsigned k = 0; !try_lock(); ++k ) | ||||
|         { | ||||
|             boost::detail::yield( k ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void unlock() | ||||
|     { | ||||
|         __sync_lock_release( &v_ ); | ||||
|     } | ||||
|  | ||||
| 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_SYNC_HPP_INCLUDED | ||||
| @@ -1,120 +0,0 @@ | ||||
| #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED | ||||
| #define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_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 <boost/smart_ptr/detail/sp_interlocked.hpp> | ||||
| #include <boost/smart_ptr/detail/yield_k.hpp> | ||||
|  | ||||
| #if defined(BOOST_SP_REPORT_IMPLEMENTATION) | ||||
|  | ||||
| #include <boost/config/pragma_message.hpp> | ||||
| BOOST_PRAGMA_MESSAGE("Using Win32 spinlock") | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // BOOST_COMPILER_FENCE | ||||
|  | ||||
| #if defined(__INTEL_COMPILER) | ||||
|  | ||||
| #define BOOST_COMPILER_FENCE __memory_barrier(); | ||||
|  | ||||
| #elif defined( _MSC_VER ) && _MSC_VER >= 1310 | ||||
|  | ||||
| extern "C" void _ReadWriteBarrier(); | ||||
| #pragma intrinsic( _ReadWriteBarrier ) | ||||
|  | ||||
| #define BOOST_COMPILER_FENCE _ReadWriteBarrier(); | ||||
|  | ||||
| #elif defined(__GNUC__) | ||||
|  | ||||
| #define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" ); | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define BOOST_COMPILER_FENCE | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // | ||||
|  | ||||
| namespace boost | ||||
| { | ||||
|  | ||||
| namespace detail | ||||
| { | ||||
|  | ||||
| class spinlock | ||||
| { | ||||
| public: | ||||
|  | ||||
|     long v_; | ||||
|  | ||||
| public: | ||||
|  | ||||
|     bool try_lock() | ||||
|     { | ||||
|         long r = BOOST_SP_INTERLOCKED_EXCHANGE( &v_, 1 ); | ||||
|  | ||||
|         BOOST_COMPILER_FENCE | ||||
|  | ||||
|         return r == 0; | ||||
|     } | ||||
|  | ||||
|     void lock() | ||||
|     { | ||||
|         for( unsigned k = 0; !try_lock(); ++k ) | ||||
|         { | ||||
|             boost::detail::yield( k ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void unlock() | ||||
|     { | ||||
|         BOOST_COMPILER_FENCE | ||||
|         *const_cast< long volatile* >( &v_ ) = 0; | ||||
|     } | ||||
|  | ||||
| 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_W32_HPP_INCLUDED | ||||
| @@ -117,7 +117,6 @@ run shared_ptr_alloc11_test.cpp ; | ||||
| run shared_ptr_alloc_construct11_test.cpp ; | ||||
| run allocate_shared_alloc11_test.cpp ; | ||||
| run allocate_shared_construct11_test.cpp ; | ||||
| run sp_interlocked_test.cpp ; | ||||
|  | ||||
| compile-fail array_fail_spa_sp_c.cpp ; | ||||
| compile-fail array_fail_sp_spa_c.cpp ; | ||||
| @@ -239,8 +238,6 @@ run sp_nothrow_test.cpp ; | ||||
|  | ||||
| compile make_shared_msvc_test.cpp ; | ||||
|  | ||||
| compile lwm_win32_cs_test.cpp ; | ||||
|  | ||||
| run atomic_sp_test.cpp ; | ||||
|  | ||||
| run sp_constexpr_test.cpp ; | ||||
|   | ||||
| @@ -1,18 +0,0 @@ | ||||
| // | ||||
| // lwm_win32_cs_test.cpp | ||||
| // | ||||
| // Copyright 2017 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) | ||||
| // | ||||
|  | ||||
| #if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) | ||||
| # include <windows.h> | ||||
| # include <boost/smart_ptr/detail/lwm_win32_cs.hpp> | ||||
| #endif | ||||
|  | ||||
| int main() | ||||
| { | ||||
| } | ||||
| @@ -1,71 +0,0 @@ | ||||
| // | ||||
| //  sp_interlocked_test.cpp | ||||
| // | ||||
| //  Copyright 2014 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 | ||||
| // | ||||
|  | ||||
| #if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) | ||||
|  | ||||
| #include <boost/smart_ptr/detail/sp_interlocked.hpp> | ||||
| #include <boost/core/lightweight_test.hpp> | ||||
|  | ||||
| #ifndef __LP64__ | ||||
|  | ||||
| typedef long long_type; | ||||
|  | ||||
| #else | ||||
|  | ||||
| // On Cygwin 64, long is 64 bit | ||||
| typedef int long_type; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     long_type x = 0, r; | ||||
|  | ||||
|     r = BOOST_SP_INTERLOCKED_INCREMENT( &x ); | ||||
|  | ||||
|     BOOST_TEST( x == 1 ); | ||||
|     BOOST_TEST( r == 1 ); | ||||
|  | ||||
|     r = BOOST_SP_INTERLOCKED_DECREMENT( &x ); | ||||
|  | ||||
|     BOOST_TEST( x == 0 ); | ||||
|     BOOST_TEST( r == 0 ); | ||||
|  | ||||
|     r = BOOST_SP_INTERLOCKED_EXCHANGE( &x, 3 ); | ||||
|  | ||||
|     BOOST_TEST( x == 3 ); | ||||
|     BOOST_TEST( r == 0 ); | ||||
|  | ||||
|     r = BOOST_SP_INTERLOCKED_EXCHANGE_ADD( &x, 2 ); | ||||
|  | ||||
|     BOOST_TEST( x == 5 ); | ||||
|     BOOST_TEST( r == 3 ); | ||||
|  | ||||
|     r = BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &x, 0, 3 ); | ||||
|  | ||||
|     BOOST_TEST( x == 5 ); | ||||
|     BOOST_TEST( r == 5 ); | ||||
|  | ||||
|     r = BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &x, 0, 5 ); | ||||
|  | ||||
|     BOOST_TEST( x == 0 ); | ||||
|     BOOST_TEST( r == 5 ); | ||||
|  | ||||
|     return boost::report_errors(); | ||||
| } | ||||
|  | ||||
| #else | ||||
|  | ||||
| int main() | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user