]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/interprocess/include/boost/interprocess/smart_ptr/detail/sp_counted_base_atomic.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / interprocess / include / boost / interprocess / smart_ptr / detail / sp_counted_base_atomic.hpp
1 #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
2 #define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED
3
4 #ifndef BOOST_CONFIG_HPP
5 # include <boost/config.hpp>
6 #endif
7 #
8 #if defined(BOOST_HAS_PRAGMA_ONCE)
9 # pragma once
10 #endif
11
12 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
13 // Copyright 2004-2005 Peter Dimov
14 // Copyright 2007-2012 Ion Gaztanaga
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/interprocess/detail/config_begin.hpp>
28 #include <boost/interprocess/detail/workaround.hpp>
29
30 #include <boost/interprocess/detail/atomic.hpp>
31 #include <typeinfo>
32
33 namespace boost {
34
35 namespace interprocess {
36
37 namespace ipcdetail {
38
39 class sp_counted_base
40 {
41 private:
42
43 sp_counted_base( sp_counted_base const & );
44 sp_counted_base & operator= ( sp_counted_base const & );
45
46 boost::uint32_t use_count_; // #shared
47 boost::uint32_t weak_count_; // #weak + (#shared != 0)
48
49 public:
50
51 sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
52 {}
53
54 ~sp_counted_base() // nothrow
55 {}
56
57 void add_ref_copy()
58 {
59 ipcdetail::atomic_inc32( &use_count_ );
60 }
61
62 bool add_ref_lock() // true on success
63 {
64 for( ;; )
65 {
66 boost::uint32_t tmp = static_cast< boost::uint32_t const volatile& >( use_count_ );
67 if( tmp == 0 ) return false;
68 if( ipcdetail::atomic_cas32( &use_count_, tmp + 1, tmp ) == tmp )
69 return true;
70 }
71 }
72
73 bool ref_release() // nothrow
74 { return 1 == ipcdetail::atomic_dec32( &use_count_ ); }
75
76 void weak_add_ref() // nothrow
77 { ipcdetail::atomic_inc32( &weak_count_ ); }
78
79 bool weak_release() // nothrow
80 { return 1 == ipcdetail::atomic_dec32( &weak_count_ ); }
81
82 long use_count() const // nothrow
83 { return (long)static_cast<boost::uint32_t const volatile &>( use_count_ ); }
84 };
85
86 } // namespace ipcdetail
87
88 } // namespace interprocess
89
90 } // namespace boost
91
92 #include <boost/interprocess/detail/config_end.hpp>
93
94 #endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED