File indexing completed on 2025-01-18 09:51:43
0001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
0025 #include <boost/smart_ptr/detail/sp_obsolete.hpp>
0026 #include <boost/config.hpp>
0027
0028 #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
0029
0030 #include <boost/config/pragma_message.hpp>
0031 BOOST_PRAGMA_MESSAGE("Using xlC/PowerPC sp_counted_base")
0032
0033 #endif
0034
0035 BOOST_SP_OBSOLETE()
0036
0037 extern "builtin" void __lwsync(void);
0038 extern "builtin" void __isync(void);
0039 extern "builtin" int __fetch_and_add(volatile int* addr, int val);
0040 extern "builtin" int __compare_and_swap(volatile int*, int*, int);
0041
0042 namespace boost
0043 {
0044
0045 namespace detail
0046 {
0047
0048 inline void atomic_increment( int *pw )
0049 {
0050
0051 __lwsync();
0052 __fetch_and_add(pw, 1);
0053 __isync();
0054 }
0055
0056 inline int atomic_decrement( int *pw )
0057 {
0058
0059 __lwsync();
0060 int originalValue = __fetch_and_add(pw, -1);
0061 __isync();
0062
0063 return (originalValue - 1);
0064 }
0065
0066 inline int atomic_conditional_increment( int *pw )
0067 {
0068
0069
0070
0071 __lwsync();
0072 int v = *const_cast<volatile int*>(pw);
0073 for (;;)
0074
0075 {
0076 if (v == 0) return 0;
0077 if (__compare_and_swap(pw, &v, v + 1))
0078 {
0079 __isync(); return (v + 1);
0080 }
0081 }
0082 }
0083
0084 class BOOST_SYMBOL_VISIBLE sp_counted_base
0085 {
0086 private:
0087
0088 sp_counted_base( sp_counted_base const & );
0089 sp_counted_base & operator= ( sp_counted_base const & );
0090
0091 int use_count_;
0092 int weak_count_;
0093 char pad[64] __attribute__((__aligned__(64)));
0094
0095 public:
0096
0097 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
0098 {
0099 }
0100
0101 virtual ~sp_counted_base()
0102 {
0103 }
0104
0105
0106
0107
0108 virtual void dispose() = 0;
0109
0110
0111
0112 virtual void destroy()
0113 {
0114 delete this;
0115 }
0116
0117 virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
0118 virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
0119 virtual void * get_untyped_deleter() = 0;
0120
0121 void add_ref_copy()
0122 {
0123 atomic_increment( &use_count_ );
0124 }
0125
0126 bool add_ref_lock()
0127 {
0128 return atomic_conditional_increment( &use_count_ ) != 0;
0129 }
0130
0131 void release()
0132 {
0133 if( atomic_decrement( &use_count_ ) == 0 )
0134 {
0135 dispose();
0136 weak_release();
0137 }
0138 }
0139
0140 void weak_add_ref()
0141 {
0142 atomic_increment( &weak_count_ );
0143 }
0144
0145 void weak_release()
0146 {
0147 if( atomic_decrement( &weak_count_ ) == 0 )
0148 {
0149 destroy();
0150 }
0151 }
0152
0153 long use_count() const
0154 {
0155 return *const_cast<volatile int*>(&use_count_);
0156 }
0157 };
0158
0159 }
0160
0161 }
0162
0163 #endif