]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / smart_ptr / detail / sp_counted_base_cw_x86.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_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_x86.hpp - CodeWarrion on 486+
12 //
13 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
14 // Copyright 2004-2005 Peter Dimov
15 // Copyright 2005 Rene Rivera
16 //
17 // Distributed under the Boost Software License, Version 1.0. (See
18 // accompanying file LICENSE_1_0.txt or copy at
19 // http://www.boost.org/LICENSE_1_0.txt)
20 //
21 //
22 // Lock-free algorithm by Alexander Terekhov
23 //
24 // Thanks to Ben Hitchings for the #weak + (#shared != 0)
25 // formulation
26 //
27
28 #include <boost/detail/sp_typeinfo.hpp>
29
30 namespace boost
31 {
32
33 namespace detail
34 {
35
36 inline int atomic_exchange_and_add( int * pw, int dv )
37 {
38 // int r = *pw;
39 // *pw += dv;
40 // return r;
41
42 asm
43 {
44 mov esi, [pw]
45 mov eax, dv
46 lock xadd dword ptr [esi], eax
47 }
48 }
49
50 inline void atomic_increment( int * pw )
51 {
52 //atomic_exchange_and_add( pw, 1 );
53
54 asm
55 {
56 mov esi, [pw]
57 lock inc dword ptr [esi]
58 }
59 }
60
61 inline int atomic_conditional_increment( int * pw )
62 {
63 // int rv = *pw;
64 // if( rv != 0 ) ++*pw;
65 // return rv;
66
67 asm
68 {
69 mov esi, [pw]
70 mov eax, dword ptr [esi]
71 L0:
72 test eax, eax
73 je L1
74 mov ebx, eax
75 inc ebx
76 lock cmpxchg dword ptr [esi], ebx
77 jne L0
78 L1:
79 }
80 }
81
82 class sp_counted_base
83 {
84 private:
85
86 sp_counted_base( sp_counted_base const & );
87 sp_counted_base & operator= ( sp_counted_base const & );
88
89 int use_count_; // #shared
90 int weak_count_; // #weak + (#shared != 0)
91
92 public:
93
94 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
95 {
96 }
97
98 virtual ~sp_counted_base() // nothrow
99 {
100 }
101
102 // dispose() is called when use_count_ drops to zero, to release
103 // the resources managed by *this.
104
105 virtual void dispose() = 0; // nothrow
106
107 // destroy() is called when weak_count_ drops to zero.
108
109 virtual void destroy() // nothrow
110 {
111 delete this;
112 }
113
114 virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
115 virtual void * get_local_deleter( sp_typeinfo const & ti ) = 0;
116 virtual void * get_untyped_deleter() = 0;
117
118 void add_ref_copy()
119 {
120 atomic_increment( &use_count_ );
121 }
122
123 bool add_ref_lock() // true on success
124 {
125 return atomic_conditional_increment( &use_count_ ) != 0;
126 }
127
128 void release() // nothrow
129 {
130 if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
131 {
132 dispose();
133 weak_release();
134 }
135 }
136
137 void weak_add_ref() // nothrow
138 {
139 atomic_increment( &weak_count_ );
140 }
141
142 void weak_release() // nothrow
143 {
144 if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
145 {
146 destroy();
147 }
148 }
149
150 long use_count() const // nothrow
151 {
152 return static_cast<int const volatile &>( use_count_ );
153 }
154 };
155
156 } // namespace detail
157
158 } // namespace boost
159
160 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED