1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/detail/sp_counted_base_gcc_ppc.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,181 @@
1.4 +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
1.5 +#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_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_gcc_ppc.hpp - g++ 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( int * pw )
1.39 +{
1.40 + // ++*pw;
1.41 +
1.42 + int tmp;
1.43 +
1.44 + __asm__
1.45 + (
1.46 + "0:\n\t"
1.47 + "lwarx %1, 0, %2\n\t"
1.48 + "addi %1, %1, 1\n\t"
1.49 + "stwcx. %1, 0, %2\n\t"
1.50 + "bne- 0b":
1.51 +
1.52 + "=m"( *pw ), "=&b"( tmp ):
1.53 + "r"( pw ), "m"( *pw ):
1.54 + "cc"
1.55 + );
1.56 +}
1.57 +
1.58 +inline int atomic_decrement( int * pw )
1.59 +{
1.60 + // return --*pw;
1.61 +
1.62 + int rv;
1.63 +
1.64 + __asm__ __volatile__
1.65 + (
1.66 + "sync\n\t"
1.67 + "0:\n\t"
1.68 + "lwarx %1, 0, %2\n\t"
1.69 + "addi %1, %1, -1\n\t"
1.70 + "stwcx. %1, 0, %2\n\t"
1.71 + "bne- 0b\n\t"
1.72 + "isync":
1.73 +
1.74 + "=m"( *pw ), "=&b"( rv ):
1.75 + "r"( pw ), "m"( *pw ):
1.76 + "memory", "cc"
1.77 + );
1.78 +
1.79 + return rv;
1.80 +}
1.81 +
1.82 +inline int atomic_conditional_increment( int * pw )
1.83 +{
1.84 + // if( *pw != 0 ) ++*pw;
1.85 + // return *pw;
1.86 +
1.87 + int rv;
1.88 +
1.89 + __asm__
1.90 + (
1.91 + "0:\n\t"
1.92 + "lwarx %1, 0, %2\n\t"
1.93 + "cmpwi %1, 0\n\t"
1.94 + "beq 1f\n\t"
1.95 + "addi %1, %1, 1\n\t"
1.96 + "1:\n\t"
1.97 + "stwcx. %1, 0, %2\n\t"
1.98 + "bne- 0b":
1.99 +
1.100 + "=m"( *pw ), "=&b"( rv ):
1.101 + "r"( pw ), "m"( *pw ):
1.102 + "cc"
1.103 + );
1.104 +
1.105 + return rv;
1.106 +}
1.107 +
1.108 +class sp_counted_base
1.109 +{
1.110 +private:
1.111 +
1.112 + sp_counted_base( sp_counted_base const & );
1.113 + sp_counted_base & operator= ( sp_counted_base const & );
1.114 +
1.115 + int use_count_; // #shared
1.116 + int weak_count_; // #weak + (#shared != 0)
1.117 +
1.118 +public:
1.119 +
1.120 + sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
1.121 + {
1.122 + }
1.123 +
1.124 + virtual ~sp_counted_base() // nothrow
1.125 + {
1.126 + }
1.127 +
1.128 + // dispose() is called when use_count_ drops to zero, to release
1.129 + // the resources managed by *this.
1.130 +
1.131 + virtual void dispose() = 0; // nothrow
1.132 +
1.133 + // destroy() is called when weak_count_ drops to zero.
1.134 +
1.135 + virtual void destroy() // nothrow
1.136 + {
1.137 + delete this;
1.138 + }
1.139 +
1.140 + virtual void * get_deleter( std::type_info const & ti ) = 0;
1.141 +
1.142 + void add_ref_copy()
1.143 + {
1.144 + atomic_increment( &use_count_ );
1.145 + }
1.146 +
1.147 + bool add_ref_lock() // true on success
1.148 + {
1.149 + return atomic_conditional_increment( &use_count_ ) != 0;
1.150 + }
1.151 +
1.152 + void release() // nothrow
1.153 + {
1.154 + if( atomic_decrement( &use_count_ ) == 0 )
1.155 + {
1.156 + dispose();
1.157 + weak_release();
1.158 + }
1.159 + }
1.160 +
1.161 + void weak_add_ref() // nothrow
1.162 + {
1.163 + atomic_increment( &weak_count_ );
1.164 + }
1.165 +
1.166 + void weak_release() // nothrow
1.167 + {
1.168 + if( atomic_decrement( &weak_count_ ) == 0 )
1.169 + {
1.170 + destroy();
1.171 + }
1.172 + }
1.173 +
1.174 + long use_count() const // nothrow
1.175 + {
1.176 + return static_cast<int const volatile &>( use_count_ );
1.177 + }
1.178 +};
1.179 +
1.180 +} // namespace detail
1.181 +
1.182 +} // namespace boost
1.183 +
1.184 +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED