Go to the documentation of this file.00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_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
00028 #include <boost/detail/sp_typeinfo.hpp>
00029
00030 namespace boost
00031 {
00032
00033 namespace detail
00034 {
00035
00036 inline int atomic_exchange_and_add( int * pw, int dv )
00037 {
00038
00039
00040
00041
00042 asm
00043 {
00044 mov esi, [pw]
00045 mov eax, dv
00046 lock xadd dword ptr [esi], eax
00047 }
00048 }
00049
00050 inline void atomic_increment( int * pw )
00051 {
00052
00053
00054 asm
00055 {
00056 mov esi, [pw]
00057 lock inc dword ptr [esi]
00058 }
00059 }
00060
00061 inline int atomic_conditional_increment( int * pw )
00062 {
00063
00064
00065
00066
00067 asm
00068 {
00069 mov esi, [pw]
00070 mov eax, dword ptr [esi]
00071 L0:
00072 test eax, eax
00073 je L1
00074 mov ebx, eax
00075 inc ebx
00076 lock cmpxchg dword ptr [esi], ebx
00077 jne L0
00078 L1:
00079 }
00080 }
00081
00082 class sp_counted_base
00083 {
00084 private:
00085
00086 sp_counted_base( sp_counted_base const & );
00087 sp_counted_base & operator= ( sp_counted_base const & );
00088
00089 int use_count_;
00090 int weak_count_;
00091
00092 public:
00093
00094 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00095 {
00096 }
00097
00098 virtual ~sp_counted_base()
00099 {
00100 }
00101
00102
00103
00104
00105 virtual void dispose() = 0;
00106
00107
00108
00109 virtual void destroy()
00110 {
00111 delete this;
00112 }
00113
00114 virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00115
00116 void add_ref_copy()
00117 {
00118 atomic_increment( &use_count_ );
00119 }
00120
00121 bool add_ref_lock()
00122 {
00123 return atomic_conditional_increment( &use_count_ ) != 0;
00124 }
00125
00126 void release()
00127 {
00128 if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
00129 {
00130 dispose();
00131 weak_release();
00132 }
00133 }
00134
00135 void weak_add_ref()
00136 {
00137 atomic_increment( &weak_count_ );
00138 }
00139
00140 void weak_release()
00141 {
00142 if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
00143 {
00144 destroy();
00145 }
00146 }
00147
00148 long use_count() const
00149 {
00150 return static_cast<int const volatile &>( use_count_ );
00151 }
00152 };
00153
00154 }
00155
00156 }
00157
00158 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED