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
0005
0006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0007 # pragma once
0008 #endif
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
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_;
0115 long weak_count_;
0116
0117 public:
0118
0119 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
0120 {
0121 }
0122
0123 virtual ~sp_counted_base()
0124 {
0125 }
0126
0127
0128
0129
0130 virtual void dispose() = 0;
0131
0132
0133
0134 virtual void destroy()
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()
0149 {
0150 return atomic_conditional_increment( &use_count_ ) != 0;
0151 }
0152
0153 void release()
0154 {
0155 if( atomic_decrement( &use_count_ ) == 0 )
0156 {
0157 dispose();
0158 weak_release();
0159 }
0160 }
0161
0162 void weak_add_ref()
0163 {
0164 atomic_increment( &weak_count_ );
0165 }
0166
0167 void weak_release()
0168 {
0169 if( atomic_decrement( &weak_count_ ) == 0 )
0170 {
0171 destroy();
0172 }
0173 }
0174
0175 long use_count() const
0176 {
0177 return static_cast<long const volatile &>( use_count_ );
0178 }
0179 };
0180
0181 }
0182
0183 }
0184
0185 #endif