rippled
LockFreeStack.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of Beast: https://github.com/vinniefalco/Beast
4  Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef BEAST_INTRUSIVE_LOCKFREESTACK_H_INCLUDED
21 #define BEAST_INTRUSIVE_LOCKFREESTACK_H_INCLUDED
22 
23 #include <atomic>
24 #include <iterator>
25 #include <type_traits>
26 
27 namespace beast {
28 
29 //------------------------------------------------------------------------------
30 
31 template <class Container, bool IsConst>
33 {
34 protected:
35  using Node = typename Container::Node;
36  using NodePtr =
38 
39 public:
41  using value_type = typename Container::value_type;
42  using difference_type = typename Container::difference_type;
43  using pointer = typename std::conditional<
44  IsConst,
45  typename Container::const_pointer,
46  typename Container::pointer>::type;
47  using reference = typename std::conditional<
48  IsConst,
49  typename Container::const_reference,
50  typename Container::reference>::type;
51 
53  {
54  }
55 
57  {
58  }
59 
60  template <bool OtherIsConst>
63  : m_node(other.m_node)
64  {
65  }
66 
69  {
70  m_node = node;
71  return static_cast<LockFreeStackIterator&>(*this);
72  }
73 
76  {
77  m_node = m_node->m_next.load();
78  return static_cast<LockFreeStackIterator&>(*this);
79  }
80 
83  {
84  LockFreeStackIterator result(*this);
85  m_node = m_node->m_next;
86  return result;
87  }
88 
89  NodePtr
90  node() const
91  {
92  return m_node;
93  }
94 
95  reference
96  operator*() const
97  {
98  return *this->operator->();
99  }
100 
101  pointer
102  operator->() const
103  {
104  return static_cast<pointer>(m_node);
105  }
106 
107 private:
109 };
110 
111 //------------------------------------------------------------------------------
112 
113 template <class Container, bool LhsIsConst, bool RhsIsConst>
114 bool
118 {
119  return lhs.node() == rhs.node();
120 }
121 
122 template <class Container, bool LhsIsConst, bool RhsIsConst>
123 bool
127 {
128  return lhs.node() != rhs.node();
129 }
130 
131 //------------------------------------------------------------------------------
132 
145 template <class Element, class Tag = void>
147 {
148 public:
149  class Node
150  {
151  public:
152  Node() : m_next(nullptr)
153  {
154  }
155 
156  explicit Node(Node* next) : m_next(next)
157  {
158  }
159 
160  Node(Node const&) = delete;
161  Node&
162  operator=(Node const&) = delete;
163 
164  private:
165  friend class LockFreeStack;
166 
167  template <class Container, bool IsConst>
168  friend class LockFreeStackIterator;
169 
171  };
172 
173 public:
174  using value_type = Element;
175  using pointer = Element*;
176  using reference = Element&;
177  using const_pointer = Element const*;
178  using const_reference = Element const&;
182  using const_iterator =
184 
185  LockFreeStack() : m_end(nullptr), m_head(&m_end)
186  {
187  }
188 
189  LockFreeStack(LockFreeStack const&) = delete;
191  operator=(LockFreeStack const&) = delete;
192 
194  bool
195  empty() const
196  {
197  return m_head.load() == &m_end;
198  }
199 
211  // VFALCO NOTE Fix this, shouldn't it be a reference like intrusive list?
212  bool
213  push_front(Node* node)
214  {
215  bool first;
216  Node* old_head = m_head.load(std::memory_order_relaxed);
217  do
218  {
219  first = (old_head == &m_end);
220  node->m_next = old_head;
221  } while (!m_head.compare_exchange_strong(
222  old_head,
223  node,
224  std::memory_order_release,
225  std::memory_order_relaxed));
226  return first;
227  }
228 
238  Element*
240  {
241  Node* node = m_head.load();
242  Node* new_head;
243  do
244  {
245  if (node == &m_end)
246  return nullptr;
247  new_head = node->m_next.load();
248  } while (!m_head.compare_exchange_strong(
249  node,
250  new_head,
251  std::memory_order_release,
252  std::memory_order_relaxed));
253  return static_cast<Element*>(node);
254  }
255 
263  iterator
265  {
266  return iterator(m_head.load());
267  }
268 
269  iterator
270  end()
271  {
272  return iterator(&m_end);
273  }
274 
276  begin() const
277  {
278  return const_iterator(m_head.load());
279  }
280 
282  end() const
283  {
284  return const_iterator(&m_end);
285  }
286 
288  cbegin() const
289  {
290  return const_iterator(m_head.load());
291  }
292 
294  cend() const
295  {
296  return const_iterator(&m_end);
297  }
300 private:
301  Node m_end;
303 };
304 
305 } // namespace beast
306 
307 #endif
beast::LockFreeStack::m_end
Node m_end
Definition: LockFreeStack.h:301
beast::operator==
bool operator==(LockFreeStackIterator< Container, LhsIsConst > const &lhs, LockFreeStackIterator< Container, RhsIsConst > const &rhs)
Definition: LockFreeStack.h:115
beast::LockFreeStackIterator::operator++
LockFreeStackIterator & operator++()
Definition: LockFreeStack.h:75
beast::LockFreeStack::begin
const_iterator begin() const
Definition: LockFreeStack.h:276
beast::LockFreeStackIterator::LockFreeStackIterator
LockFreeStackIterator(NodePtr node)
Definition: LockFreeStack.h:56
beast::LockFreeStack::cbegin
const_iterator cbegin() const
Definition: LockFreeStack.h:288
iterator
std::forward_iterator_tag
beast::LockFreeStack::Node::operator=
Node & operator=(Node const &)=delete
beast::LockFreeStack::Node::Node
Node(Node *next)
Definition: LockFreeStack.h:156
beast::LockFreeStackIterator::LockFreeStackIterator
LockFreeStackIterator(LockFreeStackIterator< Container, OtherIsConst > const &other)
Definition: LockFreeStack.h:61
beast::LockFreeStackIterator::node
NodePtr node() const
Definition: LockFreeStack.h:90
beast::LockFreeStack< ripple::Workers::Worker >::const_pointer
ripple::Workers::Worker const * const_pointer
Definition: LockFreeStack.h:177
beast::LockFreeStackIterator::operator->
pointer operator->() const
Definition: LockFreeStack.h:102
beast::LockFreeStackIterator
Definition: LockFreeStack.h:32
beast::LockFreeStackIterator::Node
typename Container::Node Node
Definition: LockFreeStack.h:35
beast::LockFreeStackIterator::operator++
LockFreeStackIterator operator++(int)
Definition: LockFreeStack.h:82
beast::operator!=
bool operator!=(LockFreeStackIterator< Container, LhsIsConst > const &lhs, LockFreeStackIterator< Container, RhsIsConst > const &rhs)
Definition: LockFreeStack.h:124
beast::LockFreeStack::Node::Node
Node()
Definition: LockFreeStack.h:152
beast::LockFreeStack::operator=
LockFreeStack & operator=(LockFreeStack const &)=delete
beast::LockFreeStackIterator::reference
typename std::conditional< IsConst, typename Container::const_reference, typename Container::reference >::type reference
Definition: LockFreeStack.h:50
beast::LockFreeStack::end
const_iterator end() const
Definition: LockFreeStack.h:282
beast::LockFreeStack::const_iterator
LockFreeStackIterator< LockFreeStack< Element, Tag >, true > const_iterator
Definition: LockFreeStack.h:183
atomic
beast::LockFreeStackIterator::difference_type
typename Container::difference_type difference_type
Definition: LockFreeStack.h:42
beast::LockFreeStackIterator::m_node
NodePtr m_node
Definition: LockFreeStack.h:108
ripple::Workers::Worker
Definition: Workers.h:183
beast::LockFreeStackIterator::NodePtr
typename std::conditional< IsConst, Node const *, Node * >::type NodePtr
Definition: LockFreeStack.h:37
beast::LockFreeStack::m_head
std::atomic< Node * > m_head
Definition: LockFreeStack.h:302
beast::LockFreeStackIterator::operator*
reference operator*() const
Definition: LockFreeStack.h:96
beast::LockFreeStack::pop_front
Element * pop_front()
Pop an element off the stack.
Definition: LockFreeStack.h:239
beast::LockFreeStackIterator::LockFreeStackIterator
LockFreeStackIterator()
Definition: LockFreeStack.h:52
beast::LockFreeStack::end
iterator end()
Definition: LockFreeStack.h:270
beast::LockFreeStack::Node
Definition: LockFreeStack.h:149
std::ptrdiff_t
beast::LockFreeStackIterator::operator=
LockFreeStackIterator & operator=(NodePtr node)
Definition: LockFreeStack.h:68
std::size_t
beast::LockFreeStack::Node::m_next
std::atomic< Node * > m_next
Definition: LockFreeStack.h:170
beast::LockFreeStackIterator::value_type
typename Container::value_type value_type
Definition: LockFreeStack.h:41
beast::LockFreeStack::LockFreeStack
LockFreeStack()
Definition: LockFreeStack.h:185
beast::LockFreeStack::begin
iterator begin()
Return a forward iterator to the beginning or end of the stack.
Definition: LockFreeStack.h:264
std::conditional
beast::LockFreeStack::push_front
bool push_front(Node *node)
Push a node onto the stack.
Definition: LockFreeStack.h:213
type_traits
beast::LockFreeStack::iterator
LockFreeStackIterator< LockFreeStack< Element, Tag >, false > iterator
Definition: LockFreeStack.h:181
beast::LockFreeStack< ripple::Workers::Worker >::const_reference
ripple::Workers::Worker const & const_reference
Definition: LockFreeStack.h:178
beast::LockFreeStack::empty
bool empty() const
Returns true if the stack is empty.
Definition: LockFreeStack.h:195
beast::LockFreeStack::cend
const_iterator cend() const
Definition: LockFreeStack.h:294
beast::LockFreeStack
Multiple Producer, Multiple Consumer (MPMC) intrusive stack.
Definition: LockFreeStack.h:146
beast
Definition: base_uint.h:641
beast::LockFreeStackIterator::pointer
typename std::conditional< IsConst, typename Container::const_pointer, typename Container::pointer >::type pointer
Definition: LockFreeStack.h:46