]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/smart_ptr/include/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / smart_ptr / include / boost / smart_ptr / detail / sp_counted_base_cw_x86.hpp
CommitLineData
7c673cae
FG
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
30namespace boost
31{
32
33namespace detail
34{
35
36inline 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
50inline 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
61inline 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
82class sp_counted_base
83{
84private:
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
92public:
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_untyped_deleter() = 0;
116
117 void add_ref_copy()
118 {
119 atomic_increment( &use_count_ );
120 }
121
122 bool add_ref_lock() // true on success
123 {
124 return atomic_conditional_increment( &use_count_ ) != 0;
125 }
126
127 void release() // nothrow
128 {
129 if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
130 {
131 dispose();
132 weak_release();
133 }
134 }
135
136 void weak_add_ref() // nothrow
137 {
138 atomic_increment( &weak_count_ );
139 }
140
141 void weak_release() // nothrow
142 {
143 if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
144 {
145 destroy();
146 }
147 }
148
149 long use_count() const // nothrow
150 {
151 return static_cast<int const volatile &>( use_count_ );
152 }
153};
154
155} // namespace detail
156
157} // namespace boost
158
159#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED