sp_counted_base_gcc_sparc.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_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 //  detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+
00011 //
00012 //  Copyright (c) 2006 Piotr Wyderski
00013 //  Copyright (c) 2006 Tomas Puverle
00014 //  Copyright (c) 2006 Peter Dimov
00015 //
00016 //  Distributed under the Boost Software License, Version 1.0.
00017 //  See accompanying file LICENSE_1_0.txt or copy at
00018 //  http://www.boost.org/LICENSE_1_0.txt
00019 //
00020 //  Thanks to Michael van der Westhuizen
00021 
00022 #include <boost/detail/sp_typeinfo.hpp>
00023 #include <inttypes.h> // int32_t
00024 
00025 namespace boost
00026 {
00027 
00028 namespace detail
00029 {
00030 
00031 inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ )
00032 {
00033     __asm__ __volatile__( "cas %0, %2, %1"
00034                         : "+m" (*dest_), "+r" (swap_)
00035                         : "r" (compare_)
00036                         : "memory" );
00037 
00038     return swap_;
00039 }
00040 
00041 inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv )
00042 {
00043     // long r = *pw;
00044     // *pw += dv;
00045     // return r;
00046 
00047     for( ;; )
00048     {
00049         int32_t r = *pw;
00050 
00051         if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) )
00052         {
00053             return r;
00054         }
00055     }
00056 }
00057 
00058 inline void atomic_increment( int32_t * pw )
00059 {
00060     atomic_fetch_and_add( pw, 1 );
00061 }
00062 
00063 inline int32_t atomic_decrement( int32_t * pw )
00064 {
00065     return atomic_fetch_and_add( pw, -1 );
00066 }
00067 
00068 inline int32_t atomic_conditional_increment( int32_t * pw )
00069 {
00070     // long r = *pw;
00071     // if( r != 0 ) ++*pw;
00072     // return r;
00073 
00074     for( ;; )
00075     {
00076         int32_t r = *pw;
00077 
00078         if( r == 0 )
00079         {
00080             return r;
00081         }
00082 
00083         if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) )
00084         {
00085             return r;
00086         }
00087     }    
00088 }
00089 
00090 class sp_counted_base
00091 {
00092 private:
00093 
00094     sp_counted_base( sp_counted_base const & );
00095     sp_counted_base & operator= ( sp_counted_base const & );
00096 
00097     int32_t use_count_;        // #shared
00098     int32_t weak_count_;       // #weak + (#shared != 0)
00099 
00100 public:
00101 
00102     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00103     {
00104     }
00105 
00106     virtual ~sp_counted_base() // nothrow
00107     {
00108     }
00109 
00110     // dispose() is called when use_count_ drops to zero, to release
00111     // the resources managed by *this.
00112 
00113     virtual void dispose() = 0; // nothrow
00114 
00115     // destroy() is called when weak_count_ drops to zero.
00116 
00117     virtual void destroy() // nothrow
00118     {
00119         delete this;
00120     }
00121 
00122     virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00123 
00124     void add_ref_copy()
00125     {
00126         atomic_increment( &use_count_ );
00127     }
00128 
00129     bool add_ref_lock() // true on success
00130     {
00131         return atomic_conditional_increment( &use_count_ ) != 0;
00132     }
00133 
00134     void release() // nothrow
00135     {
00136         if( atomic_decrement( &use_count_ ) == 1 )
00137         {
00138             dispose();
00139             weak_release();
00140         }
00141     }
00142 
00143     void weak_add_ref() // nothrow
00144     {
00145         atomic_increment( &weak_count_ );
00146     }
00147 
00148     void weak_release() // nothrow
00149     {
00150         if( atomic_decrement( &weak_count_ ) == 1 )
00151         {
00152             destroy();
00153         }
00154     }
00155 
00156     long use_count() const // nothrow
00157     {
00158         return const_cast< int32_t const volatile & >( use_count_ );
00159     }
00160 };
00161 
00162 } // namespace detail
00163 
00164 } // namespace boost
00165 
00166 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED


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