sp_counted_base_gcc_x86.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_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_x86.hpp - g++ on 486+ or AMD64
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 int atomic_exchange_and_add( int * pw, int dv )
00036 {
00037     // int r = *pw;
00038     // *pw += dv;
00039     // return r;
00040 
00041     int r;
00042 
00043     __asm__ __volatile__
00044     (
00045         "lock\n\t"
00046         "xadd %1, %0":
00047         "=m"( *pw ), "=r"( r ): // outputs (%0, %1)
00048         "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
00049         "memory", "cc" // clobbers
00050     );
00051 
00052     return r;
00053 }
00054 
00055 inline void atomic_increment( int * pw )
00056 {
00057     //atomic_exchange_and_add( pw, 1 );
00058 
00059     __asm__
00060     (
00061         "lock\n\t"
00062         "incl %0":
00063         "=m"( *pw ): // output (%0)
00064         "m"( *pw ): // input (%1)
00065         "cc" // clobbers
00066     );
00067 }
00068 
00069 inline int atomic_conditional_increment( int * pw )
00070 {
00071     // int rv = *pw;
00072     // if( rv != 0 ) ++*pw;
00073     // return rv;
00074 
00075     int rv, tmp;
00076 
00077     __asm__
00078     (
00079         "movl %0, %%eax\n\t"
00080         "0:\n\t"
00081         "test %%eax, %%eax\n\t"
00082         "je 1f\n\t"
00083         "movl %%eax, %2\n\t"
00084         "incl %2\n\t"
00085         "lock\n\t"
00086         "cmpxchgl %2, %0\n\t"
00087         "jne 0b\n\t"
00088         "1:":
00089         "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
00090         "m"( *pw ): // input (%3)
00091         "cc" // clobbers
00092     );
00093 
00094     return rv;
00095 }
00096 
00097 class sp_counted_base
00098 {
00099 private:
00100 
00101     sp_counted_base( sp_counted_base const & );
00102     sp_counted_base & operator= ( sp_counted_base const & );
00103 
00104     int use_count_;        // #shared
00105     int weak_count_;       // #weak + (#shared != 0)
00106 
00107 public:
00108 
00109     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00110     {
00111     }
00112 
00113     virtual ~sp_counted_base() // nothrow
00114     {
00115     }
00116 
00117     // dispose() is called when use_count_ drops to zero, to release
00118     // the resources managed by *this.
00119 
00120     virtual void dispose() = 0; // nothrow
00121 
00122     // destroy() is called when weak_count_ drops to zero.
00123 
00124     virtual void destroy() // nothrow
00125     {
00126         delete this;
00127     }
00128 
00129     virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00130 
00131     void add_ref_copy()
00132     {
00133         atomic_increment( &use_count_ );
00134     }
00135 
00136     bool add_ref_lock() // true on success
00137     {
00138         return atomic_conditional_increment( &use_count_ ) != 0;
00139     }
00140 
00141     void release() // nothrow
00142     {
00143         if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
00144         {
00145             dispose();
00146             weak_release();
00147         }
00148     }
00149 
00150     void weak_add_ref() // nothrow
00151     {
00152         atomic_increment( &weak_count_ );
00153     }
00154 
00155     void weak_release() // nothrow
00156     {
00157         if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
00158         {
00159             destroy();
00160         }
00161     }
00162 
00163     long use_count() const // nothrow
00164     {
00165         return static_cast<int const volatile &>( use_count_ );
00166     }
00167 };
00168 
00169 } // namespace detail
00170 
00171 } // namespace boost
00172 
00173 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED


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