|
| | RingBufferSPSC ()=default |
| |
| | RingBufferSPSC (const RingBufferSPSC &)=delete |
| |
| | RingBufferSPSC (size_t capacity) |
| |
| | ~RingBufferSPSC () override |
| |
| T * | address () override |
| | returns the address of the start of the physical read buffer
|
| |
| int | available () override |
| | provides the number of entries that are available to read
|
| |
| int | availableForWrite () override |
| | provides the number of entries that are available to write
|
| |
| virtual int | bufferCountEmpty () |
| | Provides the number of entries that are available to write: -1 does not apply.
|
| |
| virtual int | bufferCountFilled () |
| | Provides the number of entries that are available to read: -1 does not apply.
|
| |
| void | clear () |
| | same as reset
|
| |
| virtual int | clearArray (int len) |
| | Removes the next len entries.
|
| |
| virtual void | flush () |
| |
| bool | isEmpty () |
| |
| virtual bool | isFull () |
| | checks if the buffer is full
|
| |
| virtual float | levelPercent () |
| | Returns the level of the buffer in %.
|
| |
| RingBufferSPSC & | operator= (const RingBufferSPSC &)=delete |
| |
| bool | peek (T &result) override |
| | peeks the actual entry from the buffer
|
| |
| bool | read (T &result) override |
| | reads a single value
|
| |
| int | readArray (T data[], int len) override |
| | reads multiple values
|
| |
| void | reset () override |
| | clears the buffer
|
| |
| bool | resize (size_t capacity) override |
| | Resizes the buffer if supported: returns false if not supported.
|
| |
| size_t | size () override |
| |
| bool | write (T data) override |
| | write add an entry to the buffer
|
| |
| int | writeArray (const T data[], int len) override |
| | Fills the buffer data.
|
| |
| virtual int | writeArrayOverwrite (const T data[], int len) |
| | Fills the buffer data and overwrites the oldest data if the buffer is full.
|
| |
template<typename T = uint8_t>
class audio_tools::RingBufferSPSC< T >
Lock-free Single-Producer Single-Consumer ring buffer.
Safe to use from two cores / contexts simultaneously only when there is exactly one writer and exactly one reader — e.g. an ISR or a second core filling the buffer while the main loop drains it (USB audio RX path on RP2040 with core-1 tud_task).
Design ──────
- head_ is the byte-count of everything ever written; only the producer writes it (release store) and the consumer reads it (acquire load).
- tail_ is the byte-count of everything ever read; only the consumer writes it (release store) and the producer reads it (acquire load).
- No shared mutable counter between the two sides — the shared mutable state of RingBuffer<T>::_numElems is the classic data race on M0+.
- Capacity is rounded up to the next power of two so that index masking replaces modulo and wrap-around is handled by a single bit-AND.
- readArray / writeArray use memcpy for bulk transfers and split them at the wrap-around point, giving at most two memcpy calls per operation.
Not suitable for MPMC (multiple producers or consumers); use QueueLockFree for that.
- Template Parameters
-
| T | Element type. Works for any trivially-copyable T; the bulk-copy optimisation is most effective for T=uint8_t (audio streams). |
- Author
- Phil Schatzmann
- Copyright
- GPLv3