annotate DEPENDENCIES/generic/include/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp @ 41:ed9f24243b59

OS/X fix
author Chris Cannam
date Thu, 07 Aug 2014 09:18:32 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
Chris@16 2 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
Chris@16 3
Chris@16 4 // MS compatible compilers support #pragma once
Chris@16 5
Chris@16 6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
Chris@16 7 # pragma once
Chris@16 8 #endif
Chris@16 9
Chris@16 10 //
Chris@16 11 // detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC
Chris@16 12 //
Chris@16 13 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
Chris@16 14 // Copyright 2004-2005 Peter Dimov
Chris@16 15 //
Chris@16 16 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 17 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 18 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 19 //
Chris@16 20 //
Chris@16 21 // Lock-free algorithm by Alexander Terekhov
Chris@16 22 //
Chris@16 23 // Thanks to Ben Hitchings for the #weak + (#shared != 0)
Chris@16 24 // formulation
Chris@16 25 //
Chris@16 26
Chris@16 27 #include <boost/detail/sp_typeinfo.hpp>
Chris@16 28
Chris@16 29 namespace boost
Chris@16 30 {
Chris@16 31
Chris@16 32 namespace detail
Chris@16 33 {
Chris@16 34
Chris@16 35 inline void atomic_increment( register long * pw )
Chris@16 36 {
Chris@16 37 register int a;
Chris@16 38
Chris@16 39 asm
Chris@16 40 {
Chris@16 41 loop:
Chris@16 42
Chris@16 43 lwarx a, 0, pw
Chris@16 44 addi a, a, 1
Chris@16 45 stwcx. a, 0, pw
Chris@16 46 bne- loop
Chris@16 47 }
Chris@16 48 }
Chris@16 49
Chris@16 50 inline long atomic_decrement( register long * pw )
Chris@16 51 {
Chris@16 52 register int a;
Chris@16 53
Chris@16 54 asm
Chris@16 55 {
Chris@16 56 sync
Chris@16 57
Chris@16 58 loop:
Chris@16 59
Chris@16 60 lwarx a, 0, pw
Chris@16 61 addi a, a, -1
Chris@16 62 stwcx. a, 0, pw
Chris@16 63 bne- loop
Chris@16 64
Chris@16 65 isync
Chris@16 66 }
Chris@16 67
Chris@16 68 return a;
Chris@16 69 }
Chris@16 70
Chris@16 71 inline long atomic_conditional_increment( register long * pw )
Chris@16 72 {
Chris@16 73 register int a;
Chris@16 74
Chris@16 75 asm
Chris@16 76 {
Chris@16 77 loop:
Chris@16 78
Chris@16 79 lwarx a, 0, pw
Chris@16 80 cmpwi a, 0
Chris@16 81 beq store
Chris@16 82
Chris@16 83 addi a, a, 1
Chris@16 84
Chris@16 85 store:
Chris@16 86
Chris@16 87 stwcx. a, 0, pw
Chris@16 88 bne- loop
Chris@16 89 }
Chris@16 90
Chris@16 91 return a;
Chris@16 92 }
Chris@16 93
Chris@16 94 class sp_counted_base
Chris@16 95 {
Chris@16 96 private:
Chris@16 97
Chris@16 98 sp_counted_base( sp_counted_base const & );
Chris@16 99 sp_counted_base & operator= ( sp_counted_base const & );
Chris@16 100
Chris@16 101 long use_count_; // #shared
Chris@16 102 long weak_count_; // #weak + (#shared != 0)
Chris@16 103
Chris@16 104 public:
Chris@16 105
Chris@16 106 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
Chris@16 107 {
Chris@16 108 }
Chris@16 109
Chris@16 110 virtual ~sp_counted_base() // nothrow
Chris@16 111 {
Chris@16 112 }
Chris@16 113
Chris@16 114 // dispose() is called when use_count_ drops to zero, to release
Chris@16 115 // the resources managed by *this.
Chris@16 116
Chris@16 117 virtual void dispose() = 0; // nothrow
Chris@16 118
Chris@16 119 // destroy() is called when weak_count_ drops to zero.
Chris@16 120
Chris@16 121 virtual void destroy() // nothrow
Chris@16 122 {
Chris@16 123 delete this;
Chris@16 124 }
Chris@16 125
Chris@16 126 virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
Chris@16 127 virtual void * get_untyped_deleter() = 0;
Chris@16 128
Chris@16 129 void add_ref_copy()
Chris@16 130 {
Chris@16 131 atomic_increment( &use_count_ );
Chris@16 132 }
Chris@16 133
Chris@16 134 bool add_ref_lock() // true on success
Chris@16 135 {
Chris@16 136 return atomic_conditional_increment( &use_count_ ) != 0;
Chris@16 137 }
Chris@16 138
Chris@16 139 void release() // nothrow
Chris@16 140 {
Chris@16 141 if( atomic_decrement( &use_count_ ) == 0 )
Chris@16 142 {
Chris@16 143 dispose();
Chris@16 144 weak_release();
Chris@16 145 }
Chris@16 146 }
Chris@16 147
Chris@16 148 void weak_add_ref() // nothrow
Chris@16 149 {
Chris@16 150 atomic_increment( &weak_count_ );
Chris@16 151 }
Chris@16 152
Chris@16 153 void weak_release() // nothrow
Chris@16 154 {
Chris@16 155 if( atomic_decrement( &weak_count_ ) == 0 )
Chris@16 156 {
Chris@16 157 destroy();
Chris@16 158 }
Chris@16 159 }
Chris@16 160
Chris@16 161 long use_count() const // nothrow
Chris@16 162 {
Chris@16 163 return static_cast<long const volatile &>( use_count_ );
Chris@16 164 }
Chris@16 165 };
Chris@16 166
Chris@16 167 } // namespace detail
Chris@16 168
Chris@16 169 } // namespace boost
Chris@16 170
Chris@16 171 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED