18template <fl::size DescriptorCount, fl::size ArenaSize>
26template <fl::size DescriptorCount, fl::size ArenaSize>
30 for (fl::size i = 0; i < DescriptorCount; i++) {
35template <fl::size DescriptorCount, fl::size ArenaSize>
41 return push(msg.
c_str(),
static_cast<fl::u16
>(len));
44template <fl::size DescriptorCount, fl::size ArenaSize>
47 return push(str, len);
50template <fl::size DescriptorCount, fl::size ArenaSize>
64 *outPtr = &
mArena[desc.mStartIdx];
65 *outLen = desc.mLength;
70template <fl::size DescriptorCount, fl::size ArenaSize>
76 fl::u32 newArenaTail = (
mArenaTail + desc.mLength) & (ArenaSize - 1);
84 mDescriptors[tail] = Descriptor();
87 fl::u32 newTail = (tail + 1) & (DescriptorCount - 1);
95template <fl::size DescriptorCount, fl::size ArenaSize>
100template <fl::size DescriptorCount, fl::size ArenaSize>
103 fl::u32 tail =
mTail;
104 return (head - tail) & (DescriptorCount - 1);
107template <fl::size DescriptorCount, fl::size ArenaSize>
116template <fl::size DescriptorCount, fl::size ArenaSize>
123 fl::u32 head =
mHead;
125 fl::u32 next = (head + 1) & (DescriptorCount - 1);
143 fl::u32 start = aHead;
146 if (start + len > ArenaSize) {
148 fl::u32 padding = ArenaSize - start;
151 if (!
arenaHasSpace(aHead, aTail,
static_cast<fl::u16
>(padding + len))) {
157 aHead = (aHead + padding) & (ArenaSize - 1);
163 for (fl::u16 i = 0; i < len; i++) {
164 mArena[start + i] = str[i];
168 fl::u32 newArenaHead = (aHead + len) & (ArenaSize - 1);
187template <fl::size DescriptorCount, fl::size ArenaSize>
190 while (len < maxLen && str[len] !=
'\0') {
196template <fl::size DescriptorCount, fl::size ArenaSize>
199 fl::u32 used = (aHead - aTail) & (ArenaSize - 1);
200 fl::u32
free = ArenaSize - used - 1;
205template <fl::size DescriptorCount, fl::size ArenaSize>
211template <fl::size DescriptorCount, fl::size ArenaSize>
217template <fl::size DescriptorCount, fl::size ArenaSize>
223template <fl::size DescriptorCount, fl::size ArenaSize>
High-performance ISR-safe async logging queue (SPSC ring buffer) - declarations only.
bool push(const fl::string &msg)
Push a message from fl::string (ISR-safe)
volatile fl::u32 mArenaHead
Producer write position (arena)
volatile fl::u32 mTail
Consumer read position (descriptor ring)
static fl::u16 boundedStrlen(const char *str, fl::u16 maxLen)
volatile fl::u32 mDropped
Count of dropped messages (overflow)
fl::u32 loadArenaTail() const
bool empty() const
Check if queue is empty.
fl::size size() const
Get current number of messages in queue.
bool tryPop(const char **outPtr, fl::u16 *outLen)
Consumer: Try to pop one message (main thread only)
AsyncLogQueue() FL_NOEXCEPT
fl::u32 droppedCount() const
Get number of messages dropped due to overflow.
bool arenaHasSpace(fl::u32 aHead, fl::u32 aTail, fl::u16 len) const
void commit()
Consumer: Commit the popped message to free space (main thread only)
Descriptor mDescriptors[DescriptorCount]
Ring of message descriptors.
volatile fl::u32 mHead
Producer write position (descriptor ring)
volatile fl::u32 mArenaTail
Consumer read position (arena)
High-performance SPSC async log queue.
fl::size length() const FL_NOEXCEPT
const char * c_str() const FL_NOEXCEPT
RAII helper for critical sections (interrupt disable/enable) Automatically disables interrupts on con...
RAII critical section helper and interrupt control declarations.
Base definition for an LED controller.
fl::u32 mStartIdx
Offset into arena where message starts.
fl::u16 mLength
Length of message in bytes.
fl::u16 mPadding
Reserved for alignment (unused)
Descriptor for one log message.