]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / boost / boost / smart_ptr / detail / sp_counted_base_cw_ppc.hpp
CommitLineData
7c673cae
FG
1#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED
2#define BOOST_SMART_PTR_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
92f5a8d4 27#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
20effc67 28#include <boost/smart_ptr/detail/sp_obsolete.hpp>
92f5a8d4 29#include <boost/config.hpp>
7c673cae 30
20effc67
TL
31#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
32
33#include <boost/config/pragma_message.hpp>
34BOOST_PRAGMA_MESSAGE("Using CodeWarrior/PowerPC sp_counted_base")
35
36#endif
37
38BOOST_SP_OBSOLETE()
39
7c673cae
FG
40namespace boost
41{
42
43namespace detail
44{
45
46inline void atomic_increment( register long * pw )
47{
48 register int a;
49
50 asm
51 {
52loop:
53
54 lwarx a, 0, pw
55 addi a, a, 1
56 stwcx. a, 0, pw
57 bne- loop
58 }
59}
60
61inline long atomic_decrement( register long * pw )
62{
63 register int a;
64
65 asm
66 {
67 sync
68
69loop:
70
71 lwarx a, 0, pw
72 addi a, a, -1
73 stwcx. a, 0, pw
74 bne- loop
75
76 isync
77 }
78
79 return a;
80}
81
82inline long atomic_conditional_increment( register long * pw )
83{
84 register int a;
85
86 asm
87 {
88loop:
89
90 lwarx a, 0, pw
91 cmpwi a, 0
92 beq store
93
94 addi a, a, 1
95
96store:
97
98 stwcx. a, 0, pw
99 bne- loop
100 }
101
102 return a;
103}
104
92f5a8d4 105class BOOST_SYMBOL_VISIBLE sp_counted_base
7c673cae
FG
106{
107private:
108
109 sp_counted_base( sp_counted_base const & );
110 sp_counted_base & operator= ( sp_counted_base const & );
111
112 long use_count_; // #shared
113 long weak_count_; // #weak + (#shared != 0)
114
115public:
116
117 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
118 {
119 }
120
121 virtual ~sp_counted_base() // nothrow
122 {
123 }
124
125 // dispose() is called when use_count_ drops to zero, to release
126 // the resources managed by *this.
127
128 virtual void dispose() = 0; // nothrow
129
130 // destroy() is called when weak_count_ drops to zero.
131
132 virtual void destroy() // nothrow
133 {
134 delete this;
135 }
136
92f5a8d4
TL
137 virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
138 virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
7c673cae
FG
139 virtual void * get_untyped_deleter() = 0;
140
141 void add_ref_copy()
142 {
143 atomic_increment( &use_count_ );
144 }
145
146 bool add_ref_lock() // true on success
147 {
148 return atomic_conditional_increment( &use_count_ ) != 0;
149 }
150
151 void release() // nothrow
152 {
153 if( atomic_decrement( &use_count_ ) == 0 )
154 {
155 dispose();
156 weak_release();
157 }
158 }
159
160 void weak_add_ref() // nothrow
161 {
162 atomic_increment( &weak_count_ );
163 }
164
165 void weak_release() // nothrow
166 {
167 if( atomic_decrement( &weak_count_ ) == 0 )
168 {
169 destroy();
170 }
171 }
172
173 long use_count() const // nothrow
174 {
175 return static_cast<long const volatile &>( use_count_ );
176 }
177};
178
179} // namespace detail
180
181} // namespace boost
182
183#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED