Honeycomb  0.1
Component-Model Framework
Stack.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
5 
6 namespace honey { namespace lockfree
7 {
8 
10 template<class T>
12 {
13  struct Node
14  {
15  T val;
16  Node* next;
17  };
18 
19  typedef FreeList<Node> FreeList;
20  typedef typename FreeList::TaggedHandle TaggedHandle;
21 
22 public:
23  typedef T value_type;
24 
25  Stack(szt capacity = 0) : _freeList(capacity), _top(TaggedHandle()), _size(0) {}
26 
27  ~Stack() { clear(); }
28 
30  void reserve(szt capacity) { _freeList.reserve(capacity); }
32  szt capacity() const { return _freeList.capacity(); }
33 
35  template<class T_>
36  void push(T_&& val)
37  {
38  Node* node = _freeList.construct(forward<T_>(val), nullptr);
39 
40  //Attach node as top
41  TaggedHandle old;
42  do
43  {
44  old = _top.load(atomic::Order::acquire);
45  node->next = old ? _freeList.deref(old) : nullptr;
46  } while (!_top.cas(TaggedHandle(_freeList.handle(node), old.nextTag()), old));
47  ++_size;
48  }
49 
51  bool pop(optional<T&> val = optnull)
52  {
53  //Detach node from top
54  TaggedHandle old;
55  Node* node;
56  do
57  {
58  if (!(old = _top.load(atomic::Order::acquire))) return false;
59  node = _freeList.deref(old);
60  } while (!_top.cas(TaggedHandle(_freeList.handle(node->next), old.nextTag()), old));
61  --_size;
62 
63  if (val) val = move(node->val);
64  _freeList.destroy(node);
65  return true;
66  }
67 
69  bool top(T& val)
70  {
71  //loop to ensure val we read is consistent with top, otherwise we could end up returning a destroyed value
72  TaggedHandle top;
73  do
74  {
75  if (!(top = _top.load(atomic::Order::acquire))) return false;
76  val = _freeList.deref(top)->val;
77  } while (top != _top.load(atomic::Order::acquire));
78  return true;
79  }
80 
82  void clear() { while (pop()); }
83 
85  bool empty() const { return !_size; }
87  szt size() const { return _size; }
88 
89 private:
90  FreeList _freeList;
92  Atomic<szt> _size;
93 };
94 
95 } }
void reserve(szt capacity)
Ensure that enough storage is allocated for a number of elements.
Definition: Stack.h:30
Holds block handle and tag to prevent lock-free ABA issues.
Definition: Pool.h:95
T * construct(Args &&...args)
Construct object and remove from free list.
Definition: FreeList.h:35
Stack(szt capacity=0)
Definition: Stack.h:25
void reserve(szt capacity)
Ensure that enough storage is allocated for a number of objects.
Definition: FreeList.h:27
static optnull_t optnull
Null optional, use to reset an optional to an uninitialized state or test for initialization.
Definition: Optional.h:12
~Stack()
Definition: Stack.h:27
Inherit to declare that class is not copyable.
Definition: Meta.h:286
szt size() const
The number of elements in the stack.
Definition: Stack.h:87
bool pop(optional< T & > val=optnull)
Remove element from the top of the stack and move it into val. Returns true on success, false if there is no element to pop.
Definition: Stack.h:51
Definition: Atomic.h:119
Must be a load op. Synchronize with a prior release in another thread.
szt capacity() const
The number of elements for which storage is allocated.
Definition: Stack.h:32
bool empty() const
Check whether the stack does not contain any elements.
Definition: Stack.h:85
bool top(T &val)
Get a copy of the top element. Returns true on success, false if there is no element.
Definition: Stack.h:69
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
void destroy(T *ptr)
Destroy object and add to free list.
Definition: FreeList.h:40
void clear()
Remove all elements.
Definition: Stack.h:82
szt capacity() const
The number of objects for which storage is allocated.
Definition: FreeList.h:29
void push(T_ &&val)
Add new element constructed with val onto the top of the stack.
Definition: Stack.h:36
Specialization for references.
Definition: Optional.h:132
T value_type
Definition: Stack.h:23
Int nextTag() const
Definition: Pool.h:107
T * deref(Handle handle) const
Get object from compressed handle.
Definition: FreeList.h:45
Lock-free FILO stack. Uses auto-expanding freelist allocator so memory is only reclaimed upon destruc...
Definition: Stack.h:11
Handle handle(T *ptr) const
Get compressed handle for object.
Definition: FreeList.h:43
Global Honeycomb namespace.