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