sp_counted_base_gcc_ppc.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_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_ppc.hpp - g++ on PowerPC
00012 //
00013 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
00014 //  Copyright 2004-2005 Peter Dimov
00015 //
00016 //  Distributed under the Boost Software License, Version 1.0. (See
00017 //  accompanying file LICENSE_1_0.txt or copy at
00018 //  http://www.boost.org/LICENSE_1_0.txt)
00019 //
00020 //
00021 //  Lock-free algorithm by Alexander Terekhov
00022 //
00023 //  Thanks to Ben Hitchings for the #weak + (#shared != 0)
00024 //  formulation
00025 //
00026 
00027 #include <boost/detail/sp_typeinfo.hpp>
00028 
00029 namespace boost
00030 {
00031 
00032 namespace detail
00033 {
00034 
00035 inline void atomic_increment( int * pw )
00036 {
00037     // ++*pw;
00038 
00039     int tmp;
00040 
00041     __asm__
00042     (
00043         "0:\n\t"
00044         "lwarx %1, 0, %2\n\t"
00045         "addi %1, %1, 1\n\t"
00046         "stwcx. %1, 0, %2\n\t"
00047         "bne- 0b":
00048 
00049         "=m"( *pw ), "=&b"( tmp ):
00050         "r"( pw ), "m"( *pw ):
00051         "cc"
00052     );
00053 }
00054 
00055 inline int atomic_decrement( int * pw )
00056 {
00057     // return --*pw;
00058 
00059     int rv;
00060 
00061     __asm__ __volatile__
00062     (
00063         "sync\n\t"
00064         "0:\n\t"
00065         "lwarx %1, 0, %2\n\t"
00066         "addi %1, %1, -1\n\t"
00067         "stwcx. %1, 0, %2\n\t"
00068         "bne- 0b\n\t"
00069         "isync":
00070 
00071         "=m"( *pw ), "=&b"( rv ):
00072         "r"( pw ), "m"( *pw ):
00073         "memory", "cc"
00074     );
00075 
00076     return rv;
00077 }
00078 
00079 inline int atomic_conditional_increment( int * pw )
00080 {
00081     // if( *pw != 0 ) ++*pw;
00082     // return *pw;
00083 
00084     int rv;
00085 
00086     __asm__
00087     (
00088         "0:\n\t"
00089         "lwarx %1, 0, %2\n\t"
00090         "cmpwi %1, 0\n\t"
00091         "beq 1f\n\t"
00092         "addi %1, %1, 1\n\t"
00093         "1:\n\t"
00094         "stwcx. %1, 0, %2\n\t"
00095         "bne- 0b":
00096 
00097         "=m"( *pw ), "=&b"( rv ):
00098         "r"( pw ), "m"( *pw ):
00099         "cc"
00100     );
00101 
00102     return rv;
00103 }
00104 
00105 class sp_counted_base
00106 {
00107 private:
00108 
00109     sp_counted_base( sp_counted_base const & );
00110     sp_counted_base & operator= ( sp_counted_base const & );
00111 
00112     int use_count_;        // #shared
00113     int weak_count_;       // #weak + (#shared != 0)
00114 
00115 public:
00116 
00117     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00118     {
00119     }
00120 
00121     virtual ~sp_counted_base() // nothrow
00122     {
00123     }
00124 
00125     // dispose() is called when use_count_ drops to zero, to release
00126     // the resources managed by *this.
00127 
00128     virtual void dispose() = 0; // nothrow
00129 
00130     // destroy() is called when weak_count_ drops to zero.
00131 
00132     virtual void destroy() // nothrow
00133     {
00134         delete this;
00135     }
00136 
00137     virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00138 
00139     void add_ref_copy()
00140     {
00141         atomic_increment( &use_count_ );
00142     }
00143 
00144     bool add_ref_lock() // true on success
00145     {
00146         return atomic_conditional_increment( &use_count_ ) != 0;
00147     }
00148 
00149     void release() // nothrow
00150     {
00151         if( atomic_decrement( &use_count_ ) == 0 )
00152         {
00153             dispose();
00154             weak_release();
00155         }
00156     }
00157 
00158     void weak_add_ref() // nothrow
00159     {
00160         atomic_increment( &weak_count_ );
00161     }
00162 
00163     void weak_release() // nothrow
00164     {
00165         if( atomic_decrement( &weak_count_ ) == 0 )
00166         {
00167             destroy();
00168         }
00169     }
00170 
00171     long use_count() const // nothrow
00172     {
00173         return static_cast<int const volatile &>( use_count_ );
00174     }
00175 };
00176 
00177 } // namespace detail
00178 
00179 } // namespace boost
00180 
00181 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED


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