|
@@ -22,6 +22,55 @@ class SPSCQueue {
|
|
|
static_assert((Capacity & (Capacity - 1)) == 0, "Capacity must be a power of two.");
|
|
static_assert((Capacity & (Capacity - 1)) == 0, "Capacity must be a power of two.");
|
|
|
|
|
|
|
|
public:
|
|
public:
|
|
|
|
|
+ bool TryPush(T&& t) {
|
|
|
|
|
+ const size_t write_index = m_write_index.load();
|
|
|
|
|
+
|
|
|
|
|
+ // Check if we have free slots to write to.
|
|
|
|
|
+ if ((write_index - m_read_index.load()) == Capacity) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Determine the position to write to.
|
|
|
|
|
+ const size_t pos = write_index % Capacity;
|
|
|
|
|
+
|
|
|
|
|
+ // Push into the queue.
|
|
|
|
|
+ m_data[pos] = std::move(t);
|
|
|
|
|
+
|
|
|
|
|
+ // Increment the write index.
|
|
|
|
|
+ ++m_write_index;
|
|
|
|
|
+
|
|
|
|
|
+ // Notify the consumer that we have pushed into the queue.
|
|
|
|
|
+ std::scoped_lock lock{cv_mutex};
|
|
|
|
|
+ cv.notify_one();
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ template <typename... Args>
|
|
|
|
|
+ bool TryPush(Args&&... args) {
|
|
|
|
|
+ const size_t write_index = m_write_index.load();
|
|
|
|
|
+
|
|
|
|
|
+ // Check if we have free slots to write to.
|
|
|
|
|
+ if ((write_index - m_read_index.load()) == Capacity) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Determine the position to write to.
|
|
|
|
|
+ const size_t pos = write_index % Capacity;
|
|
|
|
|
+
|
|
|
|
|
+ // Emplace into the queue.
|
|
|
|
|
+ std::construct_at(std::addressof(m_data[pos]), std::forward<Args>(args)...);
|
|
|
|
|
+
|
|
|
|
|
+ // Increment the write index.
|
|
|
|
|
+ ++m_write_index;
|
|
|
|
|
+
|
|
|
|
|
+ // Notify the consumer that we have pushed into the queue.
|
|
|
|
|
+ std::scoped_lock lock{cv_mutex};
|
|
|
|
|
+ cv.notify_one();
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
void Push(T&& t) {
|
|
void Push(T&& t) {
|
|
|
const size_t write_index = m_write_index.load();
|
|
const size_t write_index = m_write_index.load();
|
|
|
|
|
|
|
@@ -153,6 +202,17 @@ private:
|
|
|
template <typename T, size_t Capacity = detail::DefaultCapacity>
|
|
template <typename T, size_t Capacity = detail::DefaultCapacity>
|
|
|
class MPSCQueue {
|
|
class MPSCQueue {
|
|
|
public:
|
|
public:
|
|
|
|
|
+ bool TryPush(T&& t) {
|
|
|
|
|
+ std::scoped_lock lock{write_mutex};
|
|
|
|
|
+ return spsc_queue.TryPush(std::move(t));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ template <typename... Args>
|
|
|
|
|
+ bool TryPush(Args&&... args) {
|
|
|
|
|
+ std::scoped_lock lock{write_mutex};
|
|
|
|
|
+ return spsc_queue.TryPush(std::forward<Args>(args)...);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
void Push(T&& t) {
|
|
void Push(T&& t) {
|
|
|
std::scoped_lock lock{write_mutex};
|
|
std::scoped_lock lock{write_mutex};
|
|
|
spsc_queue.Push(std::move(t));
|
|
spsc_queue.Push(std::move(t));
|
|
@@ -196,6 +256,17 @@ private:
|
|
|
template <typename T, size_t Capacity = detail::DefaultCapacity>
|
|
template <typename T, size_t Capacity = detail::DefaultCapacity>
|
|
|
class MPMCQueue {
|
|
class MPMCQueue {
|
|
|
public:
|
|
public:
|
|
|
|
|
+ bool TryPush(T&& t) {
|
|
|
|
|
+ std::scoped_lock lock{write_mutex};
|
|
|
|
|
+ return spsc_queue.TryPush(std::move(t));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ template <typename... Args>
|
|
|
|
|
+ bool TryPush(Args&&... args) {
|
|
|
|
|
+ std::scoped_lock lock{write_mutex};
|
|
|
|
|
+ return spsc_queue.TryPush(std::forward<Args>(args)...);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
void Push(T&& t) {
|
|
void Push(T&& t) {
|
|
|
std::scoped_lock lock{write_mutex};
|
|
std::scoped_lock lock{write_mutex};
|
|
|
spsc_queue.Push(std::move(t));
|
|
spsc_queue.Push(std::move(t));
|