12 #include "lockfreenode.h" 28 : dispenser(_dispenser)
30 end_node.node = (node_type *)(
this);
31 ts_debug_only(debug.counter = 1);
32 node_type *sentinelle = dispenser->new_node();
33 head.data.points_to.node = sentinelle;
34 head.data.access.as_atomic = 0;
35 tail.data.points_to.node = sentinelle;
36 tail.data.access.as_atomic = 0;
37 sentinelle->next.node = end_node.node;
43 assert(head.data.points_to.node == tail.data.points_to.node);
44 assert(head.data.points_to.node->next.node == end_node.node);
45 ts_debug_only(head.data.points_to.node->next.node =
nullptr;)
46 dispenser->free_node(head.data.points_to.node);
55 new_node.node = dispenser->new_node();
56 new_node.node->store(_value);
57 assert(new_node.node->next.node ==
nullptr);
58 new_node.node->next.node = end_node.node;
60 atomic_node_ptr tail_snapshot;
64 end_node.as_atomic, new_node.as_atomic))
67 update_tail(tail_snapshot);
73 atomic_node_ptr newTail;
74 newTail.data.access.as_atomic = tail_snapshot.data.access.as_atomic + 1;
75 newTail.data.points_to.node = new_node.node;
76 tail.compare_exchange_weak(tail_snapshot, newTail);
81 inline bool peek(T &_out)
84 atomic_node_ptr headSnapshot;
85 node_type *nextSnapshot;
93 nextSnapshot = headSnapshot.data.points_to.node->next;
95 if (headSnapshot.data.access != head.data.access)
101 if (nextSnapshot == end_node.node)
108 ts_debug_only(
if (!nextSnapshot)
continue;);
109 value = nextSnapshot->load();
111 }
while (skip || !head.compare_exchange_weak(headSnapshot, headSnapshot));
118 inline bool pop_front(T &_out)
120 node_type *node = internal_remove();
125 dispenser->free_node(node);
131 inline bool empty()
const {
return head.data.points_to.node->next.node == end_node.node; }
136 node_type *node = internal_remove();
139 dispenser->free_node(node);
140 node = internal_remove();
145 inline void update_tail(atomic_node_ptr &_tail)
147 atomic_node_ptr newTail;
148 newTail.data.access.as_atomic = _tail.data.access.as_atomic + 1;
149 newTail.data.points_to.node = _tail.data.points_to.node->next.node;
150 if (newTail.data.points_to.node != end_node.node)
152 tail.compare_exchange_weak(_tail, newTail);
156 node_type *internal_remove()
159 atomic_node_ptr ptr_head, ptr_tail, new_head;
169 ptr_next = ptr_head.data.points_to.node->next.node;
173 if (ptr_head.data.access.as_atomic != head.data.access.as_atomic)
180 if (ptr_next == end_node.node)
182 ptr_head.data.points_to.node =
nullptr;
188 if (ptr_head.data.points_to.node == ptr_tail.data.points_to.node)
191 update_tail(ptr_tail);
196 ts_debug_only(
if (!ptr_next)
continue;);
198 value = ptr_next->load();
201 new_head.data.access.as_atomic = ptr_head.data.access.as_atomic + 1;
202 new_head.data.points_to.node = ptr_next;
205 }
while (skip || !head.compare_exchange_weak(ptr_head, new_head));
213 if (ptr_head.data.points_to.node !=
nullptr)
215 ptr_head.data.points_to.node->store(value);
216 ts_debug_only(ptr_head.data.points_to.node->next.node =
nullptr;);
219 return ptr_head.data.points_to.node;
223 atomic_node_ptr
volatile head;
224 atomic_node_ptr
volatile tail;
225 atomic_node end_node;
226 TDispenser *dispenser;
227 struct debug_container
229 volatile int32_t counter;
231 ts_debug_only(debug_container debug;);
234 template <
class TPolicy,
class T,
class TMemInterface,
class TParam =
void * >
245 virtual bool push_back(T newData) {
return queue.push_back(newData); }
249 virtual bool pop_front(T &val) {
return queue.pop_front(val); }
251 virtual bool pop_back(T &val) {
return queue.pop_front(val); }
253 virtual bool empty()
const {
return queue.empty(); }
int64_t increment(volatile int64_t &_data)
Increments the specified data.
Definition: atomics.h:32
Class stl_allocator.
Definition: allocator.h:16
Definition: lockfreenode.h:26
int64_t decrement(volatile int64_t &_data)
Decrements the specified data.
Definition: atomics.h:39
Definition: lockfreequeue.h:20
Definition: lockfreequeue.h:235
Definition: lockfreenode.h:24
int32_t compare_exchange_weak(volatile int32_t &_data, int32_t _comperand, int32_t _value)
Compares the exchange weak.
Definition: atomics.h:68
Definition: lockfreenode.h:55
bool push_back(const T &_value)
Definition: lockfreequeue.h:52