6#ifndef XENIUM_MICHAEL_SCOTT_QUEUE_HPP
7#define XENIUM_MICHAEL_SCOTT_QUEUE_HPP
9#include <xenium/acquire_guard.hpp>
10#include <xenium/backoff.hpp>
11#include <xenium/parameter.hpp>
12#include <xenium/policy.hpp>
16#pragma warning(disable: 4324)
36template <
class T,
class... Policies>
46 static_assert(parameter::is_set<reclaimer>::value,
"reclaimer policy must be specified");
72 using marked_ptr =
typename concurrent_ptr::marked_ptr;
73 using guard_ptr =
typename concurrent_ptr::guard_ptr;
75 struct node : reclaimer::template enable_concurrent_ptr<node>
78 node(
T&& v) : value(std::move(v)) {}
84 alignas(64) concurrent_ptr head;
85 alignas(64) concurrent_ptr tail;
92 head.store(
n, std::memory_order_relaxed);
93 tail.store(
n, std::memory_order_relaxed);
96template <
class T,
class... Policies>
97michael_scott_queue<T, Policies...>::~michael_scott_queue()
100 auto n = head.load(std::memory_order_acquire);
104 auto next = n->next.load(std::memory_order_acquire);
110template <
class T,
class... Policies>
113 node*
n =
new node(std::move(value));
122 t.acquire(tail, std::memory_order_acquire);
126 auto next =
t->next.load(std::memory_order_acquire);
127 if (next.get() !=
nullptr)
131 tail.compare_exchange_weak(
expected, next, std::memory_order_release, std::memory_order_relaxed);
138 if (
t->next.compare_exchange_weak(
null,
n, std::memory_order_release, std::memory_order_relaxed))
147 tail.compare_exchange_strong(
expected,
n, std::memory_order_release, std::memory_order_relaxed);
160 h.acquire(head, std::memory_order_acquire);
164 auto next = acquire_guard(
h->next, std::memory_order_acquire);
165 if (head.load(std::memory_order_relaxed).get() !=
h.get())
170 if (next.get() ==
nullptr)
173 marked_ptr
t = tail.load(std::memory_order_relaxed);
176 if (
h.get() ==
t.get())
179 tail.compare_exchange_weak(
t, next, std::memory_order_release, std::memory_order_relaxed);
186 if (head.compare_exchange_weak(
expected, next, std::memory_order_release, std::memory_order_relaxed))
189 result = std::move(next->value);
An unbounded generic lock-free multi-producer/multi-consumer FIFO queue.
Definition michael_scott_queue.hpp:37
void push(T value)
Definition michael_scott_queue.hpp:111
bool try_pop(T &result)
Definition michael_scott_queue.hpp:151
Slim wrapper around std::hash with specialization for pointer types.
Definition hash.hpp:25
Dummy backoff strategy that does nothing.
Definition backoff.hpp:17
Policy to configure the backoff strategy.
Definition policy.hpp:39
Policy to configure the reclamation scheme to be used.
Definition policy.hpp:25