1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/detail/sp_counted_base_cw_x86.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,158 @@
1.4 +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
1.5 +#define BOOST_DETAIL_SP_COUNTED_BASE_CW_X86_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_x86.hpp - CodeWarrion on 486+
1.15 +//
1.16 +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
1.17 +// Copyright 2004-2005 Peter Dimov
1.18 +// Copyright 2005 Rene Rivera
1.19 +//
1.20 +// Distributed under the Boost Software License, Version 1.0. (See
1.21 +// accompanying file LICENSE_1_0.txt or copy at
1.22 +// http://www.boost.org/LICENSE_1_0.txt)
1.23 +//
1.24 +//
1.25 +// Lock-free algorithm by Alexander Terekhov
1.26 +//
1.27 +// Thanks to Ben Hitchings for the #weak + (#shared != 0)
1.28 +// formulation
1.29 +//
1.30 +
1.31 +#include <typeinfo>
1.32 +
1.33 +namespace boost
1.34 +{
1.35 +
1.36 +namespace detail
1.37 +{
1.38 +
1.39 +inline int atomic_exchange_and_add( int * pw, int dv )
1.40 +{
1.41 + // int r = *pw;
1.42 + // *pw += dv;
1.43 + // return r;
1.44 +
1.45 + asm
1.46 + {
1.47 + mov esi, [pw]
1.48 + mov eax, dv
1.49 + lock xadd dword ptr [esi], eax
1.50 + }
1.51 +}
1.52 +
1.53 +inline void atomic_increment( int * pw )
1.54 +{
1.55 + //atomic_exchange_and_add( pw, 1 );
1.56 +
1.57 + asm
1.58 + {
1.59 + mov esi, [pw]
1.60 + lock inc dword ptr [esi]
1.61 + }
1.62 +}
1.63 +
1.64 +inline int atomic_conditional_increment( int * pw )
1.65 +{
1.66 + // int rv = *pw;
1.67 + // if( rv != 0 ) ++*pw;
1.68 + // return rv;
1.69 +
1.70 + asm
1.71 + {
1.72 + mov esi, [pw]
1.73 + mov eax, dword ptr [esi]
1.74 + L0:
1.75 + test eax, eax
1.76 + je L1
1.77 + mov ebx, eax
1.78 + inc ebx
1.79 + lock cmpxchg dword ptr [esi], ebx
1.80 + jne L0
1.81 + L1:
1.82 + }
1.83 +}
1.84 +
1.85 +class sp_counted_base
1.86 +{
1.87 +private:
1.88 +
1.89 + sp_counted_base( sp_counted_base const & );
1.90 + sp_counted_base & operator= ( sp_counted_base const & );
1.91 +
1.92 + int use_count_; // #shared
1.93 + int weak_count_; // #weak + (#shared != 0)
1.94 +
1.95 +public:
1.96 +
1.97 + sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
1.98 + {
1.99 + }
1.100 +
1.101 + virtual ~sp_counted_base() // nothrow
1.102 + {
1.103 + }
1.104 +
1.105 + // dispose() is called when use_count_ drops to zero, to release
1.106 + // the resources managed by *this.
1.107 +
1.108 + virtual void dispose() = 0; // nothrow
1.109 +
1.110 + // destroy() is called when weak_count_ drops to zero.
1.111 +
1.112 + virtual void destroy() // nothrow
1.113 + {
1.114 + delete this;
1.115 + }
1.116 +
1.117 + virtual void * get_deleter( std::type_info const & ti ) = 0;
1.118 +
1.119 + void add_ref_copy()
1.120 + {
1.121 + atomic_increment( &use_count_ );
1.122 + }
1.123 +
1.124 + bool add_ref_lock() // true on success
1.125 + {
1.126 + return atomic_conditional_increment( &use_count_ ) != 0;
1.127 + }
1.128 +
1.129 + void release() // nothrow
1.130 + {
1.131 + if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
1.132 + {
1.133 + dispose();
1.134 + weak_release();
1.135 + }
1.136 + }
1.137 +
1.138 + void weak_add_ref() // nothrow
1.139 + {
1.140 + atomic_increment( &weak_count_ );
1.141 + }
1.142 +
1.143 + void weak_release() // nothrow
1.144 + {
1.145 + if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
1.146 + {
1.147 + destroy();
1.148 + }
1.149 + }
1.150 +
1.151 + long use_count() const // nothrow
1.152 + {
1.153 + return static_cast<int const volatile &>( use_count_ );
1.154 + }
1.155 +};
1.156 +
1.157 +} // namespace detail
1.158 +
1.159 +} // namespace boost
1.160 +
1.161 +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED