Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
pulp::runtime::WakeSignal Class Reference

A wake signal from one or more producers (typically the audio thread) to a single consumer thread that sleeps until there is work. More...

#include <wake_signal.hpp>

Public Types

using Clock = std::chrono::steady_clock

Public Member Functions

 WakeSignal () noexcept
 ~WakeSignal ()
 WakeSignal (const WakeSignal &)=delete
WakeSignal & operator= (const WakeSignal &)=delete
void notify () noexcept
 Producer side, realtime safe. Call after the work is published.
template<typename Ready>
bool wait_until (Ready &&ready, Clock::time_point deadline)
 Consumer side.
template<typename Ready>
bool wait_for (Ready &&ready, Clock::duration timeout)
 wait_until() with a deadline timeout from now.
std::uint64_t posts () const noexcept
 Diagnostics: kernel posts the producers made, and times the consumer woke from a park (a post or a timeout).
std::uint64_t wakes () const noexcept
bool consumer_parked () const noexcept
 Diagnostics: whether the consumer is currently parked (or about to be).

Detailed Description

A wake signal from one or more producers (typically the audio thread) to a single consumer thread that sleeps until there is work.

The producer publishes its work first (a ring write, a release store of a slot state) and then calls notify(). The consumer calls wait_until() or wait_for() with a predicate that reads the same published state.

Realtime contract:

  • notify() never allocates, never locks and never blocks. It is a sequentially consistent fence and one atomic load; it reaches the kernel (a dispatch semaphore on Apple, std::counting_semaphore elsewhere) only while the consumer is parked, so a producer whose consumer is busy makes no system call at all.
  • wait_until() / wait_for() block in the kernel; call them from the consumer thread only, never from the audio thread.

No lost wakeups: the consumer stores parked, fences, then re-checks its predicate before sleeping; the producer publishes, fences, then loads parked. The two sequentially consistent fences guarantee that either the consumer sees the work in its re-check or the producer sees the consumer parked and posts. An extra post (two notifies while parked) only costs the consumer one more predicate check.

One consumer at a time. Destroy the signal only after the consumer has stopped waiting (join the consumer thread first).

// audio thread
ring.push(block);
wake.notify();
// worker thread
while (running) {
wake.wait_for([&] { return !ring.empty() || !running; }, 100ms);
drain(ring);
}

Member Typedef Documentation

◆ Clock

using pulp::runtime::WakeSignal::Clock = std::chrono::steady_clock

Constructor & Destructor Documentation

◆ WakeSignal() [1/2]

pulp::runtime::WakeSignal::WakeSignal ( )
inlinenoexcept

◆ ~WakeSignal()

pulp::runtime::WakeSignal::~WakeSignal ( )
inline

◆ WakeSignal() [2/2]

pulp::runtime::WakeSignal::WakeSignal ( const WakeSignal & )
delete

Member Function Documentation

◆ consumer_parked()

bool pulp::runtime::WakeSignal::consumer_parked ( ) const
inlinenoexcept

Diagnostics: whether the consumer is currently parked (or about to be).

◆ notify()

void pulp::runtime::WakeSignal::notify ( )
inlinenoexcept

Producer side, realtime safe. Call after the work is published.

◆ operator=()

WakeSignal & pulp::runtime::WakeSignal::operator= ( const WakeSignal & )
delete

◆ posts()

std::uint64_t pulp::runtime::WakeSignal::posts ( ) const
inlinenoexcept

Diagnostics: kernel posts the producers made, and times the consumer woke from a park (a post or a timeout).

◆ wait_for()

template<typename Ready>
bool pulp::runtime::WakeSignal::wait_for ( Ready && ready,
Clock::duration timeout )
inline

wait_until() with a deadline timeout from now.

◆ wait_until()

template<typename Ready>
bool pulp::runtime::WakeSignal::wait_until ( Ready && ready,
Clock::time_point deadline )
inline

Consumer side.

Returns true once ready() holds, false if deadline passes first. ready runs before parking and after every wake, so spurious or surplus posts are harmless.

◆ wakes()

std::uint64_t pulp::runtime::WakeSignal::wakes ( ) const
inlinenoexcept

The documentation for this class was generated from the following file:
  • /home/runner/work/pulp/pulp/core/runtime/include/pulp/runtime/wake_signal.hpp