Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
spsc_queue.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <atomic>
4#include <cstddef>
5#include <cstdint>
6#include <optional>
7#include <utility>
8#include <choc/containers/choc_SingleReaderSingleWriterFIFO.h>
9
10namespace pulp::runtime {
11
13 std::size_t size_approx = 0;
14 std::size_t capacity = 0;
15 std::uint64_t overflow_count = 0;
16};
17
18// Single-producer/single-consumer lock-free queue. Either endpoint may be the
19// realtime thread: audio -> UI telemetry and UI -> audio commands are both
20// supported, provided there is exactly one producer and one consumer.
21// Wraps choc::fifo::SingleReaderSingleWriterFIFO
22template<typename T, std::size_t Capacity>
23class SpscQueue {
24 static_assert(Capacity > 0, "Capacity must be > 0");
25
26public:
28 fifo_.reset(Capacity);
29 }
30
31 // Producer: push an item. Returns false if full.
32 bool try_push(const T& item) {
33 const bool pushed = fifo_.push(item);
34 if (!pushed) overflow_count_.fetch_add(1, std::memory_order_relaxed);
35 return pushed;
36 }
37
38 bool try_push(T&& item) {
39 const bool pushed = fifo_.push(std::move(item));
40 if (!pushed) overflow_count_.fetch_add(1, std::memory_order_relaxed);
41 return pushed;
42 }
43
44 // Consumer: pop an item into reusable storage.
45 bool try_pop(T& item) {
46 return fifo_.pop(item);
47 }
48
49 // Consumer: pop an item. Returns nullopt if empty.
50 std::optional<T> try_pop() {
51 T item{};
52 if (try_pop(item)) {
53 return item;
54 }
55 return std::nullopt;
56 }
57
58 bool empty() const {
59 return fifo_.getUsedSlots() == 0;
60 }
61
62 std::size_t size_approx() const {
63 return fifo_.getUsedSlots();
64 }
65
66 std::uint64_t overflow_count() const {
67 return overflow_count_.load(std::memory_order_relaxed);
68 }
69
71 overflow_count_.store(0, std::memory_order_relaxed);
72 }
73
75 return {
76 .size_approx = size_approx(),
77 .capacity = Capacity,
78 .overflow_count = overflow_count(),
79 };
80 }
81
82 static constexpr std::size_t capacity() { return Capacity; }
83
84private:
85 choc::fifo::SingleReaderSingleWriterFIFO<T> fifo_;
86 std::atomic<std::uint64_t> overflow_count_{0};
87};
88
89} // namespace pulp::runtime
std::size_t size_approx() const
Definition spsc_queue.hpp:62
bool try_pop(T &item)
Definition spsc_queue.hpp:45
SpscQueue()
Definition spsc_queue.hpp:27
void reset_overflow_count()
Definition spsc_queue.hpp:70
std::uint64_t overflow_count() const
Definition spsc_queue.hpp:66
std::optional< T > try_pop()
Definition spsc_queue.hpp:50
bool try_push(T &&item)
Definition spsc_queue.hpp:38
static constexpr std::size_t capacity()
Definition spsc_queue.hpp:82
bool try_push(const T &item)
Definition spsc_queue.hpp:32
bool empty() const
Definition spsc_queue.hpp:58
SpscQueueTelemetry telemetry() const
Definition spsc_queue.hpp:74
Definition generated_event_source.hpp:33
Definition spsc_queue.hpp:12
std::size_t capacity
Definition spsc_queue.hpp:14
std::size_t size_approx
Definition spsc_queue.hpp:13
std::uint64_t overflow_count
Definition spsc_queue.hpp:15