23template<
typename T,
size_t SlotSize>
26 static_assert(std::has_single_bit(SlotSize),
"Only power-of-two number of messages size allowed.");
30 static constexpr size_t fifo_size = 65536;
31 static constexpr size_t slot_size = SlotSize;
32 static constexpr size_t num_slots = fifo_size / slot_size;
35 static constexpr size_t buffer_size = slot_size -
sizeof(value_type *);
54 template<typename Operation>
60 auto &slot = _slots[index / slot_size];
64 if (
auto ptr = slot.pointer.load(std::memory_order::acquire)) {
65 std::forward<Operation>(operation)(*ptr);
68 if (ptr ==
static_cast<void *
>(slot.buffer.data())) {
75 slot.pointer.store(
nullptr, std::memory_order::release);
89 template<
typename Operation>
90 void take_all(Operation
const &operation)
noexcept
95 tt_no_inline
void contended() noexcept
97 using namespace std::literals::chrono_literals;
100 ++global_counter<
"wfree_fifo">;
108 template<
typename Message,
typename... Args>
109 tt_force_inline
void emplace(Args &&...args)
noexcept requires(
sizeof(Message) <= slot_type::buffer_size)
118 ttlet index = _head.
fetch_add(slot_size, std::memory_order::relaxed);
119 tt_axiom(index % slot_size == 0);
121 auto &slot = *std::launder(std::assume_aligned<slot_size>(
reinterpret_cast<slot_type*
>(
reinterpret_cast<char*
>(
this) + index)));
129 while (slot.pointer.load(std::memory_order_acquire)) {
131 [[unlikely]] contended();
135 auto new_ptr =
new (slot.buffer.data()) Message(std::forward<Args>(args)...);
138 slot.pointer.store(new_ptr, std::memory_order::release);
145 template<
typename Message,
typename... Args>
146 tt_force_inline
void emplace(Args &&...args)
noexcept
155 ttlet index = _head.
fetch_add(slot_size, std::memory_order::relaxed);
156 tt_axiom(index % slot_size == 0);
159 auto &slot = _slots[index / slot_size];
164 ttlet new_ptr =
new Message(std::forward<Args>(args)...);
169 while (slot.pointer.load(std::memory_order::relaxed)) {
171 [[unlikely]] contended();
175 slot.pointer.store(new_ptr, std::memory_order::release);
A wait-free multiple-producer/single-consumer fifo designed for absolute performance.
Definition wfree_fifo.hpp:24
bool take_one(Operation &&operation) noexcept
Take one message from the fifo slot.
Definition wfree_fifo.hpp:55
tt_force_inline void emplace(Args &&...args) noexcept
Create an message in-place on the fifo.
Definition wfree_fifo.hpp:109
void take_all(Operation const &operation) noexcept
Take all message from the queue.
Definition wfree_fifo.hpp:90
tt_force_inline void emplace(Args &&...args) noexcept
Create an message in-place on the fifo.
Definition wfree_fifo.hpp:146
Definition wfree_fifo.hpp:34
Definition concepts.hpp:34