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