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