38 #ifndef UTILS_TYPES_SPSC_QUEUE_HPP 39 #define UTILS_TYPES_SPSC_QUEUE_HPP 48 template <
class E, FwSizeType CAPACITY>
51 static_assert(CAPACITY * 2 <= std::numeric_limits<FwSizeType>::max(),
52 "This implementation distinguishes full and empty queues by using indices modulo CAPACITY * 2, " 53 "so CAPACITY * 2 must fit in the index type");
55 SpscQueue() : m_elements{}, m_nextProduceIdx(0), m_nextConsumeIdx(0) {
56 FW_ASSERT(this->m_nextProduceIdx.is_lock_free() && this->m_nextConsumeIdx.is_lock_free());
60 return countElements(this->m_nextProduceIdx.load(), this->m_nextConsumeIdx.load()) == CAPACITY;
63 bool isEmpty()
const {
return countElements(this->m_nextProduceIdx.load(), this->m_nextConsumeIdx.load()) == 0; }
67 FwSizeType nextProduceIdx = this->m_nextProduceIdx.load();
68 FwSizeType nextConsumeIdx = this->m_nextConsumeIdx.load();
70 if (countElements(nextProduceIdx, nextConsumeIdx) == CAPACITY) {
74 this->m_elements[nextProduceIdx % CAPACITY] = element;
75 this->m_nextProduceIdx.store((nextProduceIdx + 1) % (CAPACITY * 2));
81 FwSizeType nextProduceIdx = this->m_nextProduceIdx.load();
82 FwSizeType nextConsumeIdx = this->m_nextConsumeIdx.load();
84 if (countElements(nextProduceIdx, nextConsumeIdx) == 0) {
88 elementOut = this->m_elements[nextConsumeIdx % CAPACITY];
89 this->m_nextConsumeIdx.store((nextConsumeIdx + 1) % (CAPACITY * 2));
94 bool peek(E& elementOut)
const {
95 FwSizeType nextProduceIdx = this->m_nextProduceIdx.load();
96 FwSizeType nextConsumeIdx = this->m_nextConsumeIdx.load();
98 if (countElements(nextProduceIdx, nextConsumeIdx) == 0) {
102 elementOut = this->m_elements[nextConsumeIdx % CAPACITY];
113 E m_elements[CAPACITY];
114 std::atomic<FwSizeType> m_nextProduceIdx;
115 std::atomic<FwSizeType> m_nextConsumeIdx;
118 FwSizeType count = (nextProduceIdx - nextConsumeIdx + CAPACITY * 2) % (CAPACITY * 2);
119 FW_ASSERT(count <= CAPACITY, nextProduceIdx, nextConsumeIdx, count, CAPACITY);
PlatformSizeType FwSizeType
bool peek(E &elementOut) const
bool produce(const E &element)
bool consume(E &elementOut)