epoc32/include/stdapis/boost/detail/sp_counted_base_cw_ppc.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     1 #ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
     2 #define BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_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_ppc.hpp - CodeWarrior on PowerPC
    12 //
    13 //  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
    14 //  Copyright 2004-2005 Peter Dimov
    15 //
    16 //  Distributed under the Boost Software License, Version 1.0. (See
    17 //  accompanying file LICENSE_1_0.txt or copy at
    18 //  http://www.boost.org/LICENSE_1_0.txt)
    19 //
    20 //
    21 //  Lock-free algorithm by Alexander Terekhov
    22 //
    23 //  Thanks to Ben Hitchings for the #weak + (#shared != 0)
    24 //  formulation
    25 //
    26 
    27 #include <typeinfo>
    28 
    29 namespace boost
    30 {
    31 
    32 namespace detail
    33 {
    34 
    35 inline void atomic_increment( register long * pw )
    36 {
    37     register int a;
    38 
    39     asm
    40     {
    41 loop:
    42 
    43     lwarx   a, 0, pw
    44     addi    a, a, 1
    45     stwcx.  a, 0, pw
    46     bne-    loop
    47     }
    48 }
    49 
    50 inline long atomic_decrement( register long * pw )
    51 {
    52     register int a;
    53 
    54     asm
    55     {
    56     sync
    57 
    58 loop:
    59 
    60     lwarx   a, 0, pw
    61     addi    a, a, -1
    62     stwcx.  a, 0, pw
    63     bne-    loop
    64 
    65     isync
    66     }
    67 
    68     return a;
    69 }
    70 
    71 inline long atomic_conditional_increment( register long * pw )
    72 {
    73     register int a;
    74 
    75     asm
    76     {
    77 loop:
    78 
    79     lwarx   a, 0, pw
    80     cmpwi   a, 0
    81     beq     store
    82 
    83     addi    a, a, 1
    84 
    85 store:
    86 
    87     stwcx.  a, 0, pw
    88     bne-    loop
    89     }
    90 
    91     return a;
    92 }
    93 
    94 class sp_counted_base
    95 {
    96 private:
    97 
    98     sp_counted_base( sp_counted_base const & );
    99     sp_counted_base & operator= ( sp_counted_base const & );
   100 
   101     long use_count_;        // #shared
   102     long weak_count_;       // #weak + (#shared != 0)
   103 
   104 public:
   105 
   106     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
   107     {
   108     }
   109 
   110     virtual ~sp_counted_base() // nothrow
   111     {
   112     }
   113 
   114     // dispose() is called when use_count_ drops to zero, to release
   115     // the resources managed by *this.
   116 
   117     virtual void dispose() = 0; // nothrow
   118 
   119     // destroy() is called when weak_count_ drops to zero.
   120 
   121     virtual void destroy() // nothrow
   122     {
   123         delete this;
   124     }
   125 
   126     virtual void * get_deleter( std::type_info const & ti ) = 0;
   127 
   128     void add_ref_copy()
   129     {
   130         atomic_increment( &use_count_ );
   131     }
   132 
   133     bool add_ref_lock() // true on success
   134     {
   135         return atomic_conditional_increment( &use_count_ ) != 0;
   136     }
   137 
   138     void release() // nothrow
   139     {
   140         if( atomic_decrement( &use_count_ ) == 0 )
   141         {
   142             dispose();
   143             weak_release();
   144         }
   145     }
   146 
   147     void weak_add_ref() // nothrow
   148     {
   149         atomic_increment( &weak_count_ );
   150     }
   151 
   152     void weak_release() // nothrow
   153     {
   154         if( atomic_decrement( &weak_count_ ) == 0 )
   155         {
   156             destroy();
   157         }
   158     }
   159 
   160     long use_count() const // nothrow
   161     {
   162         return static_cast<long const volatile &>( use_count_ );
   163     }
   164 };
   165 
   166 } // namespace detail
   167 
   168 } // namespace boost
   169 
   170 #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED