8 #include <xenium/detail/port.hpp>
9 #include <xenium/reclamation/detail/deletable_object.hpp>
11 namespace xenium::reclamation::detail {
12 template <
class Node = deletable_
object>
13 struct retired_nodes {
18 template <
class Node = deletable_
object>
21 _nodes.first =
nullptr;
22 _nodes.last =
nullptr;
25 ~retire_list() { assert(_nodes.first ==
nullptr); }
27 void push(Node* node) {
28 node->next = _nodes.first;
30 if (_nodes.last ==
nullptr) {
35 retired_nodes<Node> steal() {
37 _nodes.first =
nullptr;
38 _nodes.last =
nullptr;
42 [[nodiscard]]
bool empty()
const {
return _nodes.first ==
nullptr; }
45 retired_nodes<Node> _nodes;
48 template <
class Node = deletable_
object>
49 struct counting_retire_list {
50 void push(Node* node) {
55 retired_nodes<Node> steal() {
60 [[nodiscard]]
bool empty()
const {
return list.empty(); }
61 [[nodiscard]] std::size_t size()
const {
return counter; }
64 retire_list<Node> list;
68 template <
class Node = deletable_
object>
70 void add(retired_nodes<Node> nodes) {
71 assert(nodes.first !=
nullptr);
72 auto* h = head.load(std::memory_order_relaxed);
76 }
while (!head.compare_exchange_weak(h, nodes.first, std::memory_order_release, std::memory_order_relaxed));
79 XENIUM_FORCEINLINE Node* adopt() {
80 if (head.load(std::memory_order_relaxed) ==
nullptr) {
85 return head.exchange(
nullptr, std::memory_order_acquire);
89 std::atomic<Node*> head;