sp_counted_base_gcc_mips.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
00002 #define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED
00003 
00004 // MS compatible compilers support #pragma once
00005 
00006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
00007 # pragma once
00008 #endif
00009 
00010 //
00011 //  detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS
00012 //
00013 //  Copyright (c) 2009, Spirent Communications, Inc.
00014 //
00015 //  Distributed under the Boost Software License, Version 1.0. (See
00016 //  accompanying file LICENSE_1_0.txt or copy at
00017 //  http://www.boost.org/LICENSE_1_0.txt)
00018 //
00019 //
00020 //  Lock-free algorithm by Alexander Terekhov
00021 //
00022 
00023 #include <boost/detail/sp_typeinfo.hpp>
00024 
00025 namespace boost
00026 {
00027 
00028 namespace detail
00029 {
00030 
00031 inline void atomic_increment( int * pw )
00032 {
00033     // ++*pw;
00034 
00035     int tmp;
00036 
00037     __asm__ __volatile__
00038     (
00039         "0:\n\t"
00040         "ll %0, %1\n\t"
00041         "addiu %0, 1\n\t"
00042         "sc %0, %1\n\t"
00043         "beqz %0, 0b":
00044         "=&r"( tmp ), "=m"( *pw ):
00045         "m"( *pw )
00046     );
00047 }
00048 
00049 inline int atomic_decrement( int * pw )
00050 {
00051     // return --*pw;
00052 
00053     int rv, tmp;
00054 
00055     __asm__ __volatile__
00056     (
00057         "0:\n\t"
00058         "ll %1, %2\n\t"
00059         "addiu %0, %1, -1\n\t"
00060         "sc %0, %2\n\t"
00061         "beqz %0, 0b\n\t"
00062         "addiu %0, %1, -1":
00063         "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
00064         "m"( *pw ):
00065         "memory"
00066     );
00067 
00068     return rv;
00069 }
00070 
00071 inline int atomic_conditional_increment( int * pw )
00072 {
00073     // if( *pw != 0 ) ++*pw;
00074     // return *pw;
00075 
00076     int rv, tmp;
00077 
00078     __asm__ __volatile__
00079     (
00080         "0:\n\t"
00081         "ll %0, %2\n\t"
00082         "beqz %0, 1f\n\t"
00083         "addiu %1, %0, 1\n\t"
00084         "sc %1, %2\n\t"
00085         "beqz %1, 0b\n\t"
00086         "addiu %0, %0, 1\n\t"
00087         "1:":
00088         "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ):
00089         "m"( *pw ):
00090         "memory"
00091     );
00092 
00093     return rv;
00094 }
00095 
00096 class sp_counted_base
00097 {
00098 private:
00099 
00100     sp_counted_base( sp_counted_base const & );
00101     sp_counted_base & operator= ( sp_counted_base const & );
00102 
00103     int use_count_;        // #shared
00104     int weak_count_;       // #weak + (#shared != 0)
00105 
00106 public:
00107 
00108     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00109     {
00110     }
00111 
00112     virtual ~sp_counted_base() // nothrow
00113     {
00114     }
00115 
00116     // dispose() is called when use_count_ drops to zero, to release
00117     // the resources managed by *this.
00118 
00119     virtual void dispose() = 0; // nothrow
00120 
00121     // destroy() is called when weak_count_ drops to zero.
00122 
00123     virtual void destroy() // nothrow
00124     {
00125         delete this;
00126     }
00127 
00128     virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00129 
00130     void add_ref_copy()
00131     {
00132         atomic_increment( &use_count_ );
00133     }
00134 
00135     bool add_ref_lock() // true on success
00136     {
00137         return atomic_conditional_increment( &use_count_ ) != 0;
00138     }
00139 
00140     void release() // nothrow
00141     {
00142         if( atomic_decrement( &use_count_ ) == 0 )
00143         {
00144             dispose();
00145             weak_release();
00146         }
00147     }
00148 
00149     void weak_add_ref() // nothrow
00150     {
00151         atomic_increment( &weak_count_ );
00152     }
00153 
00154     void weak_release() // nothrow
00155     {
00156         if( atomic_decrement( &weak_count_ ) == 0 )
00157         {
00158             destroy();
00159         }
00160     }
00161 
00162     long use_count() const // nothrow
00163     {
00164         return static_cast<int const volatile &>( use_count_ );
00165     }
00166 };
00167 
00168 } // namespace detail
00169 
00170 } // namespace boost
00171 
00172 #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29