6#include "TTauri/Foundation/required.hpp"
7#include "TTauri/Foundation/atomic.hpp"
18template<
typename T,
size_t Capacity>
19class wfree_message_queue;
21template<
typename T,
size_t Capacity,
bool WriteOperation>
33 parent(other.parent), index(other.index)
35 tt_assume(
this != &other);
36 other.parent =
nullptr;
41 if (parent ==
nullptr) {
45 if constexpr (WriteOperation) {
56 tt_assume(
this != &other);
61 T &operator*()
noexcept
63 return (*parent)[index];
66 T *operator->()
noexcept
68 return &(*parent)[index];
72template<
typename T,
size_t Capacity>
74 using index_type = size_t;
87 static constexpr index_type capacity = Capacity;
91 static constexpr index_type slack = 16;
92 static_assert(capacity > (slack * 2),
"The capacity of the message queue should be much larger than its slack.");
109 index_type
size() const noexcept {
111 return head.
load(std::memory_order_relaxed) - tail.
load(std::memory_order_relaxed);
114 bool empty() const noexcept {
115 return head.
load(std::memory_order_relaxed) <= tail.
load(std::memory_order_relaxed);
118 bool full() const noexcept {
119 return head.
load(std::memory_order_relaxed) >= (tail.
load(std::memory_order_relaxed) + (capacity - slack));
127 template<
typename BlockCounterTag=
void>
129 return {
this, write_start<BlockCounterTag>()};
141 value_type
const &operator[](index_type index)
const noexcept {
142 return messages[index % capacity].value;
145 value_type &operator[](index_type index)
noexcept {
146 return messages[index % capacity].value;
156 template<
typename CounterTag=
void>
158 ttlet index = head.
fetch_add(1, std::memory_order_acquire);
159 auto &message = messages[index % capacity];
165 wait_for_transition<CounterTag>(message.in_use,
false, std::memory_order_acquire);
175 auto &message = messages[index % capacity];
178 message.in_use.store(
true, std::memory_order_release);
187 template<
typename CounterTag=
void>
189 ttlet index = tail.
fetch_add(1, std::memory_order_acquire);
190 auto &message = messages[index % capacity];
193 wait_for_transition<CounterTag>(message.in_use,
true, std::memory_order_acquire);
203 auto &message = messages[index % capacity];
206 message.in_use.store(
false, std::memory_order_release);
Definition wfree_message_queue.hpp:73
index_type size() const noexcept
Definition wfree_message_queue.hpp:109
index_type write_start() noexcept
Start a write into the message queue.
Definition wfree_message_queue.hpp:157
scoped_write_operation write() noexcept
Definition wfree_message_queue.hpp:128
void read_finish(index_type index) noexcept
Definition wfree_message_queue.hpp:202
scoped_read_operation read() noexcept
Definition wfree_message_queue.hpp:137
void write_finish(index_type index) noexcept
Definition wfree_message_queue.hpp:174
index_type read_start() noexcept
Definition wfree_message_queue.hpp:188
Definition wfree_message_queue.hpp:22