File indexing completed on 2025-01-18 09:51:42
0001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
0020 #include <boost/smart_ptr/detail/sp_obsolete.hpp>
0021 #include <boost/config.hpp>
0022
0023 #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
0024
0025 #include <boost/config/pragma_message.hpp>
0026 BOOST_PRAGMA_MESSAGE("Using g++/IA64 sp_counted_base")
0027
0028 #endif
0029
0030 BOOST_SP_OBSOLETE()
0031
0032 namespace boost
0033 {
0034
0035 namespace detail
0036 {
0037
0038 inline void atomic_increment( int * pw )
0039 {
0040
0041
0042 int tmp;
0043
0044
0045
0046
0047 __asm__ ("fetchadd4.rel %0=%1,1" :
0048 "=r"(tmp), "=m"(*pw) :
0049 "m"( *pw ));
0050 }
0051
0052 inline int atomic_decrement( int * pw )
0053 {
0054
0055
0056 int rv;
0057
0058 __asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
0059 " cmp.eq p7,p0=1,%0 ;; \n"
0060 "(p7) ld4.acq %0=%1 " :
0061 "=&r"(rv), "=m"(*pw) :
0062 "m"( *pw ) :
0063 "p7");
0064
0065 return rv;
0066 }
0067
0068 inline int atomic_conditional_increment( int * pw )
0069 {
0070
0071
0072
0073 int rv, tmp, tmp2;
0074
0075 __asm__ ("0: ld4 %0=%3 ;; \n"
0076 " cmp.eq p7,p0=0,%0 ;; \n"
0077 "(p7) br.cond.spnt 1f \n"
0078 " mov ar.ccv=%0 \n"
0079 " add %1=1,%0 ;; \n"
0080 " cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
0081 " cmp.ne p7,p0=%0,%2 ;; \n"
0082 "(p7) br.cond.spnt 0b \n"
0083 " mov %0=%1 ;; \n"
0084 "1:" :
0085 "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
0086 "m"( *pw ) :
0087 "ar.ccv", "p7");
0088
0089 return rv;
0090 }
0091
0092 class BOOST_SYMBOL_VISIBLE sp_counted_base
0093 {
0094 private:
0095
0096 sp_counted_base( sp_counted_base const & );
0097 sp_counted_base & operator= ( sp_counted_base const & );
0098
0099 int use_count_;
0100 int weak_count_;
0101
0102 public:
0103
0104 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
0105 {
0106 }
0107
0108 virtual ~sp_counted_base()
0109 {
0110 }
0111
0112
0113
0114
0115 virtual void dispose() = 0;
0116
0117
0118
0119 virtual void destroy()
0120 {
0121 delete this;
0122 }
0123
0124 virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
0125 virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
0126 virtual void * get_untyped_deleter() = 0;
0127
0128 void add_ref_copy()
0129 {
0130 atomic_increment( &use_count_ );
0131 }
0132
0133 bool add_ref_lock()
0134 {
0135 return atomic_conditional_increment( &use_count_ ) != 0;
0136 }
0137
0138 void release()
0139 {
0140 if( atomic_decrement( &use_count_ ) == 0 )
0141 {
0142 dispose();
0143 weak_release();
0144 }
0145 }
0146
0147 void weak_add_ref()
0148 {
0149 atomic_increment( &weak_count_ );
0150 }
0151
0152 void weak_release()
0153 {
0154 if( atomic_decrement( &weak_count_ ) == 0 )
0155 {
0156 destroy();
0157 }
0158 }
0159
0160 long use_count() const
0161 {
0162 return static_cast<int const volatile &>( use_count_ );
0163 }
0164 };
0165
0166 }
0167
0168 }
0169
0170 #endif