Go to the documentation of this file.00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_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 #include <boost/detail/sp_typeinfo.hpp>
00023 #include <inttypes.h>
00024
00025 namespace boost
00026 {
00027
00028 namespace detail
00029 {
00030
00031 inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
00032 {
00033 __asm__ __volatile__( "cas %0, %2, %1"
00034 : "+m" (*dest_), "+r" (swap_)
00035 : "r" (compare_)
00036 : "memory" );
00037
00038 return swap_;
00039 }
00040
00041 inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
00042 {
00043
00044
00045
00046
00047 for( ;; )
00048 {
00049 int32_t r = *pw;
00050
00051 if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
00052 {
00053 return r;
00054 }
00055 }
00056 }
00057
00058 inline void atomic_increment( int32_t * pw )
00059 {
00060 atomic_fetch_and_add( pw, 1 );
00061 }
00062
00063 inline int32_t atomic_decrement( int32_t * pw )
00064 {
00065 return atomic_fetch_and_add( pw, -1 );
00066 }
00067
00068 inline int32_t atomic_conditional_increment( int32_t * pw )
00069 {
00070
00071
00072
00073
00074 for( ;; )
00075 {
00076 int32_t r = *pw;
00077
00078 if( r == 0 )
00079 {
00080 return r;
00081 }
00082
00083 if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
00084 {
00085 return r;
00086 }
00087 }
00088 }
00089
00090 class sp_counted_base
00091 {
00092 private:
00093
00094 sp_counted_base( sp_counted_base const & );
00095 sp_counted_base & operator= ( sp_counted_base const & );
00096
00097 int32_t use_count_;
00098 int32_t weak_count_;
00099
00100 public:
00101
00102 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00103 {
00104 }
00105
00106 virtual ~sp_counted_base()
00107 {
00108 }
00109
00110
00111
00112
00113 virtual void dispose() = 0;
00114
00115
00116
00117 virtual void destroy()
00118 {
00119 delete this;
00120 }
00121
00122 virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00123
00124 void add_ref_copy()
00125 {
00126 atomic_increment( &use_count_ );
00127 }
00128
00129 bool add_ref_lock()
00130 {
00131 return atomic_conditional_increment( &use_count_ ) != 0;
00132 }
00133
00134 void release()
00135 {
00136 if( atomic_decrement( &use_count_ ) == 1 )
00137 {
00138 dispose();
00139 weak_release();
00140 }
00141 }
00142
00143 void weak_add_ref()
00144 {
00145 atomic_increment( &weak_count_ );
00146 }
00147
00148 void weak_release()
00149 {
00150 if( atomic_decrement( &weak_count_ ) == 1 )
00151 {
00152 destroy();
00153 }
00154 }
00155
00156 long use_count() const
00157 {
00158 return const_cast< int32_t const volatile & >( use_count_ );
00159 }
00160 };
00161
00162 }
00163
00164 }
00165
00166 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED