Go to the documentation of this file.00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_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( int * pw )
00036 {
00037
00038
00039 int tmp;
00040
00041 __asm__
00042 (
00043 "0:\n\t"
00044 "lwarx %1, 0, %2\n\t"
00045 "addi %1, %1, 1\n\t"
00046 "stwcx. %1, 0, %2\n\t"
00047 "bne- 0b":
00048
00049 "=m"( *pw ), "=&b"( tmp ):
00050 "r"( pw ), "m"( *pw ):
00051 "cc"
00052 );
00053 }
00054
00055 inline int atomic_decrement( int * pw )
00056 {
00057
00058
00059 int rv;
00060
00061 __asm__ __volatile__
00062 (
00063 "sync\n\t"
00064 "0:\n\t"
00065 "lwarx %1, 0, %2\n\t"
00066 "addi %1, %1, -1\n\t"
00067 "stwcx. %1, 0, %2\n\t"
00068 "bne- 0b\n\t"
00069 "isync":
00070
00071 "=m"( *pw ), "=&b"( rv ):
00072 "r"( pw ), "m"( *pw ):
00073 "memory", "cc"
00074 );
00075
00076 return rv;
00077 }
00078
00079 inline int atomic_conditional_increment( int * pw )
00080 {
00081
00082
00083
00084 int rv;
00085
00086 __asm__
00087 (
00088 "0:\n\t"
00089 "lwarx %1, 0, %2\n\t"
00090 "cmpwi %1, 0\n\t"
00091 "beq 1f\n\t"
00092 "addi %1, %1, 1\n\t"
00093 "1:\n\t"
00094 "stwcx. %1, 0, %2\n\t"
00095 "bne- 0b":
00096
00097 "=m"( *pw ), "=&b"( rv ):
00098 "r"( pw ), "m"( *pw ):
00099 "cc"
00100 );
00101
00102 return rv;
00103 }
00104
00105 class sp_counted_base
00106 {
00107 private:
00108
00109 sp_counted_base( sp_counted_base const & );
00110 sp_counted_base & operator= ( sp_counted_base const & );
00111
00112 int use_count_;
00113 int weak_count_;
00114
00115 public:
00116
00117 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00118 {
00119 }
00120
00121 virtual ~sp_counted_base()
00122 {
00123 }
00124
00125
00126
00127
00128 virtual void dispose() = 0;
00129
00130
00131
00132 virtual void destroy()
00133 {
00134 delete this;
00135 }
00136
00137 virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00138
00139 void add_ref_copy()
00140 {
00141 atomic_increment( &use_count_ );
00142 }
00143
00144 bool add_ref_lock()
00145 {
00146 return atomic_conditional_increment( &use_count_ ) != 0;
00147 }
00148
00149 void release()
00150 {
00151 if( atomic_decrement( &use_count_ ) == 0 )
00152 {
00153 dispose();
00154 weak_release();
00155 }
00156 }
00157
00158 void weak_add_ref()
00159 {
00160 atomic_increment( &weak_count_ );
00161 }
00162
00163 void weak_release()
00164 {
00165 if( atomic_decrement( &weak_count_ ) == 0 )
00166 {
00167 destroy();
00168 }
00169 }
00170
00171 long use_count() const
00172 {
00173 return static_cast<int const volatile &>( use_count_ );
00174 }
00175 };
00176
00177 }
00178
00179 }
00180
00181 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED