rippled
Loading...
Searching...
No Matches
LockFreeStack.h
1#ifndef BEAST_INTRUSIVE_LOCKFREESTACK_H_INCLUDED
2#define BEAST_INTRUSIVE_LOCKFREESTACK_H_INCLUDED
3
4#include <atomic>
5#include <iterator>
6#include <type_traits>
7
8namespace beast {
9
10//------------------------------------------------------------------------------
11
12template <class Container, bool IsConst>
14{
15protected:
16 using Node = typename Container::Node;
17 using NodePtr =
19
20public:
22 using value_type = typename Container::value_type;
23 using difference_type = typename Container::difference_type;
24 using pointer = typename std::conditional<
25 IsConst,
26 typename Container::const_pointer,
27 typename Container::pointer>::type;
28 using reference = typename std::conditional<
29 IsConst,
30 typename Container::const_reference,
31 typename Container::reference>::type;
32
36
40
41 template <bool OtherIsConst>
47
50 {
51 m_node = node;
52 return static_cast<LockFreeStackIterator&>(*this);
53 }
54
57 {
58 m_node = m_node->m_next.load();
59 return static_cast<LockFreeStackIterator&>(*this);
60 }
61
64 {
65 LockFreeStackIterator result(*this);
66 m_node = m_node->m_next;
67 return result;
68 }
69
71 node() const
72 {
73 return m_node;
74 }
75
77 operator*() const
78 {
79 return *this->operator->();
80 }
81
83 operator->() const
84 {
85 return static_cast<pointer>(m_node);
86 }
87
88private:
90};
91
92//------------------------------------------------------------------------------
93
94template <class Container, bool LhsIsConst, bool RhsIsConst>
95bool
102
103template <class Container, bool LhsIsConst, bool RhsIsConst>
104bool
108{
109 return lhs.node() != rhs.node();
110}
111
112//------------------------------------------------------------------------------
113
126template <class Element, class Tag = void>
128{
129public:
130 class Node
131 {
132 public:
133 Node() : m_next(nullptr)
134 {
135 }
136
137 explicit Node(Node* next) : m_next(next)
138 {
139 }
140
141 Node(Node const&) = delete;
142 Node&
143 operator=(Node const&) = delete;
144
145 private:
146 friend class LockFreeStack;
147
148 template <class Container, bool IsConst>
150
152 };
153
154public:
155 using value_type = Element;
156 using pointer = Element*;
157 using reference = Element&;
158 using const_pointer = Element const*;
159 using const_reference = Element const&;
165
167 {
168 }
169
170 LockFreeStack(LockFreeStack const&) = delete;
172 operator=(LockFreeStack const&) = delete;
173
175 bool
176 empty() const
177 {
178 return m_head.load() == &m_end;
179 }
180
192 // VFALCO NOTE Fix this, shouldn't it be a reference like intrusive list?
193 bool
195 {
196 bool first;
197 Node* old_head = m_head.load(std::memory_order_relaxed);
198 do
199 {
200 first = (old_head == &m_end);
201 node->m_next = old_head;
202 } while (!m_head.compare_exchange_strong(
203 old_head,
204 node,
207 return first;
208 }
209
219 Element*
221 {
222 Node* node = m_head.load();
223 Node* new_head;
224 do
225 {
226 if (node == &m_end)
227 return nullptr;
228 new_head = node->m_next.load();
229 } while (!m_head.compare_exchange_strong(
230 node,
231 new_head,
234 return static_cast<Element*>(node);
235 }
236
246 {
247 return iterator(m_head.load());
248 }
249
252 {
253 return iterator(&m_end);
254 }
255
257 begin() const
258 {
259 return const_iterator(m_head.load());
260 }
261
263 end() const
264 {
265 return const_iterator(&m_end);
266 }
267
269 cbegin() const
270 {
271 return const_iterator(m_head.load());
272 }
273
275 cend() const
276 {
277 return const_iterator(&m_end);
278 }
281private:
284};
285
286} // namespace beast
287
288#endif
reference operator*() const
LockFreeStackIterator & operator++()
typename Container::Node Node
typename std::conditional< IsConst, typename Container::const_pointer, typename Container::pointer >::type pointer
LockFreeStackIterator & operator=(NodePtr node)
LockFreeStackIterator(LockFreeStackIterator< Container, OtherIsConst > const &other)
LockFreeStackIterator(NodePtr node)
typename Container::value_type value_type
typename std::conditional< IsConst, Node const *, Node * >::type NodePtr
typename Container::difference_type difference_type
typename std::conditional< IsConst, typename Container::const_reference, typename Container::reference >::type reference
LockFreeStackIterator operator++(int)
Node(Node const &)=delete
Node & operator=(Node const &)=delete
std::atomic< Node * > m_next
Multiple Producer, Multiple Consumer (MPMC) intrusive stack.
const_iterator cend() const
bool push_front(Node *node)
Push a node onto the stack.
LockFreeStackIterator< LockFreeStack< Element, Tag >, false > iterator
const_iterator cbegin() const
iterator begin()
Return a forward iterator to the beginning or end of the stack.
Element * pop_front()
Pop an element off the stack.
LockFreeStack(LockFreeStack const &)=delete
bool empty() const
Returns true if the stack is empty.
LockFreeStack & operator=(LockFreeStack const &)=delete
Element const * const_pointer
Element const & const_reference
const_iterator begin() const
std::atomic< Node * > m_head
LockFreeStackIterator< LockFreeStack< Element, Tag >, true > const_iterator
const_iterator end() const
T is_same_v
bool operator==(LockFreeStackIterator< Container, LhsIsConst > const &lhs, LockFreeStackIterator< Container, RhsIsConst > const &rhs)
bool operator!=(LockFreeStackIterator< Container, LhsIsConst > const &lhs, LockFreeStackIterator< Container, RhsIsConst > const &rhs)