]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / smart_ptr / detail / sp_counted_base_gcc_x86.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_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_gcc_x86.hpp - g++ on 486+ or AMD64
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/smart_ptr/detail/sp_typeinfo_.hpp>
28 #include <boost/smart_ptr/detail/sp_obsolete.hpp>
29 #include <boost/config.hpp>
30
31 #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
32
33 #include <boost/config/pragma_message.hpp>
34 BOOST_PRAGMA_MESSAGE("Using g++/x86 sp_counted_base")
35
36 #endif
37
38 BOOST_SP_OBSOLETE()
39
40 namespace boost
41 {
42
43 namespace detail
44 {
45
46 inline int atomic_exchange_and_add( int * pw, int dv )
47 {
48 // int r = *pw;
49 // *pw += dv;
50 // return r;
51
52 int r;
53
54 __asm__ __volatile__
55 (
56 "lock\n\t"
57 "xadd %1, %0":
58 "=m"( *pw ), "=r"( r ): // outputs (%0, %1)
59 "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
60 "memory", "cc" // clobbers
61 );
62
63 return r;
64 }
65
66 inline void atomic_increment( int * pw )
67 {
68 //atomic_exchange_and_add( pw, 1 );
69
70 __asm__
71 (
72 "lock\n\t"
73 "incl %0":
74 "=m"( *pw ): // output (%0)
75 "m"( *pw ): // input (%1)
76 "cc" // clobbers
77 );
78 }
79
80 inline int atomic_conditional_increment( int * pw )
81 {
82 // int rv = *pw;
83 // if( rv != 0 ) ++*pw;
84 // return rv;
85
86 int rv, tmp;
87
88 __asm__
89 (
90 "movl %0, %%eax\n\t"
91 "0:\n\t"
92 "test %%eax, %%eax\n\t"
93 "je 1f\n\t"
94 "movl %%eax, %2\n\t"
95 "incl %2\n\t"
96 "lock\n\t"
97 "cmpxchgl %2, %0\n\t"
98 "jne 0b\n\t"
99 "1:":
100 "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
101 "m"( *pw ): // input (%3)
102 "cc" // clobbers
103 );
104
105 return rv;
106 }
107
108 class BOOST_SYMBOL_VISIBLE sp_counted_base
109 {
110 private:
111
112 sp_counted_base( sp_counted_base const & );
113 sp_counted_base & operator= ( sp_counted_base const & );
114
115 int use_count_; // #shared
116 int weak_count_; // #weak + (#shared != 0)
117
118 public:
119
120 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
121 {
122 }
123
124 virtual ~sp_counted_base() // nothrow
125 {
126 }
127
128 // dispose() is called when use_count_ drops to zero, to release
129 // the resources managed by *this.
130
131 virtual void dispose() = 0; // nothrow
132
133 // destroy() is called when weak_count_ drops to zero.
134
135 virtual void destroy() // nothrow
136 {
137 delete this;
138 }
139
140 virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
141 virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
142 virtual void * get_untyped_deleter() = 0;
143
144 void add_ref_copy()
145 {
146 atomic_increment( &use_count_ );
147 }
148
149 bool add_ref_lock() // true on success
150 {
151 return atomic_conditional_increment( &use_count_ ) != 0;
152 }
153
154 void release() // nothrow
155 {
156 if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
157 {
158 dispose();
159 weak_release();
160 }
161 }
162
163 void weak_add_ref() // nothrow
164 {
165 atomic_increment( &weak_count_ );
166 }
167
168 void weak_release() // nothrow
169 {
170 if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
171 {
172 destroy();
173 }
174 }
175
176 long use_count() const // nothrow
177 {
178 return static_cast<int const volatile &>( use_count_ );
179 }
180 };
181
182 } // namespace detail
183
184 } // namespace boost
185
186 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED