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  std::forward_iterator_tag,
34  typename Container::value_type,
35  typename Container::difference_type,
36  typename std::conditional<
37  IsConst,
38  typename Container::const_pointer,
39  typename Container::pointer>::type,
40  typename std::conditional<
41  IsConst,
42  typename Container::const_reference,
43  typename Container::reference>::type>
44 {
45 protected:
46  using Node = typename Container::Node;
47  using NodePtr =
49 
50 public:
51  using value_type = typename Container::value_type;
52  using pointer = typename std::conditional<
53  IsConst,
54  typename Container::const_pointer,
55  typename Container::pointer>::type;
56  using reference = typename std::conditional<
57  IsConst,
58  typename Container::const_reference,
59  typename Container::reference>::type;
60 
62  {
63  }
64 
66  {
67  }
68 
69  template <bool OtherIsConst>
72  : m_node(other.m_node)
73  {
74  }
75 
78  {
79  m_node = node;
80  return static_cast<LockFreeStackIterator&>(*this);
81  }
82 
85  {
86  m_node = m_node->m_next.load();
87  return static_cast<LockFreeStackIterator&>(*this);
88  }
89 
92  {
93  LockFreeStackIterator result(*this);
94  m_node = m_node->m_next;
95  return result;
96  }
97 
98  NodePtr
99  node() const
100  {
101  return m_node;
102  }
103 
104  reference
105  operator*() const
106  {
107  return *this->operator->();
108  }
109 
110  pointer
111  operator->() const
112  {
113  return static_cast<pointer>(m_node);
114  }
115 
116 private:
118 };
119 
120 //------------------------------------------------------------------------------
121 
122 template <class Container, bool LhsIsConst, bool RhsIsConst>
123 bool
127 {
128  return lhs.node() == rhs.node();
129 }
130 
131 template <class Container, bool LhsIsConst, bool RhsIsConst>
132 bool
136 {
137  return lhs.node() != rhs.node();
138 }
139 
140 //------------------------------------------------------------------------------
141 
154 template <class Element, class Tag = void>
156 {
157 public:
158  class Node
159  {
160  public:
161  Node() : m_next(nullptr)
162  {
163  }
164 
165  explicit Node(Node* next) : m_next(next)
166  {
167  }
168 
169  Node(Node const&) = delete;
170  Node&
171  operator=(Node const&) = delete;
172 
173  private:
174  friend class LockFreeStack;
175 
176  template <class Container, bool IsConst>
177  friend class LockFreeStackIterator;
178 
180  };
181 
182 public:
183  using value_type = Element;
184  using pointer = Element*;
185  using reference = Element&;
186  using const_pointer = Element const*;
187  using const_reference = Element const&;
191  using const_iterator =
193 
194  LockFreeStack() : m_end(nullptr), m_head(&m_end)
195  {
196  }
197 
198  LockFreeStack(LockFreeStack const&) = delete;
200  operator=(LockFreeStack const&) = delete;
201 
203  bool
204  empty() const
205  {
206  return m_head.load() == &m_end;
207  }
208 
220  // VFALCO NOTE Fix this, shouldn't it be a reference like intrusive list?
221  bool
222  push_front(Node* node)
223  {
224  bool first;
225  Node* old_head = m_head.load(std::memory_order_relaxed);
226  do
227  {
228  first = (old_head == &m_end);
229  node->m_next = old_head;
230  } while (!m_head.compare_exchange_strong(
231  old_head,
232  node,
233  std::memory_order_release,
234  std::memory_order_relaxed));
235  return first;
236  }
237 
247  Element*
249  {
250  Node* node = m_head.load();
251  Node* new_head;
252  do
253  {
254  if (node == &m_end)
255  return nullptr;
256  new_head = node->m_next.load();
257  } while (!m_head.compare_exchange_strong(
258  node,
259  new_head,
260  std::memory_order_release,
261  std::memory_order_relaxed));
262  return static_cast<Element*>(node);
263  }
264 
272  iterator
274  {
275  return iterator(m_head.load());
276  }
277 
278  iterator
279  end()
280  {
281  return iterator(&m_end);
282  }
283 
285  begin() const
286  {
287  return const_iterator(m_head.load());
288  }
289 
291  end() const
292  {
293  return const_iterator(&m_end);
294  }
295 
297  cbegin() const
298  {
299  return const_iterator(m_head.load());
300  }
301 
303  cend() const
304  {
305  return const_iterator(&m_end);
306  }
309 private:
310  Node m_end;
312 };
313 
314 } // namespace beast
315 
316 #endif
beast::LockFreeStack::m_end
Node m_end
Definition: LockFreeStack.h:310
beast::operator==
bool operator==(LockFreeStackIterator< Container, LhsIsConst > const &lhs, LockFreeStackIterator< Container, RhsIsConst > const &rhs)
Definition: LockFreeStack.h:124
beast::LockFreeStackIterator::operator++
LockFreeStackIterator & operator++()
Definition: LockFreeStack.h:84
beast::LockFreeStack::begin
const_iterator begin() const
Definition: LockFreeStack.h:285
beast::LockFreeStackIterator::LockFreeStackIterator
LockFreeStackIterator(NodePtr node)
Definition: LockFreeStack.h:65
beast::LockFreeStack::cbegin
const_iterator cbegin() const
Definition: LockFreeStack.h:297
iterator
beast::LockFreeStack::Node::operator=
Node & operator=(Node const &)=delete
beast::LockFreeStack::Node::Node
Node(Node *next)
Definition: LockFreeStack.h:165
beast::LockFreeStackIterator::LockFreeStackIterator
LockFreeStackIterator(LockFreeStackIterator< Container, OtherIsConst > const &other)
Definition: LockFreeStack.h:70
beast::LockFreeStackIterator::node
NodePtr node() const
Definition: LockFreeStack.h:99
beast::LockFreeStack< ripple::Workers::Worker >::const_pointer
ripple::Workers::Worker const * const_pointer
Definition: LockFreeStack.h:186
beast::LockFreeStackIterator::operator->
pointer operator->() const
Definition: LockFreeStack.h:111
beast::LockFreeStackIterator
Definition: LockFreeStack.h:32
beast::LockFreeStackIterator::Node
typename Container::Node Node
Definition: LockFreeStack.h:46
beast::LockFreeStackIterator::operator++
LockFreeStackIterator operator++(int)
Definition: LockFreeStack.h:91
beast::operator!=
bool operator!=(LockFreeStackIterator< Container, LhsIsConst > const &lhs, LockFreeStackIterator< Container, RhsIsConst > const &rhs)
Definition: LockFreeStack.h:133
beast::LockFreeStack::Node::Node
Node()
Definition: LockFreeStack.h:161
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:59
beast::LockFreeStack::end
const_iterator end() const
Definition: LockFreeStack.h:291
beast::LockFreeStack::const_iterator
LockFreeStackIterator< LockFreeStack< Element, Tag >, true > const_iterator
Definition: LockFreeStack.h:192
atomic
beast::LockFreeStackIterator::m_node
NodePtr m_node
Definition: LockFreeStack.h:117
ripple::Workers::Worker
Definition: Workers.h:143
beast::LockFreeStackIterator::NodePtr
typename std::conditional< IsConst, Node const *, Node * >::type NodePtr
Definition: LockFreeStack.h:48
beast::LockFreeStack::m_head
std::atomic< Node * > m_head
Definition: LockFreeStack.h:311
beast::LockFreeStackIterator::operator*
reference operator*() const
Definition: LockFreeStack.h:105
beast::LockFreeStack::pop_front
Element * pop_front()
Pop an element off the stack.
Definition: LockFreeStack.h:248
beast::LockFreeStackIterator::LockFreeStackIterator
LockFreeStackIterator()
Definition: LockFreeStack.h:61
beast::LockFreeStack::end
iterator end()
Definition: LockFreeStack.h:279
beast::LockFreeStack::Node
Definition: LockFreeStack.h:158
std::ptrdiff_t
beast::LockFreeStackIterator::operator=
LockFreeStackIterator & operator=(NodePtr node)
Definition: LockFreeStack.h:77
std::size_t
beast::LockFreeStack::Node::m_next
std::atomic< Node * > m_next
Definition: LockFreeStack.h:179
beast::LockFreeStackIterator::value_type
typename Container::value_type value_type
Definition: LockFreeStack.h:51
beast::LockFreeStack::LockFreeStack
LockFreeStack()
Definition: LockFreeStack.h:194
beast::LockFreeStack::begin
iterator begin()
Return a forward iterator to the beginning or end of the stack.
Definition: LockFreeStack.h:273
std::conditional
beast::LockFreeStack::push_front
bool push_front(Node *node)
Push a node onto the stack.
Definition: LockFreeStack.h:222
type_traits
beast::LockFreeStack::iterator
LockFreeStackIterator< LockFreeStack< Element, Tag >, false > iterator
Definition: LockFreeStack.h:190
beast::LockFreeStack< ripple::Workers::Worker >::const_reference
ripple::Workers::Worker const & const_reference
Definition: LockFreeStack.h:187
beast::LockFreeStack::empty
bool empty() const
Returns true if the stack is empty.
Definition: LockFreeStack.h:204
beast::LockFreeStack::cend
const_iterator cend() const
Definition: LockFreeStack.h:303
beast::LockFreeStack
Multiple Producer, Multiple Consumer (MPMC) intrusive stack.
Definition: LockFreeStack.h:155
beast
Definition: base_uint.h:585
beast::LockFreeStackIterator::pointer
typename std::conditional< IsConst, typename Container::const_pointer, typename Container::pointer >::type pointer
Definition: LockFreeStack.h:55