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_PPC_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_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 //
0011 //  detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC
0012 //
0013 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
0014 //  Copyright 2004-2005 Peter Dimov
0015 //
0016 //  Distributed under the Boost Software License, Version 1.0. (See
0017 //  accompanying file LICENSE_1_0.txt or copy at
0018 //  http://www.boost.org/LICENSE_1_0.txt)
0019 //
0020 //
0021 //  Lock-free algorithm by Alexander Terekhov
0022 //
0023 //  Thanks to Ben Hitchings for the #weak + (#shared != 0)
0024 //  formulation
0025 //
0026 
0027 #include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
0028 #include <boost/smart_ptr/detail/sp_obsolete.hpp>
0029 #include <boost/config.hpp>
0030 
0031 #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
0032 
0033 #include <boost/config/pragma_message.hpp>
0034 BOOST_PRAGMA_MESSAGE("Using g++/PowerPC sp_counted_base")
0035 
0036 #endif
0037 
0038 BOOST_SP_OBSOLETE()
0039 
0040 namespace boost
0041 {
0042 
0043 namespace detail
0044 {
0045 
0046 inline void atomic_increment( int * pw )
0047 {
0048     // ++*pw;
0049 
0050     int tmp;
0051 
0052     __asm__
0053     (
0054         "0:\n\t"
0055         "lwarx %1, 0, %2\n\t"
0056         "addi %1, %1, 1\n\t"
0057         "stwcx. %1, 0, %2\n\t"
0058         "bne- 0b":
0059 
0060         "=m"( *pw ), "=&b"( tmp ):
0061         "r"( pw ), "m"( *pw ):
0062         "cc"
0063     );
0064 }
0065 
0066 inline int atomic_decrement( int * pw )
0067 {
0068     // return --*pw;
0069 
0070     int rv;
0071 
0072     __asm__ __volatile__
0073     (
0074         "sync\n\t"
0075         "0:\n\t"
0076         "lwarx %1, 0, %2\n\t"
0077         "addi %1, %1, -1\n\t"
0078         "stwcx. %1, 0, %2\n\t"
0079         "bne- 0b\n\t"
0080         "isync":
0081 
0082         "=m"( *pw ), "=&b"( rv ):
0083         "r"( pw ), "m"( *pw ):
0084         "memory", "cc"
0085     );
0086 
0087     return rv;
0088 }
0089 
0090 inline int atomic_conditional_increment( int * pw )
0091 {
0092     // if( *pw != 0 ) ++*pw;
0093     // return *pw;
0094 
0095     int rv;
0096 
0097     __asm__
0098     (
0099         "0:\n\t"
0100         "lwarx %1, 0, %2\n\t"
0101         "cmpwi %1, 0\n\t"
0102         "beq 1f\n\t"
0103         "addi %1, %1, 1\n\t"
0104         "1:\n\t"
0105         "stwcx. %1, 0, %2\n\t"
0106         "bne- 0b":
0107 
0108         "=m"( *pw ), "=&b"( rv ):
0109         "r"( pw ), "m"( *pw ):
0110         "cc"
0111     );
0112 
0113     return rv;
0114 }
0115 
0116 class BOOST_SYMBOL_VISIBLE sp_counted_base
0117 {
0118 private:
0119 
0120     sp_counted_base( sp_counted_base const & );
0121     sp_counted_base & operator= ( sp_counted_base const & );
0122 
0123     int use_count_;        // #shared
0124     int weak_count_;       // #weak + (#shared != 0)
0125 
0126 public:
0127 
0128     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
0129     {
0130     }
0131 
0132     virtual ~sp_counted_base() // nothrow
0133     {
0134     }
0135 
0136     // dispose() is called when use_count_ drops to zero, to release
0137     // the resources managed by *this.
0138 
0139     virtual void dispose() = 0; // nothrow
0140 
0141     // destroy() is called when weak_count_ drops to zero.
0142 
0143     virtual void destroy() // nothrow
0144     {
0145         delete this;
0146     }
0147 
0148     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
0149     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
0150     virtual void * get_untyped_deleter() = 0;
0151 
0152     void add_ref_copy()
0153     {
0154         atomic_increment( &use_count_ );
0155     }
0156 
0157     bool add_ref_lock() // true on success
0158     {
0159         return atomic_conditional_increment( &use_count_ ) != 0;
0160     }
0161 
0162     void release() // nothrow
0163     {
0164         if( atomic_decrement( &use_count_ ) == 0 )
0165         {
0166             dispose();
0167             weak_release();
0168         }
0169     }
0170 
0171     void weak_add_ref() // nothrow
0172     {
0173         atomic_increment( &weak_count_ );
0174     }
0175 
0176     void weak_release() // nothrow
0177     {
0178         if( atomic_decrement( &weak_count_ ) == 0 )
0179         {
0180             destroy();
0181         }
0182     }
0183 
0184     long use_count() const // nothrow
0185     {
0186         return static_cast<int const volatile &>( use_count_ );
0187     }
0188 };
0189 
0190 } // namespace detail
0191 
0192 } // namespace boost
0193 
0194 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED