Back to home page

EIC code displayed by LXR

 
 

    


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 // MS compatible compilers support #pragma once
0005 
0006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0007 # pragma once
0008 #endif
0009 
0010 //
0011 //  detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS
0012 //
0013 //  Copyright (c) 2009, Spirent Communications, Inc.
0014 //
0015 //  Distributed under the Boost Software License, Version 1.0. (See
0016 //  accompanying file LICENSE_1_0.txt or copy at
0017 //  http://www.boost.org/LICENSE_1_0.txt)
0018 //
0019 //
0020 //  Lock-free algorithm by Alexander Terekhov
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     // ++*pw;
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     // return --*pw;
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     // if( *pw != 0 ) ++*pw;
0095     // return *pw;
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_;        // #shared
0130     int weak_count_;       // #weak + (#shared != 0)
0131 
0132 public:
0133 
0134     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
0135     {
0136     }
0137 
0138     virtual ~sp_counted_base() // nothrow
0139     {
0140     }
0141 
0142     // dispose() is called when use_count_ drops to zero, to release
0143     // the resources managed by *this.
0144 
0145     virtual void dispose() = 0; // nothrow
0146 
0147     // destroy() is called when weak_count_ drops to zero.
0148 
0149     virtual void destroy() // nothrow
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() // true on success
0164     {
0165         return atomic_conditional_increment( &use_count_ ) != 0;
0166     }
0167 
0168     void release() // nothrow
0169     {
0170         if( atomic_decrement( &use_count_ ) == 0 )
0171         {
0172             dispose();
0173             weak_release();
0174         }
0175     }
0176 
0177     void weak_add_ref() // nothrow
0178     {
0179         atomic_increment( &weak_count_ );
0180     }
0181 
0182     void weak_release() // nothrow
0183     {
0184         if( atomic_decrement( &weak_count_ ) == 0 )
0185         {
0186             destroy();
0187         }
0188     }
0189 
0190     long use_count() const // nothrow
0191     {
0192         return static_cast<int const volatile &>( use_count_ );
0193     }
0194 };
0195 
0196 } // namespace detail
0197 
0198 } // namespace boost
0199 
0200 #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED