]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // tagged pointer, for aba prevention |
2 | // | |
3 | // Copyright (C) 2008, 2016 Tim Blechmann | |
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_DCAS_HPP_INCLUDED | |
10 | #define BOOST_LOCKFREE_TAGGED_PTR_DCAS_HPP_INCLUDED | |
11 | ||
12 | #include <cstddef> /* for std::size_t */ | |
13 | #include <limits> | |
14 | ||
15 | #include <boost/predef.h> | |
16 | ||
17 | namespace boost { | |
18 | namespace lockfree { | |
19 | namespace detail { | |
20 | ||
21 | ||
22 | ||
23 | template <class T> | |
24 | class BOOST_ALIGNMENT(2 * sizeof(void*)) tagged_ptr | |
25 | { | |
26 | public: | |
27 | typedef std::size_t tag_t; | |
28 | ||
29 | /** uninitialized constructor */ | |
30 | tagged_ptr(void) BOOST_NOEXCEPT//: ptr(0), tag(0) | |
31 | {} | |
32 | ||
33 | #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS | |
34 | tagged_ptr(tagged_ptr const & p): | |
35 | ptr(p.ptr), tag(p.tag) | |
36 | {} | |
37 | #else | |
38 | tagged_ptr(tagged_ptr const & p) = default; | |
39 | #endif | |
40 | ||
41 | explicit tagged_ptr(T * p, tag_t t = 0): | |
42 | ptr(p), tag(t) | |
43 | {} | |
44 | ||
45 | /** unsafe set operation */ | |
46 | /* @{ */ | |
47 | #ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS | |
48 | tagged_ptr & operator= (tagged_ptr const & p) | |
49 | { | |
50 | set(p.ptr, p.tag); | |
51 | return *this; | |
52 | } | |
53 | #else | |
54 | tagged_ptr & operator= (tagged_ptr const & p) = default; | |
55 | #endif | |
56 | ||
57 | void set(T * p, tag_t t) | |
58 | { | |
59 | ptr = p; | |
60 | tag = t; | |
61 | } | |
62 | /* @} */ | |
63 | ||
64 | /** comparing semantics */ | |
65 | /* @{ */ | |
66 | bool operator== (volatile tagged_ptr const & p) const | |
67 | { | |
68 | return (ptr == p.ptr) && (tag == p.tag); | |
69 | } | |
70 | ||
71 | bool operator!= (volatile tagged_ptr const & p) const | |
72 | { | |
73 | return !operator==(p); | |
74 | } | |
75 | /* @} */ | |
76 | ||
77 | /** pointer access */ | |
78 | /* @{ */ | |
79 | T * get_ptr(void) const | |
80 | { | |
81 | return ptr; | |
82 | } | |
83 | ||
84 | void set_ptr(T * p) | |
85 | { | |
86 | ptr = p; | |
87 | } | |
88 | /* @} */ | |
89 | ||
90 | /** tag access */ | |
91 | /* @{ */ | |
92 | tag_t get_tag() const | |
93 | { | |
94 | return tag; | |
95 | } | |
96 | ||
97 | tag_t get_next_tag() const | |
98 | { | |
99 | tag_t next = (get_tag() + 1) & (std::numeric_limits<tag_t>::max)(); | |
100 | return next; | |
101 | } | |
102 | ||
103 | void set_tag(tag_t t) | |
104 | { | |
105 | tag = t; | |
106 | } | |
107 | /* @} */ | |
108 | ||
109 | /** smart pointer support */ | |
110 | /* @{ */ | |
111 | T & operator*() const | |
112 | { | |
113 | return *ptr; | |
114 | } | |
115 | ||
116 | T * operator->() const | |
117 | { | |
118 | return ptr; | |
119 | } | |
120 | ||
121 | operator bool(void) const | |
122 | { | |
123 | return ptr != 0; | |
124 | } | |
125 | /* @} */ | |
126 | ||
127 | protected: | |
128 | T * ptr; | |
129 | tag_t tag; | |
130 | }; | |
131 | ||
132 | } /* namespace detail */ | |
133 | } /* namespace lockfree */ | |
134 | } /* namespace boost */ | |
135 | ||
136 | #endif /* BOOST_LOCKFREE_TAGGED_PTR_DCAS_HPP_INCLUDED */ |