]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/smart_ptr/include/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / smart_ptr / include / boost / smart_ptr / detail / sp_counted_base_gcc_ia64.hpp
CommitLineData
7c673cae
FG
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
21namespace boost
22{
23
24namespace detail
25{
26
27inline 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
41inline 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
57inline 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
81class sp_counted_base
82{
83private:
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
91public:
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_untyped_deleter() = 0;
115
116 void add_ref_copy()
117 {
118 atomic_increment( &use_count_ );
119 }
120
121 bool add_ref_lock() // true on success
122 {
123 return atomic_conditional_increment( &use_count_ ) != 0;
124 }
125
126 void release() // nothrow
127 {
128 if( atomic_decrement( &use_count_ ) == 0 )
129 {
130 dispose();
131 weak_release();
132 }
133 }
134
135 void weak_add_ref() // nothrow
136 {
137 atomic_increment( &weak_count_ );
138 }
139
140 void weak_release() // nothrow
141 {
142 if( atomic_decrement( &weak_count_ ) == 0 )
143 {
144 destroy();
145 }
146 }
147
148 long use_count() const // nothrow
149 {
150 return static_cast<int const volatile &>( use_count_ ); // TODO use ld.acq here
151 }
152};
153
154} // namespace detail
155
156} // namespace boost
157
158#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED