]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/lockfree/include/boost/lockfree/detail/tagged_ptr_ptrcompression.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / lockfree / include / boost / lockfree / detail / tagged_ptr_ptrcompression.hpp
1 // tagged pointer, for aba prevention
2 //
3 // Copyright (C) 2008, 2009, 2016 Tim Blechmann, based on code by Cory Nelson
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8
9 #ifndef BOOST_LOCKFREE_TAGGED_PTR_PTRCOMPRESSION_HPP_INCLUDED
10 #define BOOST_LOCKFREE_TAGGED_PTR_PTRCOMPRESSION_HPP_INCLUDED
11
12 #include <cstddef> /* for std::size_t */
13 #include <limits>
14
15 #include <boost/cstdint.hpp>
16 #include <boost/predef.h>
17
18 namespace boost {
19 namespace lockfree {
20 namespace detail {
21
22 #ifdef BOOST_ARCH_X86_64
23
24 template <class T>
25 class tagged_ptr
26 {
27 typedef boost::uint64_t compressed_ptr_t;
28
29 public:
30 typedef boost::uint16_t tag_t;
31
32 private:
33 union cast_unit
34 {
35 compressed_ptr_t value;
36 tag_t tag[4];
37 };
38
39 static const int tag_index = 3;
40 static const compressed_ptr_t ptr_mask = 0xffffffffffffUL; //(1L<<48L)-1;
41
42 static T* extract_ptr(volatile compressed_ptr_t const & i)
43 {
44 return (T*)(i & ptr_mask);
45 }
46
47 static tag_t extract_tag(volatile compressed_ptr_t const & i)
48 {
49 cast_unit cu;
50 cu.value = i;
51 return cu.tag[tag_index];
52 }
53
54 static compressed_ptr_t pack_ptr(T * ptr, tag_t tag)
55 {
56 cast_unit ret;
57 ret.value = compressed_ptr_t(ptr);
58 ret.tag[tag_index] = tag;
59 return ret.value;
60 }
61
62 public:
63 /** uninitialized constructor */
64 tagged_ptr(void) BOOST_NOEXCEPT//: ptr(0), tag(0)
65 {}
66
67 /** copy constructor */
68 #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
69 tagged_ptr(tagged_ptr const & p):
70 ptr(p.ptr)
71 {}
72 #else
73 tagged_ptr(tagged_ptr const & p) = default;
74 #endif
75
76 explicit tagged_ptr(T * p, tag_t t = 0):
77 ptr(pack_ptr(p, t))
78 {}
79
80 /** unsafe set operation */
81 /* @{ */
82 #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
83 tagged_ptr & operator= (tagged_ptr const & p)
84 {
85 ptr = p.ptr;
86 return *this;
87 }
88 #else
89 tagged_ptr & operator= (tagged_ptr const & p) = default;
90 #endif
91
92 void set(T * p, tag_t t)
93 {
94 ptr = pack_ptr(p, t);
95 }
96 /* @} */
97
98 /** comparing semantics */
99 /* @{ */
100 bool operator== (volatile tagged_ptr const & p) const
101 {
102 return (ptr == p.ptr);
103 }
104
105 bool operator!= (volatile tagged_ptr const & p) const
106 {
107 return !operator==(p);
108 }
109 /* @} */
110
111 /** pointer access */
112 /* @{ */
113 T * get_ptr() const
114 {
115 return extract_ptr(ptr);
116 }
117
118 void set_ptr(T * p)
119 {
120 tag_t tag = get_tag();
121 ptr = pack_ptr(p, tag);
122 }
123 /* @} */
124
125 /** tag access */
126 /* @{ */
127 tag_t get_tag() const
128 {
129 return extract_tag(ptr);
130 }
131
132 tag_t get_next_tag() const
133 {
134 tag_t next = (get_tag() + 1u) & (std::numeric_limits<tag_t>::max)();
135 return next;
136 }
137
138 void set_tag(tag_t t)
139 {
140 T * p = get_ptr();
141 ptr = pack_ptr(p, t);
142 }
143 /* @} */
144
145 /** smart pointer support */
146 /* @{ */
147 T & operator*() const
148 {
149 return *get_ptr();
150 }
151
152 T * operator->() const
153 {
154 return get_ptr();
155 }
156
157 operator bool(void) const
158 {
159 return get_ptr() != 0;
160 }
161 /* @} */
162
163 protected:
164 compressed_ptr_t ptr;
165 };
166 #else
167 #error unsupported platform
168 #endif
169
170 } /* namespace detail */
171 } /* namespace lockfree */
172 } /* namespace boost */
173
174 #endif /* BOOST_LOCKFREE_TAGGED_PTR_PTRCOMPRESSION_HPP_INCLUDED */