Files
punktfunk/crates/pf-frame
enricobuehler 7c964e95c6 fix(host,audio): the rtkit boost was applied to a thread that does not run the capture callback
The comment above it asserted "the stream's `process` callbacks run ON this
mainloop thread (we never hand PipeWire a separate data loop)". We do: the
stream is created with `RT_PROCESS`, so libpipewire runs `process()` on a data
loop it creates and schedules itself.

Measured in one live host process on 2026-08-15:

    punktfunk-pw-au   SCHED_OTHER  nice 0     <- the thread we boost
    data-loop.0       SCHED_RR     prio 20    <- the thread running process()

This is not a stale-comment nit. #232 shipped the rtkit boost to answer a field
report of audio stutter, its success line was read as evidence that the capture
callback had been prioritised, and the follow-up round concluded priorities were
"engaged but insufficient" — when they had never been applied to the thread in
question. Whether the capture callback is realtime decides whether a Wine shader
storm can deschedule it for tens of milliseconds at a 2.7 ms quantum, which is
the exact shape of the one field signature still unexplained (~2 stalls/s of
~30 ms with the node reporting itself continuously Streaming).

So the assumption is replaced by a measurement rather than a guess about which
thread to boost:

- `pf_frame::thread_qos::current_thread_sched()` reports the calling thread's
  policy, RT priority and nice. Three by-value syscalls, no allocation and no
  blocking, so it is safe to call from an RT callback.
- The capture callback reports its own scheduling once per open. Every future
  field log now states what the audio path actually runs as, instead of what we
  asked for somewhere else.

The boost itself is kept: this thread still dispatches state and format events,
and it IS the capture thread when `PUNKTFUNK_STREAM_SINK=0` selects the legacy
monitor path.

Deliberately not attempted here: boosting the data loop. rtkit is a blocking
D-Bus call and must never run inside an RT audio callback, and on the one host
that could be measured PipeWire already gives that thread SCHED_RR/20 — a nice
boost would be inert. Ship the instrument first; a host that reports
SCHED_OTHER here is the evidence that would justify the plumbing.

Gated in the amd64 CI container: fmt, clippy -D warnings on punktfunk-host and
pf-frame, pf-frame tests (incl. a non-vacuity test that the introspection
returns a policy the kernel could have named), and the full punktfunk-host suite
at 560 passed. The one failure, mgmt::tests::local_summary_is_loopback_only_and_
non_sensitive, is the recorded process-global parallel-test race: it passes when
run alone, which is the documented discriminator, and it is untouched by this.
2026-08-15 20:13:14 +02:00
..