Lock-free background-IR shuttle for PartitionedConvolver. More...
#include <convolver_messages.hpp>
Public Member Functions | |
| ConvolverIrSwapperT ()=default | |
| ConvolverIrSwapperT (const ConvolverIrSwapperT &)=delete | |
| ConvolverIrSwapperT & | operator= (const ConvolverIrSwapperT &)=delete |
| bool | stage_ir (const SampleType *ir, std::size_t ir_length, std::size_t block_size) |
| Build a fresh IR state off the audio thread and publish it for the audio thread to pick up. | |
| bool | stage_ir (std::unique_ptr< ConvolverIrStateT< SampleType > > next) |
| Publish a pre-built state. Same semantics as the raw overload. | |
| std::unique_ptr< ConvolverIrStateT< SampleType > > | try_consume () |
| Audio-thread-callable: atomically claim the most recently staged IR, if any. | |
| bool | retire (std::unique_ptr< ConvolverIrStateT< SampleType > > &displaced) |
| Audio-thread-callable: park the IR that the audio thread is displacing so a non-RT thread can free it. | |
| bool | has_retire_capacity () const |
| True if there's room in the retire ring for one more displaced IR. | |
| bool | has_retire_capacity (std::size_t n) const |
Room to park at least n IRs — for a caller that must retire more than one in a single audio-thread step (e.g. | |
| std::size_t | drain_old () |
| UI / worker thread: reclaim ALL retired IRs the audio thread has parked. | |
| std::unique_ptr< ConvolverIrStateT< SampleType > > | drain_old_one () |
| UI / worker thread: pop ONE retired IR for test inspection. | |
| bool | has_pending () const |
| True if a freshly-staged IR is awaiting consumption. | |
| bool | has_retired () const |
| True if any retired IR is awaiting drain. | |
Static Public Member Functions | |
| static constexpr std::size_t | retire_capacity () |
| Compile-time capacity of the retired-IR ring. | |
Lock-free background-IR shuttle for PartitionedConvolver.
Workflow (single producer, single audio-thread consumer):
ConvolverIrSwapper swapper; // background / UI thread PartitionedConvolver conv; // audio thread conv.load_ir(initial_ir, len, 256); // first IR loaded inline
// ── UI / worker thread ── swapper.stage_ir(new_ir, new_len, 256); // allocates, FFTs
// ── audio thread (block boundary) ── conv.try_swap_ir(swapper); // atomically picks up new IR
// ── UI / worker thread ── swapper.drain_old(); // reclaim memory from the displaced IR
Guarantees:
|
default |
|
delete |
|
inline |
UI / worker thread: reclaim ALL retired IRs the audio thread has parked.
Returns the count freed; the actual deallocation runs off the audio thread.
|
inline |
UI / worker thread: pop ONE retired IR for test inspection.
Returns nullptr if none queued.
|
inline |
True if a freshly-staged IR is awaiting consumption.
|
inline |
True if there's room in the retire ring for one more displaced IR.
Audio thread checks this before consuming pending so a swap never strands a displaced IR without an off-thread free path.
|
inline |
Room to park at least n IRs — for a caller that must retire more than one in a single audio-thread step (e.g.
a completed crossfade fade-out PLUS the just-displaced IR). Reserve before committing so no retire ever fails inline and strands an IR on the audio thread.
|
inline |
True if any retired IR is awaiting drain.
|
delete |
|
inlinenodiscard |
Audio-thread-callable: park the IR that the audio thread is displacing so a non-RT thread can free it.
Returns true if the IR was queued for drain; false if the retire ring is already full. On false the displaced state is returned to the caller via the moved-in unique_ptr being LEFT INTACT (caller still owns it). The audio-thread caller (see PartitionedConvolver::try_swap_ir) should gate the swap on has_retire_capacity() first so this path is never hit in well-paced operation.
RT contract: never allocates, never blocks, never frees.
|
inlinestaticconstexpr |
Compile-time capacity of the retired-IR ring.
Sized so a few back-to-back swaps survive a single missed drain tick — past this point, swaps refuse until a drain runs.
|
inline |
Build a fresh IR state off the audio thread and publish it for the audio thread to pick up.
Returns true on success.
If a previously-staged IR has not yet been consumed by the audio thread, this call replaces it and the old pre-built state is freed inline (still on the worker thread — never the audio thread).
|
inline |
Publish a pre-built state. Same semantics as the raw overload.
|
inline |
Audio-thread-callable: atomically claim the most recently staged IR, if any.
Returns nullptr if nothing is pending. NEVER blocks, NEVER allocates, NEVER frees.