23 template<
class T,
class Alloc_ = SmallAllocator<T>,
class Backoff = Backoff, u
int8 iterMax = 2>
48 Node(T_&& val) : val(forward<T_>(val)) {}
54 typedef typename Node::Link Link;
66 _mem(*this,
alloc, threadMax),
69 _mem.storeRef(_head, &createNode(T()));
70 _mem.storeRef(_tail, &createNode(T()));
71 _mem.storeRef(_head.
ptr()->next, _tail);
72 _mem.storeRef(_tail.
ptr()->prev, _head);
73 _mem.releaseRef(*_head.
ptr());
74 _mem.releaseRef(*_tail.
ptr());
80 _mem.deleteNode(*_head.
ptr());
81 _mem.deleteNode(*_tail.
ptr());
88 Node& node = createNode(forward<T_>(val));
89 Node* prev = _mem.deRefLink(_head);
90 Node* next = _mem.deRefLink(prev->next);
94 _mem.storeRef(node.prev, prev);
95 _mem.storeRef(node.next, next);
96 if (_mem.casRef(prev->next, &node, next))
break;
97 _mem.releaseRef(*next);
98 next = _mem.deRefLink(prev->next);
103 _mem.releaseRef(*prev);
104 pushEnd(node, *next);
111 Node& node = createNode(forward<T_>(val));
112 Node* next = _mem.deRefLink(_tail);
113 Node* prev = _mem.deRefLink(next->prev);
117 _mem.storeRef(node.prev, prev);
118 _mem.storeRef(node.next, next);
119 if (_mem.casRef(prev->next, &node, next))
break;
120 prev = &correctPrev(*prev, *next);
125 _mem.releaseRef(*prev);
126 pushEnd(node, *next);
132 Node* prev = _mem.deRefLink(_head);
136 Node* node = _mem.deRefLink(prev->next);
137 if (node == _tail.
ptr())
139 _mem.releaseRef(*node);
140 _mem.releaseRef(*prev);
143 bool next_d = node->next.d();
144 Node* next = _mem.deRefLink(node->next);
148 _mem.casRef(prev->next, next, node);
149 _mem.releaseRef(*next);
150 _mem.releaseRef(*node);
153 if (_mem.casRef(node->next, Link(next,
true), next))
156 prev = &correctPrev(*prev, *next);
157 _mem.releaseRef(*prev);
158 _mem.releaseRef(*next);
159 if (val) val = move(node->val);
160 _mem.releaseRef(*node);
161 _mem.deleteNode(*node);
164 _mem.releaseRef(*next);
165 _mem.releaseRef(*node);
175 Node* next = _mem.deRefLink(_tail);
176 Node* node = _mem.deRefLink(next->prev);
180 if (node->next != Link(next))
182 node = &correctPrev(*node, *next);
185 if (node == _head.
ptr())
187 _mem.releaseRef(*node);
188 _mem.releaseRef(*next);
191 if (_mem.casRef(node->next, Link(next,
true), next))
194 Node* prev = _mem.deRefLink(node->prev);
195 prev = &correctPrev(*prev, *next);
196 _mem.releaseRef(*prev);
197 _mem.releaseRef(*next);
198 if (val) val = move(node->val);
199 _mem.releaseRef(*node);
200 _mem.deleteNode(*node);
226 Iter_() : _list(nullptr), _cur(nullptr) {}
229 _list(const_cast<
List*>(&list)),
230 _cur(!end ? _list->_head.ptr() : _list->_tail.ptr())
232 _list->_mem.ref(*_cur);
239 if (_cur) _list->_mem.releaseRef(*_cur);
245 if (_cur) _list->_mem.releaseRef(*_cur);
248 if (_cur) _list->_mem.ref(*_cur);
256 if (_cur == _list->_tail.
ptr())
break;
257 Node* next = _list->_mem.deRefLink(_cur->next);
258 bool d = next->next.d();
259 if (d && _cur->next != Link(next,
true))
261 _list->setMark(next->prev);
262 _list->_mem.casRef(_cur->next, next->next.ptr(), next);
263 _list->_mem.releaseRef(*next);
266 _list->_mem.releaseRef(*_cur);
277 if (_cur == _list->_head.
ptr())
break;
278 Node* prev = _list->_mem.deRefLink(_cur->prev);
279 if (prev->next == Link(_cur) && !_cur->next.d())
281 _list->_mem.releaseRef(*_cur);
285 else if (_cur->next.d())
287 _list->_mem.releaseRef(*prev);
292 prev = &_list->correctPrev(*prev, *_cur);
293 _list->_mem.releaseRef(*prev);
309 bool valid()
const {
return !_cur->next.d(); }
376 if (it ==
end() || !it.
valid())
return false;
385 if (it ==
rend() || !it.
valid())
return false;
397 Node& node = createNode(forward<T_>(val));
398 Node* prev = _mem.deRefLink(pos._cur->prev);
399 Node* next =
nullptr;
403 while (pos._cur->next.d())
406 prev = &correctPrev(*prev, *pos._cur);
409 _mem.storeRef(node.prev, prev);
410 _mem.storeRef(node.next, next);
411 if (_mem.casRef(prev->next, &node, pos._cur))
break;
412 prev = &correctPrev(*prev, *pos._cur);
417 _mem.releaseRef(*prev);
420 _mem.releaseRef(correctPrev(node, *next));
421 _mem.releaseRef(*next);
430 Node* node = it._cur;
434 bool next_d = it._cur->next.d();
435 Node* next = _mem.deRefLink(it._cur->next);
438 _mem.releaseRef(*next);
441 if (node->next.cas(Link(next,
true), next))
445 Node* prev =
nullptr;
448 bool bPrev = node->prev.d();
449 prev = _mem.deRefLink(node->prev);
450 if (bPrev || node->prev.cas(Link(prev,
true), prev))
break;
451 _mem.releaseRef(*prev);
453 prev = &correctPrev(*prev, *next);
454 _mem.releaseRef(*prev);
455 _mem.releaseRef(*next);
456 if (val) val = move(node->val);
457 _mem.deleteNode(*node);
460 _mem.releaseRef(*next);
476 static const uint8 linkMax = 2;
478 static const uint8 linkDelMax = linkMax;
480 static const uint8 hazardMax = 5 + iterMax;
483 void cleanUpNode(
Node& node)
487 Node* prev = _mem.deRefLink(node.prev);
491 _mem.releaseRef(*prev);
494 Node* prev2 = _mem.deRefLink(prev->prev);
495 _mem.casRef(node.prev, Link(prev2,
true), Link(prev,
true));
496 _mem.releaseRef(*prev2);
497 _mem.releaseRef(*prev);
501 Node* next = _mem.deRefLink(node.next);
505 _mem.releaseRef(*next);
508 Node* next2 = _mem.deRefLink(next->next);
509 _mem.casRef(node.next, Link(next2,
true), Link(next,
true));
510 _mem.releaseRef(*next2);
511 _mem.releaseRef(*next);
516 void terminateNode(
Node& node,
bool concurrent)
520 _mem.storeRef(node.prev, Link(
nullptr,
true));
521 _mem.storeRef(node.next, Link(
nullptr,
true));
525 _mem.casRef(node.prev, Link(
nullptr,
true), Link(node.prev));
526 _mem.casRef(node.next, Link(
nullptr,
true), Link(node.next));
531 Node& createNode(T_&& val)
533 Node& node = _mem.createNode(forward<T_>(val));
534 assert((reinterpret_cast<intptr_t>(&node) & ~Link::ptr_mask) == 0,
"Pointer not 2-byte aligned, bits found outside mask.");
539 void setMark(Link& link)
544 if (old.d() || link.cas(Link(old.ptr(),
true), old))
break;
549 void pushEnd(
Node& node,
Node& next)
555 Link link = next.prev;
556 if (link.d() || node.next != Link(&next))
break;
557 if (_mem.casRef(next.prev, &node, link))
560 pNode = &correctPrev(node, next);
566 _mem.releaseRef(next);
567 _mem.releaseRef(*pNode);
574 Node* lastLink =
nullptr;
578 Link link = node.prev;
584 _mem.releaseRef(*prev);
590 bool prev2_d = prev->next.d();
591 Node* prev2 = _mem.deRefLink(prev->next);
597 _mem.casRef(lastLink->next, prev2, prev);
598 _mem.releaseRef(*prev2);
599 _mem.releaseRef(*prev);
604 _mem.releaseRef(*prev2);
605 prev2 = _mem.deRefLink(prev->prev);
606 _mem.releaseRef(*prev);
612 if (lastLink) _mem.releaseRef(*lastLink);
617 _mem.releaseRef(*prev2);
618 if (_mem.casRef(node.prev, prev, link))
620 if (prev->prev.d())
continue;
626 if (lastLink) _mem.releaseRef(*lastLink);
630 HazardMem<List> _mem;
ConstIter begin() const
Get iterator to the beginning of the list.
Definition: List.h:320
Base node class, inherit from this class, add link members, and use as Node type in HazardMemConfig...
Definition: HazardMem.h:12
Combines node pointer and delete mark in one Cas-able integer.
Definition: List.h:31
void clear()
Remove all elements.
Definition: List.h:467
bool empty() const
Check whether the list does not contain any elements.
Definition: List.h:470
Iterator.
Definition: List.h:215
IterR_ & operator++()
Definition: List.h:344
bool operator!=(const Iter_ &rhs) const
Definition: List.h:303
Iter_ & operator=(const Iter_ &it)
Copy iterator, must reference copied cursor.
Definition: List.h:243
T_ value_type
Definition: List.h:221
std::bidirectional_iterator_tag iterator_category
Definition: List.h:336
static optnull_t optnull
Null optional, use to reset an optional to an uninitialized state or test for initialization.
Definition: Optional.h:12
bool cas(const Link &val, const Link &old)
Definition: List.h:41
Iter_ & operator--()
Definition: List.h:273
List(const Alloc &alloc=Alloc(), int threadMax=10)
Definition: List.h:65
bool operator!=(const IterR_ &rhs) const
Definition: List.h:350
bool operator==(const Link &rhs)
Definition: List.h:43
pointer operator->() const
Definition: List.h:353
sdt difference_type
Definition: List.h:338
Link(Node *ptr, bool d=false)
Definition: List.h:38
Link()
Definition: List.h:37
Iter_< const T > ConstIter
Definition: List.h:317
ptrdiff_t sdt
Size difference type, shorthand for ptrdiff_t.
Definition: Core.h:92
Inherit to declare that class is not copyable.
Definition: Meta.h:286
Iter_ operator--(int)
Definition: List.h:300
bool pop_front(optional< T & > val=optnull)
Remove element from the beginning of the list and move it into val. Returns true on success...
Definition: List.h:130
void inc(int ticks=1)
Increase tick count by ticks. Increases the amount of time that backoff will wait.
Definition: Backoff.h:28
sdt difference_type
Definition: List.h:222
bool valid() const
Returns true if iterator points to valid element that has not been deleted.
Definition: List.h:309
bool operator!=(const Link &rhs)
Definition: List.h:44
void push_back(T_ &&val)
Add new element constructed with val onto the end of the list.
Definition: List.h:109
IterR rend()
Definition: List.h:370
bool front(T &val)
Get a copy of the element at the beginning of the list. Returns true on success, false if there is no...
Definition: List.h:373
Iter_ & operator++()
Definition: List.h:252
Atomic< intptr_t > data
Definition: HazardMem.h:28
Iter_(const List &list, bool end)
Definition: List.h:228
bool operator==(const IterR_ &rhs) const
Definition: List.h:349
IterR_ operator++(int)
Definition: List.h:346
T_ * pointer
Definition: List.h:339
T value_type
Definition: List.h:57
T_ * pointer
Definition: List.h:223
T_ value_type
Definition: List.h:337
bool valid() const
Definition: List.h:355
Node * ptr() const
Definition: List.h:39
unsigned char uint8
Definition: Core.h:12
szt size() const
Number of elements in list.
Definition: List.h:472
IterR rbegin()
Definition: List.h:366
Iter_ operator++(int)
Definition: List.h:299
~List()
Definition: List.h:77
bool operator==(const Iter_ &rhs) const
Definition: List.h:302
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
IterR_(Iter &it=Iter())
Definition: List.h:342
bool d() const
Definition: List.h:40
static const intptr_t d_mask
Definition: List.h:34
void push_front(T_ &&val)
Insert new element constructed with val at the beginning of the list.
Definition: List.h:86
bool erase(Iter &it, optional< T & > val=optnull)
Erase element at iterator position and move it into val, and advance iterator. Returns true if this t...
Definition: List.h:427
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
T * alloc(szt count=1)
Allocate memory for count number of T objects. Objects are not constructed.
Definition: Allocator.h:31
Iter_< T_ > Iter
Definition: List.h:334
~Iter_()
Definition: List.h:237
Configuration interface for memory manager. Inherit this class and override types and static members...
Definition: HazardMem.h:32
pointer operator->() const
Definition: List.h:306
ConstIter end() const
Get iterator to the end of the list.
Definition: List.h:324
Iter end()
Definition: List.h:325
T_ & reference
Definition: List.h:224
IterR_< const T > ConstIterR
Definition: List.h:362
bool back(T &val)
Get a copy of the element the end of the list. Returns true on success, false if there is no element...
Definition: List.h:382
Specialization for references.
Definition: Optional.h:132
T_ & reference
Definition: List.h:340
ConstIterR rend() const
Get reverse iterator to the beginning of the list.
Definition: List.h:369
Reverse iterator.
Definition: List.h:329
Iter begin()
Definition: List.h:321
ConstIterR rbegin() const
Get reverse iterator to the end of the list.
Definition: List.h:365
reference operator*() const
Definition: List.h:305
IterR_ & operator--()
Definition: List.h:345
Alloc_ Alloc
Definition: List.h:58
Node * ptr() const
Get node pointer.
Definition: HazardMem.h:26
HazardMemNode Node
Definition: HazardMem.h:34
Iter_()
Definition: List.h:226
Iter_< T > Iter
Definition: List.h:316
Lock-free memory manager, provides safe memory reclamation for concurrent algorithms.
Definition: HazardMem.h:57
void wait()
Perform backoff, suspend thread.
Definition: Backoff.h:56
static const intptr_t ptr_mask
Definition: List.h:35
void reset()
Reset backoff to initial state.
Definition: Backoff.h:59
IterR_< T > IterR
Definition: List.h:361
Iter_(const Iter_ &it)
Definition: List.h:235
std::bidirectional_iterator_tag iterator_category
Definition: List.h:220
Iter insert(const Iter &it, T_ &&val)
Insert new element constructed with val before iterator position. Returns iterator pointing to new el...
Definition: List.h:392
Global Honeycomb namespace.
Base link class, contains a generic Cas-able data chunk. The data chunk contains a pointer to a Hazar...
Definition: HazardMem.h:23
Lock-free doubly-linked list.
Definition: List.h:24
bool pop_back(optional< T & > val=optnull)
Remove element from the end of the list and move it into val. Returns true on success, false if there is no element to pop.
Definition: List.h:173
reference operator*() const
Definition: List.h:352
IterR_ operator--(int)
Definition: List.h:347