Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:51:42

0001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_ATOMIC_HPP_INCLUDED
0003 
0004 // MS compatible compilers support #pragma once
0005 
0006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0007 # pragma once
0008 #endif
0009 
0010 // detail/sp_counted_base_gcc_atomic.hpp - g++ 4.7+ __atomic intrinsics
0011 //
0012 // Copyright 2007, 2020 Peter Dimov
0013 // Distributed under the Boost Software License, Version 1.0.
0014 // https://www.boost.org/LICENSE_1_0.txt
0015 
0016 #include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
0017 #include <boost/config.hpp>
0018 #include <boost/cstdint.hpp>
0019 
0020 #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
0021 
0022 #include <boost/config/pragma_message.hpp>
0023 BOOST_PRAGMA_MESSAGE("Using __atomic sp_counted_base")
0024 
0025 #endif
0026 
0027 namespace boost
0028 {
0029 
0030 namespace detail
0031 {
0032 
0033 inline void atomic_increment( boost::uint_least32_t * pw )
0034 {
0035     __atomic_fetch_add( pw, 1, __ATOMIC_RELAXED );
0036 }
0037 
0038 inline boost::uint_least32_t atomic_decrement( boost::uint_least32_t * pw )
0039 {
0040     return __atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL );
0041 }
0042 
0043 inline boost::uint_least32_t atomic_conditional_increment( boost::uint_least32_t * pw )
0044 {
0045     // long r = *pw;
0046     // if( r != 0 ) ++*pw;
0047     // return r;
0048 
0049     boost::uint_least32_t r = __atomic_load_n( pw, __ATOMIC_RELAXED );
0050 
0051     for( ;; )
0052     {
0053         if( r == 0 )
0054         {
0055             return r;
0056         }
0057 
0058         if( __atomic_compare_exchange_n( pw, &r, r + 1, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) )
0059         {
0060             return r;
0061         }
0062     }
0063 }
0064 
0065 inline boost::uint_least32_t atomic_load( boost::uint_least32_t const * pw )
0066 {
0067     return __atomic_load_n( pw, __ATOMIC_ACQUIRE );
0068 }
0069 
0070 class BOOST_SYMBOL_VISIBLE sp_counted_base
0071 {
0072 private:
0073 
0074     sp_counted_base( sp_counted_base const & );
0075     sp_counted_base & operator= ( sp_counted_base const & );
0076 
0077     boost::uint_least32_t use_count_;        // #shared
0078     boost::uint_least32_t weak_count_;       // #weak + (#shared != 0)
0079 
0080 public:
0081 
0082     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
0083     {
0084     }
0085 
0086     virtual ~sp_counted_base() // nothrow
0087     {
0088     }
0089 
0090     // dispose() is called when use_count_ drops to zero, to release
0091     // the resources managed by *this.
0092 
0093     virtual void dispose() = 0; // nothrow
0094 
0095     // destroy() is called when weak_count_ drops to zero.
0096 
0097     virtual void destroy() // nothrow
0098     {
0099         delete this;
0100     }
0101 
0102     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
0103     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
0104     virtual void * get_untyped_deleter() = 0;
0105 
0106     void add_ref_copy()
0107     {
0108         atomic_increment( &use_count_ );
0109     }
0110 
0111     bool add_ref_lock() // true on success
0112     {
0113         return atomic_conditional_increment( &use_count_ ) != 0;
0114     }
0115 
0116     void release() // nothrow
0117     {
0118         if( atomic_decrement( &use_count_ ) == 1 )
0119         {
0120             dispose();
0121             weak_release();
0122         }
0123     }
0124 
0125     void weak_add_ref() // nothrow
0126     {
0127         atomic_increment( &weak_count_ );
0128     }
0129 
0130     void weak_release() // nothrow
0131     {
0132         if( atomic_decrement( &weak_count_ ) == 1 )
0133         {
0134             destroy();
0135         }
0136     }
0137 
0138     long use_count() const // nothrow
0139     {
0140         return static_cast<long>( atomic_load( &use_count_ ) );
0141     }
0142 };
0143 
0144 } // namespace detail
0145 
0146 } // namespace boost
0147 
0148 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED