epoc32/include/stdapis/boost/detail/sp_counted_base_cw_x86.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
     1 #ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
     2 #define BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
     3 
     4 // MS compatible compilers support #pragma once
     5 
     6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
     7 # pragma once
     8 #endif
     9 
    10 //
    11 //  detail/sp_counted_base_cw_x86.hpp - CodeWarrion on 486+
    12 //
    13 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
    14 //  Copyright 2004-2005 Peter Dimov
    15 //  Copyright 2005 Rene Rivera
    16 //
    17 //  Distributed under the Boost Software License, Version 1.0. (See
    18 //  accompanying file LICENSE_1_0.txt or copy at
    19 //  http://www.boost.org/LICENSE_1_0.txt)
    20 //
    21 //
    22 //  Lock-free algorithm by Alexander Terekhov
    23 //
    24 //  Thanks to Ben Hitchings for the #weak + (#shared != 0)
    25 //  formulation
    26 //
    27 
    28 #include <typeinfo>
    29 
    30 namespace boost
    31 {
    32 
    33 namespace detail
    34 {
    35 
    36 inline int atomic_exchange_and_add( int * pw, int dv )
    37 {
    38     // int r = *pw;
    39     // *pw += dv;
    40     // return r;
    41 
    42     asm
    43     {
    44         mov esi, [pw]
    45         mov eax, dv
    46         lock xadd dword ptr [esi], eax
    47     }
    48 }
    49 
    50 inline void atomic_increment( int * pw )
    51 {
    52     //atomic_exchange_and_add( pw, 1 );
    53 
    54     asm
    55     {
    56         mov esi, [pw]
    57         lock inc dword ptr [esi]
    58     }
    59 }
    60 
    61 inline int atomic_conditional_increment( int * pw )
    62 {
    63     // int rv = *pw;
    64     // if( rv != 0 ) ++*pw;
    65     // return rv;
    66 
    67     asm
    68     {
    69         mov esi, [pw]
    70         mov eax, dword ptr [esi]
    71     L0:
    72         test eax, eax
    73         je L1
    74         mov ebx, eax
    75         inc ebx
    76         lock cmpxchg dword ptr [esi], ebx
    77         jne L0
    78     L1:
    79     }
    80 }
    81 
    82 class sp_counted_base
    83 {
    84 private:
    85 
    86     sp_counted_base( sp_counted_base const & );
    87     sp_counted_base & operator= ( sp_counted_base const & );
    88 
    89     int use_count_;        // #shared
    90     int weak_count_;       // #weak + (#shared != 0)
    91 
    92 public:
    93 
    94     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
    95     {
    96     }
    97 
    98     virtual ~sp_counted_base() // nothrow
    99     {
   100     }
   101 
   102     // dispose() is called when use_count_ drops to zero, to release
   103     // the resources managed by *this.
   104 
   105     virtual void dispose() = 0; // nothrow
   106 
   107     // destroy() is called when weak_count_ drops to zero.
   108 
   109     virtual void destroy() // nothrow
   110     {
   111         delete this;
   112     }
   113 
   114     virtual void * get_deleter( std::type_info const & ti ) = 0;
   115 
   116     void add_ref_copy()
   117     {
   118         atomic_increment( &use_count_ );
   119     }
   120 
   121     bool add_ref_lock() // true on success
   122     {
   123         return atomic_conditional_increment( &use_count_ ) != 0;
   124     }
   125 
   126     void release() // nothrow
   127     {
   128         if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
   129         {
   130             dispose();
   131             weak_release();
   132         }
   133     }
   134 
   135     void weak_add_ref() // nothrow
   136     {
   137         atomic_increment( &weak_count_ );
   138     }
   139 
   140     void weak_release() // nothrow
   141     {
   142         if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
   143         {
   144             destroy();
   145         }
   146     }
   147 
   148     long use_count() const // nothrow
   149     {
   150         return static_cast<int const volatile &>( use_count_ );
   151     }
   152 };
   153 
   154 } // namespace detail
   155 
   156 } // namespace boost
   157 
   158 #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED