]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/smart_ptr/include/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / smart_ptr / include / boost / smart_ptr / detail / sp_counted_base_gcc_ppc.hpp
CommitLineData
7c673cae
FG
1#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED
2#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_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_gcc_ppc.hpp - g++ 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
27#include <boost/detail/sp_typeinfo.hpp>
28
29namespace boost
30{
31
32namespace detail
33{
34
35inline void atomic_increment( int * pw )
36{
37 // ++*pw;
38
39 int tmp;
40
41 __asm__
42 (
43 "0:\n\t"
44 "lwarx %1, 0, %2\n\t"
45 "addi %1, %1, 1\n\t"
46 "stwcx. %1, 0, %2\n\t"
47 "bne- 0b":
48
49 "=m"( *pw ), "=&b"( tmp ):
50 "r"( pw ), "m"( *pw ):
51 "cc"
52 );
53}
54
55inline int atomic_decrement( int * pw )
56{
57 // return --*pw;
58
59 int rv;
60
61 __asm__ __volatile__
62 (
63 "sync\n\t"
64 "0:\n\t"
65 "lwarx %1, 0, %2\n\t"
66 "addi %1, %1, -1\n\t"
67 "stwcx. %1, 0, %2\n\t"
68 "bne- 0b\n\t"
69 "isync":
70
71 "=m"( *pw ), "=&b"( rv ):
72 "r"( pw ), "m"( *pw ):
73 "memory", "cc"
74 );
75
76 return rv;
77}
78
79inline int atomic_conditional_increment( int * pw )
80{
81 // if( *pw != 0 ) ++*pw;
82 // return *pw;
83
84 int rv;
85
86 __asm__
87 (
88 "0:\n\t"
89 "lwarx %1, 0, %2\n\t"
90 "cmpwi %1, 0\n\t"
91 "beq 1f\n\t"
92 "addi %1, %1, 1\n\t"
93 "1:\n\t"
94 "stwcx. %1, 0, %2\n\t"
95 "bne- 0b":
96
97 "=m"( *pw ), "=&b"( rv ):
98 "r"( pw ), "m"( *pw ):
99 "cc"
100 );
101
102 return rv;
103}
104
105class sp_counted_base
106{
107private:
108
109 sp_counted_base( sp_counted_base const & );
110 sp_counted_base & operator= ( sp_counted_base const & );
111
112 int use_count_; // #shared
113 int 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
137 virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
138 virtual void * get_untyped_deleter() = 0;
139
140 void add_ref_copy()
141 {
142 atomic_increment( &use_count_ );
143 }
144
145 bool add_ref_lock() // true on success
146 {
147 return atomic_conditional_increment( &use_count_ ) != 0;
148 }
149
150 void release() // nothrow
151 {
152 if( atomic_decrement( &use_count_ ) == 0 )
153 {
154 dispose();
155 weak_release();
156 }
157 }
158
159 void weak_add_ref() // nothrow
160 {
161 atomic_increment( &weak_count_ );
162 }
163
164 void weak_release() // nothrow
165 {
166 if( atomic_decrement( &weak_count_ ) == 0 )
167 {
168 destroy();
169 }
170 }
171
172 long use_count() const // nothrow
173 {
174 return static_cast<int const volatile &>( use_count_ );
175 }
176};
177
178} // namespace detail
179
180} // namespace boost
181
182#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED