Lock-free transfer of ownership to a reader that must never block, plus a ring for handing the displaced value back so the audio thread never frees.
More...
#include <slot.hpp>
|
| | Handoff ()=default |
| | Handoff (const Handoff &)=delete |
| Handoff & | operator= (const Handoff &)=delete |
| | ~Handoff () |
| | Reclaims anything still parked. Both threads must have stopped.
|
| bool | publish (std::unique_ptr< T > next) |
| | Producer thread.
|
| std::unique_ptr< T > | try_consume () noexcept |
| | Audio-thread-callable.
|
| bool | retire (std::unique_ptr< T > &displaced) noexcept |
| | Audio-thread-callable.
|
| bool | has_retire_capacity (std::size_t n=1) const noexcept |
| | Room in the retire ring for n more values.
|
| std::size_t | drain_retired () |
| | Producer / worker thread. Free every parked value. Returns the count.
|
| std::unique_ptr< T > | drain_retired_one () |
| | Producer / worker thread.
|
| bool | has_pending () const noexcept |
| bool | has_retired () const noexcept |
template<typename T, std::size_t RetireCapacity = 8>
class pulp::runtime::Handoff< T, RetireCapacity >
Lock-free transfer of ownership to a reader that must never block, plus a ring for handing the displaced value back so the audio thread never frees.
This is the pattern Timur Doumler and Ross Bencina describe as standard practice for real-time audio: build the object off-thread, swap a pointer, return the old one through a lock-free FIFO for a non-RT thread to destroy.
if (next) {
auto displaced = std::exchange(current_, std::move(next));
(void)swapper.
retire(displaced);
}
}
bool retire(std::unique_ptr< T > &displaced) noexcept
Audio-thread-callable.
Definition slot.hpp:297
bool has_retire_capacity(std::size_t n=1) const noexcept
Room in the retire ring for n more values.
Definition slot.hpp:307
bool has_pending() const noexcept
Definition slot.hpp:325
std::size_t drain_retired()
Producer / worker thread. Free every parked value. Returns the count.
Definition slot.hpp:312
bool publish(std::unique_ptr< T > next)
Producer thread.
Definition slot.hpp:271
std::unique_ptr< T > try_consume() noexcept
Audio-thread-callable.
Definition slot.hpp:284
- Warning
- One producer thread, one consumer (audio) thread.
◆ Handoff() [1/2]
template<typename T, std::size_t RetireCapacity = 8>
◆ Handoff() [2/2]
template<typename T, std::size_t RetireCapacity = 8>
◆ ~Handoff()
template<typename T, std::size_t RetireCapacity = 8>
Reclaims anything still parked. Both threads must have stopped.
◆ drain_retired()
template<typename T, std::size_t RetireCapacity = 8>
Producer / worker thread. Free every parked value. Returns the count.
◆ drain_retired_one()
template<typename T, std::size_t RetireCapacity = 8>
Producer / worker thread.
Pop one parked value, for callers that want to inspect it before it dies. Returns nullptr when none are queued.
◆ has_pending()
template<typename T, std::size_t RetireCapacity = 8>
◆ has_retire_capacity()
template<typename T, std::size_t RetireCapacity = 8>
Room in the retire ring for n more values.
Reserve before committing to a swap so a retire never fails inline and strands a value on the audio thread.
◆ has_retired()
template<typename T, std::size_t RetireCapacity = 8>
◆ operator=()
template<typename T, std::size_t RetireCapacity = 8>
◆ publish()
template<typename T, std::size_t RetireCapacity = 8>
Producer thread.
Publish a value for the audio thread to claim. If a previously published value has not been consumed yet, it is replaced and freed here — on the producer thread, never the audio thread.
Returns false only for a null argument.
◆ retire()
template<typename T, std::size_t RetireCapacity = 8>
Audio-thread-callable.
Park the value the audio thread is displacing so a non-RT thread can free it.
Returns false when the retire ring is full; on false the caller still owns displaced (the unique_ptr is left intact). Gate on has_retire_capacity() before consuming so this never happens in well-paced operation.
RT contract: never allocates, never blocks, never frees.
◆ retire_capacity()
template<typename T, std::size_t RetireCapacity = 8>
|
|
inlinestaticconstexprnoexcept |
◆ try_consume()
template<typename T, std::size_t RetireCapacity = 8>
Audio-thread-callable.
Atomically claim the most recently published value, or nullptr if there is none.
RT contract: never allocates, never blocks, never frees.
The documentation for this class was generated from the following file:
- /home/runner/work/pulp/pulp/core/runtime/include/pulp/runtime/slot.hpp