sp_counted_base_gcc_ia64.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
00003 
00004 //
00005 //  detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
00006 //
00007 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
00008 //  Copyright 2004-2006 Peter Dimov
00009 //  Copyright 2005 Ben Hutchings
00010 //
00011 //  Distributed under the Boost Software License, Version 1.0. (See
00012 //  accompanying file LICENSE_1_0.txt or copy at
00013 //  http://www.boost.org/LICENSE_1_0.txt)
00014 //
00015 //
00016 //  Lock-free algorithm by Alexander Terekhov
00017 //
00018 
00019 #include <boost/detail/sp_typeinfo.hpp>
00020 
00021 namespace boost
00022 {
00023 
00024 namespace detail
00025 {
00026 
00027 inline void atomic_increment( int * pw )
00028 {
00029     // ++*pw;
00030 
00031     int tmp;
00032 
00033     // No barrier is required here but fetchadd always has an acquire or
00034     // release barrier associated with it.  We choose release as it should be
00035     // cheaper.
00036     __asm__ ("fetchadd4.rel %0=%1,1" :
00037          "=r"(tmp), "=m"(*pw) :
00038          "m"( *pw ));
00039 }
00040 
00041 inline int atomic_decrement( int * pw )
00042 {
00043     // return --*pw;
00044 
00045     int rv;
00046 
00047     __asm__ ("     fetchadd4.rel %0=%1,-1 ;; \n"
00048              "     cmp.eq        p7,p0=1,%0 ;; \n"
00049              "(p7) ld4.acq       %0=%1    " :
00050              "=&r"(rv), "=m"(*pw) :
00051              "m"( *pw ) :
00052              "p7");
00053 
00054     return rv;
00055 }
00056 
00057 inline int atomic_conditional_increment( int * pw )
00058 {
00059     // if( *pw != 0 ) ++*pw;
00060     // return *pw;
00061 
00062     int rv, tmp, tmp2;
00063 
00064     __asm__ ("0:   ld4          %0=%3           ;; \n"
00065          "     cmp.eq       p7,p0=0,%0        ;; \n"
00066          "(p7) br.cond.spnt 1f                \n"
00067          "     mov          ar.ccv=%0         \n"
00068          "     add          %1=1,%0           ;; \n"
00069          "     cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
00070          "     cmp.ne       p7,p0=%0,%2       ;; \n"
00071          "(p7) br.cond.spnt 0b                \n"
00072          "     mov          %0=%1             ;; \n"
00073          "1:" : 
00074          "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
00075          "m"( *pw ) :
00076          "ar.ccv", "p7");
00077 
00078     return rv;
00079 }
00080 
00081 class sp_counted_base
00082 {
00083 private:
00084 
00085     sp_counted_base( sp_counted_base const & );
00086     sp_counted_base & operator= ( sp_counted_base const & );
00087 
00088     int use_count_;        // #shared
00089     int weak_count_;       // #weak + (#shared != 0)
00090 
00091 public:
00092 
00093     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
00094     {
00095     }
00096 
00097     virtual ~sp_counted_base() // nothrow
00098     {
00099     }
00100 
00101     // dispose() is called when use_count_ drops to zero, to release
00102     // the resources managed by *this.
00103 
00104     virtual void dispose() = 0; // nothrow
00105 
00106     // destroy() is called when weak_count_ drops to zero.
00107 
00108     virtual void destroy() // nothrow
00109     {
00110         delete this;
00111     }
00112 
00113     virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
00114 
00115     void add_ref_copy()
00116     {
00117         atomic_increment( &use_count_ );
00118     }
00119 
00120     bool add_ref_lock() // true on success
00121     {
00122         return atomic_conditional_increment( &use_count_ ) != 0;
00123     }
00124 
00125     void release() // nothrow
00126     {
00127         if( atomic_decrement( &use_count_ ) == 0 )
00128         {
00129             dispose();
00130             weak_release();
00131         }
00132     }
00133 
00134     void weak_add_ref() // nothrow
00135     {
00136         atomic_increment( &weak_count_ );
00137     }
00138 
00139     void weak_release() // nothrow
00140     {
00141         if( atomic_decrement( &weak_count_ ) == 0 )
00142         {
00143             destroy();
00144         }
00145     }
00146 
00147     long use_count() const // nothrow
00148     {
00149         return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
00150     }
00151 };
00152 
00153 } // namespace detail
00154 
00155 } // namespace boost
00156 
00157 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED


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