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