]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / smart_ptr / detail / sp_counted_base_vacpp_ppc.hpp
CommitLineData
7c673cae
FG
1#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
2#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED
3
4//
5// detail/sp_counted_base_vacpp_ppc.hpp - xlC(vacpp) on POWER
6// based on: detail/sp_counted_base_w32.hpp
7//
8// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
9// Copyright 2004-2005 Peter Dimov
10// Copyright 2006 Michael van der Westhuizen
11// Copyright 2012 IBM Corp.
12//
13// Distributed under the Boost Software License, Version 1.0. (See
14// accompanying file LICENSE_1_0.txt or copy at
15// http://www.boost.org/LICENSE_1_0.txt)
16//
17//
18// Lock-free algorithm by Alexander Terekhov
19//
20// Thanks to Ben Hitchings for the #weak + (#shared != 0)
21// formulation
22//
23
92f5a8d4
TL
24#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
25#include <boost/config.hpp>
7c673cae
FG
26
27extern "builtin" void __lwsync(void);
28extern "builtin" void __isync(void);
29extern "builtin" int __fetch_and_add(volatile int* addr, int val);
30extern "builtin" int __compare_and_swap(volatile int*, int*, int);
31
32namespace boost
33{
34
35namespace detail
36{
37
38inline void atomic_increment( int *pw )
39{
40 // ++*pw;
41 __lwsync();
42 __fetch_and_add(pw, 1);
43 __isync();
44}
45
46inline int atomic_decrement( int *pw )
47{
48 // return --*pw;
49 __lwsync();
50 int originalValue = __fetch_and_add(pw, -1);
51 __isync();
52
53 return (originalValue - 1);
54}
55
56inline int atomic_conditional_increment( int *pw )
57{
58 // if( *pw != 0 ) ++*pw;
59 // return *pw;
60
61 __lwsync();
62 int v = *const_cast<volatile int*>(pw);
63 for (;;)
64 // loop until state is known
65 {
66 if (v == 0) return 0;
67 if (__compare_and_swap(pw, &v, v + 1))
68 {
69 __isync(); return (v + 1);
70 }
71 }
72}
73
92f5a8d4 74class BOOST_SYMBOL_VISIBLE sp_counted_base
7c673cae
FG
75{
76private:
77
78 sp_counted_base( sp_counted_base const & );
79 sp_counted_base & operator= ( sp_counted_base const & );
80
81 int use_count_; // #shared
82 int weak_count_; // #weak + (#shared != 0)
83 char pad[64] __attribute__((__aligned__(64)));
84 // pad to prevent false sharing
85public:
86
87 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
88 {
89 }
90
91 virtual ~sp_counted_base() // nothrow
92 {
93 }
94
95 // dispose() is called when use_count_ drops to zero, to release
96 // the resources managed by *this.
97
98 virtual void dispose() = 0; // nothrow
99
100 // destroy() is called when weak_count_ drops to zero.
101
102 virtual void destroy() // nothrow
103 {
104 delete this;
105 }
106
92f5a8d4
TL
107 virtual void * get_deleter( sp_typeinfo_ const & ti ) = 0;
108 virtual void * get_local_deleter( sp_typeinfo_ const & ti ) = 0;
7c673cae
FG
109 virtual void * get_untyped_deleter() = 0;
110
111 void add_ref_copy()
112 {
113 atomic_increment( &use_count_ );
114 }
115
116 bool add_ref_lock() // true on success
117 {
118 return atomic_conditional_increment( &use_count_ ) != 0;
119 }
120
121 void release() // nothrow
122 {
123 if( atomic_decrement( &use_count_ ) == 0 )
124 {
125 dispose();
126 weak_release();
127 }
128 }
129
130 void weak_add_ref() // nothrow
131 {
132 atomic_increment( &weak_count_ );
133 }
134
135 void weak_release() // nothrow
136 {
137 if( atomic_decrement( &weak_count_ ) == 0 )
138 {
139 destroy();
140 }
141 }
142
143 long use_count() const // nothrow
144 {
145 return *const_cast<volatile int*>(&use_count_);
146 }
147};
148
149} // namespace detail
150
151} // namespace boost
152
153#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_VACPP_PPC_HPP_INCLUDED