1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/detail/sp_counted_base_cw_ppc.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,170 @@
1.4 +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
1.5 +#define BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
1.6 +
1.7 +// MS compatible compilers support #pragma once
1.8 +
1.9 +#if defined(_MSC_VER) && (_MSC_VER >= 1020)
1.10 +# pragma once
1.11 +#endif
1.12 +
1.13 +//
1.14 +// detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC
1.15 +//
1.16 +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
1.17 +// Copyright 2004-2005 Peter Dimov
1.18 +//
1.19 +// Distributed under the Boost Software License, Version 1.0. (See
1.20 +// accompanying file LICENSE_1_0.txt or copy at
1.21 +// http://www.boost.org/LICENSE_1_0.txt)
1.22 +//
1.23 +//
1.24 +// Lock-free algorithm by Alexander Terekhov
1.25 +//
1.26 +// Thanks to Ben Hitchings for the #weak + (#shared != 0)
1.27 +// formulation
1.28 +//
1.29 +
1.30 +#include <typeinfo>
1.31 +
1.32 +namespace boost
1.33 +{
1.34 +
1.35 +namespace detail
1.36 +{
1.37 +
1.38 +inline void atomic_increment( register long * pw )
1.39 +{
1.40 + register int a;
1.41 +
1.42 + asm
1.43 + {
1.44 +loop:
1.45 +
1.46 + lwarx a, 0, pw
1.47 + addi a, a, 1
1.48 + stwcx. a, 0, pw
1.49 + bne- loop
1.50 + }
1.51 +}
1.52 +
1.53 +inline long atomic_decrement( register long * pw )
1.54 +{
1.55 + register int a;
1.56 +
1.57 + asm
1.58 + {
1.59 + sync
1.60 +
1.61 +loop:
1.62 +
1.63 + lwarx a, 0, pw
1.64 + addi a, a, -1
1.65 + stwcx. a, 0, pw
1.66 + bne- loop
1.67 +
1.68 + isync
1.69 + }
1.70 +
1.71 + return a;
1.72 +}
1.73 +
1.74 +inline long atomic_conditional_increment( register long * pw )
1.75 +{
1.76 + register int a;
1.77 +
1.78 + asm
1.79 + {
1.80 +loop:
1.81 +
1.82 + lwarx a, 0, pw
1.83 + cmpwi a, 0
1.84 + beq store
1.85 +
1.86 + addi a, a, 1
1.87 +
1.88 +store:
1.89 +
1.90 + stwcx. a, 0, pw
1.91 + bne- loop
1.92 + }
1.93 +
1.94 + return a;
1.95 +}
1.96 +
1.97 +class sp_counted_base
1.98 +{
1.99 +private:
1.100 +
1.101 + sp_counted_base( sp_counted_base const & );
1.102 + sp_counted_base & operator= ( sp_counted_base const & );
1.103 +
1.104 + long use_count_; // #shared
1.105 + long weak_count_; // #weak + (#shared != 0)
1.106 +
1.107 +public:
1.108 +
1.109 + sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
1.110 + {
1.111 + }
1.112 +
1.113 + virtual ~sp_counted_base() // nothrow
1.114 + {
1.115 + }
1.116 +
1.117 + // dispose() is called when use_count_ drops to zero, to release
1.118 + // the resources managed by *this.
1.119 +
1.120 + virtual void dispose() = 0; // nothrow
1.121 +
1.122 + // destroy() is called when weak_count_ drops to zero.
1.123 +
1.124 + virtual void destroy() // nothrow
1.125 + {
1.126 + delete this;
1.127 + }
1.128 +
1.129 + virtual void * get_deleter( std::type_info const & ti ) = 0;
1.130 +
1.131 + void add_ref_copy()
1.132 + {
1.133 + atomic_increment( &use_count_ );
1.134 + }
1.135 +
1.136 + bool add_ref_lock() // true on success
1.137 + {
1.138 + return atomic_conditional_increment( &use_count_ ) != 0;
1.139 + }
1.140 +
1.141 + void release() // nothrow
1.142 + {
1.143 + if( atomic_decrement( &use_count_ ) == 0 )
1.144 + {
1.145 + dispose();
1.146 + weak_release();
1.147 + }
1.148 + }
1.149 +
1.150 + void weak_add_ref() // nothrow
1.151 + {
1.152 + atomic_increment( &weak_count_ );
1.153 + }
1.154 +
1.155 + void weak_release() // nothrow
1.156 + {
1.157 + if( atomic_decrement( &weak_count_ ) == 0 )
1.158 + {
1.159 + destroy();
1.160 + }
1.161 + }
1.162 +
1.163 + long use_count() const // nothrow
1.164 + {
1.165 + return static_cast<long const volatile &>( use_count_ );
1.166 + }
1.167 +};
1.168 +
1.169 +} // namespace detail
1.170 +
1.171 +} // namespace boost
1.172 +
1.173 +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED