Go to the documentation of this file.00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
00003
00004
00005
00006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
00007 # pragma once
00008 #endif
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <boost/detail/sp_typeinfo.hpp>
00028
00029 namespace boost
00030 {
00031
00032 namespace detail
00033 {
00034
00035 inline void atomic_increment( register long * pw )
00036 {
00037 register int a;
00038
00039 asm
00040 {
00041 loop:
00042
00043 lwarx a, 0, pw
00044 addi a, a, 1
00045 stwcx. a, 0, pw
00046 bne- loop
00047 }
00048 }
00049
00050 inline long atomic_decrement( register long * pw )
00051 {
00052 register int a;
00053
00054 asm
00055 {
00056 sync
00057
00058 loop:
00059
00060 lwarx a, 0, pw
00061 addi a, a, -1
00062 stwcx. a, 0, pw
00063 bne- loop
00064
00065 isync
00066 }
00067
00068 return a;
00069 }
00070
00071 inline long atomic_conditional_increment( register long * pw )
00072 {
00073 register int a;
00074
00075 asm
00076 {
00077 loop:
00078
00079 lwarx a, 0, pw
00080 cmpwi a, 0
00081 beq store
00082
00083 addi a, a, 1
00084
00085 store:
00086
00087 stwcx. a, 0, pw
00088 bne- loop
00089 }
00090
00091 return a;
00092 }
00093
00094 class sp_counted_base
00095 {
00096 private:
00097
00098 sp_counted_base( sp_counted_base const & );
00099 sp_counted_base & operator= ( sp_counted_base const & );
00100
00101 long use_count_;
00102 long weak_count_;
00103
00104 public:
00105
00106 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00107 {
00108 }
00109
00110 virtual ~sp_counted_base()
00111 {
00112 }
00113
00114
00115
00116
00117 virtual void dispose() = 0;
00118
00119
00120
00121 virtual void destroy()
00122 {
00123 delete this;
00124 }
00125
00126 virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00127
00128 void add_ref_copy()
00129 {
00130 atomic_increment( &use_count_ );
00131 }
00132
00133 bool add_ref_lock()
00134 {
00135 return atomic_conditional_increment( &use_count_ ) != 0;
00136 }
00137
00138 void release()
00139 {
00140 if( atomic_decrement( &use_count_ ) == 0 )
00141 {
00142 dispose();
00143 weak_release();
00144 }
00145 }
00146
00147 void weak_add_ref()
00148 {
00149 atomic_increment( &weak_count_ );
00150 }
00151
00152 void weak_release()
00153 {
00154 if( atomic_decrement( &weak_count_ ) == 0 )
00155 {
00156 destroy();
00157 }
00158 }
00159
00160 long use_count() const
00161 {
00162 return static_cast<long const volatile &>( use_count_ );
00163 }
00164 };
00165
00166 }
00167
00168 }
00169
00170 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED