00001 #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
00002 #define BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <typeinfo>
00020
00021 namespace boost
00022 {
00023
00024 namespace detail
00025 {
00026
00027 inline void atomic_increment( long * pw )
00028 {
00029
00030
00031 long tmp;
00032
00033
00034
00035
00036 __asm__ ("fetchadd8.rel %0=[%2],1" :
00037 "=r"(tmp), "=m"(*pw) :
00038 "r"(pw));
00039 }
00040
00041 inline long atomic_decrement( long * pw )
00042 {
00043
00044
00045 long rv;
00046
00047 __asm__ (" fetchadd8.rel %0=[%2],-1 ;; \n"
00048 " cmp.eq p7,p0=1,%0 ;; \n"
00049 "(p7) ld8.acq %0=[%2] " :
00050 "=&r"(rv), "=m"(*pw) :
00051 "r"(pw) :
00052 "p7");
00053
00054 return rv;
00055 }
00056
00057 inline long atomic_conditional_increment( long * pw )
00058 {
00059
00060
00061
00062 long rv, tmp, tmp2;
00063
00064 __asm__ ("0: ld8 %0=[%4] ;; \n"
00065 " cmp.eq p7,p0=0,%0 ;; \n"
00066 "(p7) br.cond.spnt 1f \n"
00067 " mov ar.ccv=%0 \n"
00068 " add %1=1,%0 ;; \n"
00069 " cmpxchg8.acq %2=[%4],%1,ar.ccv ;; \n"
00070 " cmp.ne p7,p0=%0,%2 ;; \n"
00071 "(p7) br.cond.spnt 0b \n"
00072 " mov %0=%1 ;; \n"
00073 "1:" :
00074 "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
00075 "r"(pw) :
00076 "ar.ccv", "p7");
00077
00078 return rv;
00079 }
00080
00081 class sp_counted_base
00082 {
00083 private:
00084
00085 sp_counted_base( sp_counted_base const & );
00086 sp_counted_base & operator= ( sp_counted_base const & );
00087
00088 long use_count_;
00089 long weak_count_;
00090
00091 public:
00092
00093 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00094 {
00095 }
00096
00097 virtual ~sp_counted_base()
00098 {
00099 }
00100
00101
00102
00103
00104 virtual void dispose() = 0;
00105
00106
00107
00108 virtual void destroy()
00109 {
00110 delete this;
00111 }
00112
00113 virtual void * get_deleter( std::type_info const & ti ) = 0;
00114
00115 void add_ref_copy()
00116 {
00117 atomic_increment( &use_count_ );
00118 }
00119
00120 bool add_ref_lock()
00121 {
00122 return atomic_conditional_increment( &use_count_ ) != 0;
00123 }
00124
00125 void release()
00126 {
00127 if( atomic_decrement( &use_count_ ) == 0 )
00128 {
00129 dispose();
00130 weak_release();
00131 }
00132 }
00133
00134 void weak_add_ref()
00135 {
00136 atomic_increment( &weak_count_ );
00137 }
00138
00139 void weak_release()
00140 {
00141 if( atomic_decrement( &weak_count_ ) == 0 )
00142 {
00143 destroy();
00144 }
00145 }
00146
00147 long use_count() const
00148 {
00149 return static_cast<long const volatile &>( use_count_ );
00150 }
00151 };
00152
00153 }
00154
00155 }
00156
00157 #endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED