]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/lockfree/detail/tagged_ptr_ptrcompression.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / lockfree / detail / tagged_ptr_ptrcompression.hpp
CommitLineData
7c673cae
FG
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
18namespace boost {
19namespace lockfree {
20namespace detail {
21
92f5a8d4 22#if BOOST_ARCH_X86_64 || defined (__aarch64__)
7c673cae
FG
23
24template <class T>
25class tagged_ptr
26{
27 typedef boost::uint64_t compressed_ptr_t;
28
29public:
30 typedef boost::uint16_t tag_t;
31
32private:
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
62public:
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
163protected:
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 */