]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / smart_ptr / detail / sp_counted_base_gcc_ia64.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED
3
4 //
5 // detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64
6 //
7 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
8 // Copyright 2004-2006 Peter Dimov
9 // Copyright 2005 Ben Hutchings
10 //
11 // Distributed under the Boost Software License, Version 1.0. (See
12 // accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
14 //
15 //
16 // Lock-free algorithm by Alexander Terekhov
17 //
18
19 #include <boost/detail/sp_typeinfo.hpp>
20
21 namespace boost
22 {
23
24 namespace detail
25 {
26
27 inline void atomic_increment( int * pw )
28 {
29 // ++*pw;
30
31 int tmp;
32
33 // No barrier is required here but fetchadd always has an acquire or
34 // release barrier associated with it. We choose release as it should be
35 // cheaper.
36 __asm__ ("fetchadd4.rel %0=%1,1" :
37 "=r"(tmp), "=m"(*pw) :
38 "m"( *pw ));
39 }
40
41 inline int atomic_decrement( int * pw )
42 {
43 // return --*pw;
44
45 int rv;
46
47 __asm__ (" fetchadd4.rel %0=%1,-1 ;; \n"
48 " cmp.eq p7,p0=1,%0 ;; \n"
49 "(p7) ld4.acq %0=%1 " :
50 "=&r"(rv), "=m"(*pw) :
51 "m"( *pw ) :
52 "p7");
53
54 return rv;
55 }
56
57 inline int atomic_conditional_increment( int * pw )
58 {
59 // if( *pw != 0 ) ++*pw;
60 // return *pw;
61
62 int rv, tmp, tmp2;
63
64 __asm__ ("0: ld4 %0=%3 ;; \n"
65 " cmp.eq p7,p0=0,%0 ;; \n"
66 "(p7) br.cond.spnt 1f \n"
67 " mov ar.ccv=%0 \n"
68 " add %1=1,%0 ;; \n"
69 " cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n"
70 " cmp.ne p7,p0=%0,%2 ;; \n"
71 "(p7) br.cond.spnt 0b \n"
72 " mov %0=%1 ;; \n"
73 "1:" :
74 "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) :
75 "m"( *pw ) :
76 "ar.ccv", "p7");
77
78 return rv;
79 }
80
81 class sp_counted_base
82 {
83 private:
84
85 sp_counted_base( sp_counted_base const & );
86 sp_counted_base & operator= ( sp_counted_base const & );
87
88 int use_count_; // #shared
89 int weak_count_; // #weak + (#shared != 0)
90
91 public:
92
93 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
94 {
95 }
96
97 virtual ~sp_counted_base() // nothrow
98 {
99 }
100
101 // dispose() is called when use_count_ drops to zero, to release
102 // the resources managed by *this.
103
104 virtual void dispose() = 0; // nothrow
105
106 // destroy() is called when weak_count_ drops to zero.
107
108 virtual void destroy() // nothrow
109 {
110 delete this;
111 }
112
113 virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
114 virtual void * get_local_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_decrement( &use_count_ ) == 0 )
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_decrement( &weak_count_ ) == 0 )
144 {
145 destroy();
146 }
147 }
148
149 long use_count() const // nothrow
150 {
151 return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
152 }
153 };
154
155 } // namespace detail
156
157 } // namespace boost
158
159 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED