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