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_CW_PPC_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_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_cw_ppc.hpp - CodeWarrior 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 CodeWarrior/PowerPC sp_counted_base")
0035 
0036 #endif
0037 
0038 namespace boost
0039 {
0040 
0041 namespace detail
0042 {
0043 
0044 inline void atomic_increment( register long * pw )
0045 {
0046     register int a;
0047 
0048     asm
0049     {
0050 loop:
0051 
0052     lwarx   a, 0, pw
0053     addi    a, a, 1
0054     stwcx.  a, 0, pw
0055     bne-    loop
0056     }
0057 }
0058 
0059 inline long atomic_decrement( register long * pw )
0060 {
0061     register int a;
0062 
0063     asm
0064     {
0065 #if defined(__PPCZen__) || defined(__PPCe500__) || defined(__PPCe500v2__)
0066     msync
0067 #else
0068     sync
0069 #endif
0070 
0071 loop:
0072 
0073     lwarx   a, 0, pw
0074     addi    a, a, -1
0075     stwcx.  a, 0, pw
0076     bne-    loop
0077 
0078     isync
0079     }
0080 
0081     return a;
0082 }
0083 
0084 inline long atomic_conditional_increment( register long * pw )
0085 {
0086     register int a;
0087 
0088     asm
0089     {
0090 loop:
0091 
0092     lwarx   a, 0, pw
0093     cmpwi   a, 0
0094     beq     store
0095 
0096     addi    a, a, 1
0097 
0098 store:
0099 
0100     stwcx.  a, 0, pw
0101     bne-    loop
0102     }
0103 
0104     return a;
0105 }
0106 
0107 class BOOST_SYMBOL_VISIBLE sp_counted_base
0108 {
0109 private:
0110 
0111     sp_counted_base( sp_counted_base const & );
0112     sp_counted_base & operator= ( sp_counted_base const & );
0113 
0114     long use_count_;        // #shared
0115     long weak_count_;       // #weak + (#shared != 0)
0116 
0117 public:
0118 
0119     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
0120     {
0121     }
0122 
0123     virtual ~sp_counted_base() // nothrow
0124     {
0125     }
0126 
0127     // dispose() is called when use_count_ drops to zero, to release
0128     // the resources managed by *this.
0129 
0130     virtual void dispose() = 0; // nothrow
0131 
0132     // destroy() is called when weak_count_ drops to zero.
0133 
0134     virtual void destroy() // nothrow
0135     {
0136         delete this;
0137     }
0138 
0139     virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
0140     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
0141     virtual void * get_untyped_deleter() = 0;
0142 
0143     void add_ref_copy()
0144     {
0145         atomic_increment( &use_count_ );
0146     }
0147 
0148     bool add_ref_lock() // true on success
0149     {
0150         return atomic_conditional_increment( &use_count_ ) != 0;
0151     }
0152 
0153     void release() // nothrow
0154     {
0155         if( atomic_decrement( &use_count_ ) == 0 )
0156         {
0157             dispose();
0158             weak_release();
0159         }
0160     }
0161 
0162     void weak_add_ref() // nothrow
0163     {
0164         atomic_increment( &weak_count_ );
0165     }
0166 
0167     void weak_release() // nothrow
0168     {
0169         if( atomic_decrement( &weak_count_ ) == 0 )
0170         {
0171             destroy();
0172         }
0173     }
0174 
0175     long use_count() const // nothrow
0176     {
0177         return static_cast<long const volatile &>( use_count_ );
0178     }
0179 };
0180 
0181 } // namespace detail
0182 
0183 } // namespace boost
0184 
0185 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED