]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/detail/sp_counted_base_sync.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / smart_ptr / detail / sp_counted_base_sync.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_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 // detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics
11 //
12 // Copyright (c) 2007 Peter Dimov
13 //
14 // Distributed under the Boost Software License, Version 1.0.
15 // See accompanying file LICENSE_1_0.txt or copy at
16 // http://www.boost.org/LICENSE_1_0.txt
17
18 #include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
19 #include <boost/config.hpp>
20 #include <limits.h>
21
22 #if defined( __ia64__ ) && defined( __INTEL_COMPILER )
23 # include <ia64intrin.h>
24 #endif
25
26 #if defined(BOOST_SP_REPORT_IMPLEMENTATION)
27
28 #include <boost/config/pragma_message.hpp>
29 BOOST_PRAGMA_MESSAGE("Using __sync sp_counted_base")
30
31 #endif
32
33 namespace boost
34 {
35
36 namespace detail
37 {
38
39 #if INT_MAX >= 2147483647
40
41 typedef int sp_int32_t;
42
43 #else
44
45 typedef long sp_int32_t;
46
47 #endif
48
49 inline void atomic_increment( sp_int32_t * pw )
50 {
51 __sync_fetch_and_add( pw, 1 );
52 }
53
54 inline sp_int32_t atomic_decrement( sp_int32_t * pw )
55 {
56 return __sync_fetch_and_add( pw, -1 );
57 }
58
59 inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw )
60 {
61 // long r = *pw;
62 // if( r != 0 ) ++*pw;
63 // return r;
64
65 sp_int32_t r = *pw;
66
67 for( ;; )
68 {
69 if( r == 0 )
70 {
71 return r;
72 }
73
74 sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 );
75
76 if( r2 == r )
77 {
78 return r;
79 }
80 else
81 {
82 r = r2;
83 }
84 }
85 }
86
87 class BOOST_SYMBOL_VISIBLE sp_counted_base
88 {
89 private:
90
91 sp_counted_base( sp_counted_base const & );
92 sp_counted_base & operator= ( sp_counted_base const & );
93
94 sp_int32_t use_count_; // #shared
95 sp_int32_t weak_count_; // #weak + (#shared != 0)
96
97 public:
98
99 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
100 {
101 }
102
103 virtual ~sp_counted_base() // nothrow
104 {
105 }
106
107 // dispose() is called when use_count_ drops to zero, to release
108 // the resources managed by *this.
109
110 virtual void dispose() = 0; // nothrow
111
112 // destroy() is called when weak_count_ drops to zero.
113
114 virtual void destroy() // nothrow
115 {
116 delete this;
117 }
118
119 virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
120 virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
121 virtual void * get_untyped_deleter() = 0;
122
123 void add_ref_copy()
124 {
125 atomic_increment( &use_count_ );
126 }
127
128 bool add_ref_lock() // true on success
129 {
130 return atomic_conditional_increment( &use_count_ ) != 0;
131 }
132
133 void release() // nothrow
134 {
135 if( atomic_decrement( &use_count_ ) == 1 )
136 {
137 dispose();
138 weak_release();
139 }
140 }
141
142 void weak_add_ref() // nothrow
143 {
144 atomic_increment( &weak_count_ );
145 }
146
147 void weak_release() // nothrow
148 {
149 if( atomic_decrement( &weak_count_ ) == 1 )
150 {
151 destroy();
152 }
153 }
154
155 long use_count() const // nothrow
156 {
157 return const_cast< sp_int32_t const volatile & >( use_count_ );
158 }
159 };
160
161 } // namespace detail
162
163 } // namespace boost
164
165 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED