The Windows host could tank a local game's 1% lows — mint retries broadcast PnP device changes at the whole box, and session tuning never reverted
#185
Merged
enricobuehlermerged 2 commits from worktree-audio-stutter-fixes into main2026-08-12 22:03:51 +00:00
Field report (2026-08-12): Punktfunk's audio devices make Helldivers 2 stutter — 1% lows of 2–5 FPS — and uninstalling restores the lost performance. Code triage found two host-side mechanisms that can do that to a locally played game; this fixes both.
1. The minted-endpoint retry storm
minted::ensure_blocking() ran a full provisioning pass on every virtual-mic open with no cooldown, no in-flight guard, and no give-up — and ensure_role() reached UpdateDriverForPlugAndPlayDevicesWeven when the devnode already existed. The mic pump reopens with backoff capped at 60 s, so on any box where minting cannot converge (driver refused, endpoints never appear), the host paid roughly once a minute, forever:
a SetupAPI sweep of the whole MEDIA class,
a PnP driver (re)bind, whose device-change broadcast every running app services — games like Helldivers 2 (Wwise + in-game voice) rebuild their audio graph on it, a multi-hundred-millisecond stall each time,
up to two SetDefaultEndpoint restores.
A periodic hard hitch with fine average FPS is exactly a "1% lows of 2–5" signature. The fix, in layers:
Steady-state fast path in ensure_role(): a marker devnode whose endpoints are all live resolves by ID and returns — no PnP touch, no default-device writes. ("Healthy" uses the same endpoint resolvers the full pass polls, so it's exactly the state the full pass would declare ready.)
ensure_blocking() waits on an in-flight pass (bounded) instead of racing a second SetupAPI sweep against it — that race is how a pump once ended up wired to the cable while the worker minted (the dead-mic-air deploy race).
The 60 s RETRY_COOLDOWN now applies to the blocking path too. The first-ever resolve still blocks unconditionally, preserving the cold-boot mint contract the function documents.
Five unlatched passes stop minting for the host lifetime (counted across the worker and the blocking path, logged once); a service restart re-arms. A box that cannot mint must not tax every app on it forever.
2. Session tuning that never reverted
pf-frame's tune_process_once() put the whole host process at HIGH_PRIORITY_CLASS with timeBeginPeriod(1) and DWM MMCSS on the first hot stream thread, documented as "reverts at process exit" — but the host is a 24/7 service. After a single streaming session it competed at HIGH priority with a 1 ms global timer against whatever the user played locally, indefinitely.
The process-wide tuning is now refcounted across the hot threads via a TLS guard: the first hot thread applies it, the last one's exit reverts it (timeEndPeriod(1), DwmEnableMMCSS(0), NORMAL class) — the same thread-exit lifetime the per-thread MMCSS and execution-state effects already ride, so a session that ends tears everything down with no new bookkeeping. Every on_hot_thread() call site was checked to be a session-scoped thread (capture/encode, packetizer, send, NVENC retrieve). The refcount transitions sit under a Mutex, not atomics: an interleaved add/sub pair could otherwise finish with a running session untuned.
Notes
Layered on top of #179 (mic-stream idle-stop) — together they make an idle host genuinely quiescent: no running WASAPI stream, no PnP retries, no elevated priority class.
Which of the two mechanisms the reporter's box was actually hitting is still unconfirmed — the discriminating check is whether stopping the service (without uninstalling) restores performance, and whether the host log shows mint retries.
Verification
Gated on the windows-amd64 runner (C:\pf-verify), wipe→ship→touch so the compile is provably real:
cargo test -p punktfunk-host --release audio:: — 83/83 ✓
cargo fmt --all --check ✓
Not yet verified on glass: a box that reproduces the field stutter (none of ours does); the giving-up warning and the revert log line are the observable markers for a field follow-up.
Field report (2026-08-12): Punktfunk's audio devices make Helldivers 2 stutter — 1% lows of 2–5 FPS — and uninstalling restores the lost performance. Code triage found two host-side mechanisms that can do that to a *locally played* game; this fixes both.
## 1. The minted-endpoint retry storm
`minted::ensure_blocking()` ran a **full provisioning pass on every virtual-mic open** with no cooldown, no in-flight guard, and no give-up — and `ensure_role()` reached `UpdateDriverForPlugAndPlayDevicesW` **even when the devnode already existed**. The mic pump reopens with backoff capped at 60 s, so on any box where minting cannot converge (driver refused, endpoints never appear), the host paid roughly once a minute, forever:
* a SetupAPI sweep of the whole MEDIA class,
* a PnP driver (re)bind, whose **device-change broadcast every running app services** — games like Helldivers 2 (Wwise + in-game voice) rebuild their audio graph on it, a multi-hundred-millisecond stall each time,
* up to two `SetDefaultEndpoint` restores.
A periodic hard hitch with fine average FPS is exactly a "1% lows of 2–5" signature. The fix, in layers:
* **Steady-state fast path in `ensure_role()`**: a marker devnode whose endpoints are all live resolves by ID and returns — no PnP touch, no default-device writes. ("Healthy" uses the same endpoint resolvers the full pass polls, so it's exactly the state the full pass would declare ready.)
* **`ensure_blocking()` waits on an in-flight pass** (bounded) instead of racing a second SetupAPI sweep against it — that race is how a pump once ended up wired to the cable while the worker minted (the dead-mic-air deploy race).
* **The 60 s `RETRY_COOLDOWN` now applies to the blocking path too.** The first-ever resolve still blocks unconditionally, preserving the cold-boot mint contract the function documents.
* **Five unlatched passes stop minting for the host lifetime** (counted across the worker and the blocking path, logged once); a service restart re-arms. A box that cannot mint must not tax every app on it forever.
## 2. Session tuning that never reverted
`pf-frame`'s `tune_process_once()` put the **whole host process** at `HIGH_PRIORITY_CLASS` with `timeBeginPeriod(1)` and DWM MMCSS on the first hot stream thread, documented as "reverts at process exit" — but the host is a 24/7 service. After a single streaming session it competed at HIGH priority with a 1 ms global timer against whatever the user played locally, indefinitely.
The process-wide tuning is now **refcounted across the hot threads** via a TLS guard: the first hot thread applies it, the last one's exit reverts it (`timeEndPeriod(1)`, `DwmEnableMMCSS(0)`, NORMAL class) — the same thread-exit lifetime the per-thread MMCSS and execution-state effects already ride, so a session that ends tears everything down with no new bookkeeping. Every `on_hot_thread()` call site was checked to be a session-scoped thread (capture/encode, packetizer, send, NVENC retrieve). The refcount transitions sit under a Mutex, not atomics: an interleaved add/sub pair could otherwise finish with a running session untuned.
## Notes
* Layered on top of #179 (mic-stream idle-stop) — together they make an idle host genuinely quiescent: no running WASAPI stream, no PnP retries, no elevated priority class.
* Which of the two mechanisms the reporter's box was actually hitting is still unconfirmed — the discriminating check is whether stopping the service (without uninstalling) restores performance, and whether the host log shows mint retries.
## Verification
Gated on the windows-amd64 runner (`C:\pf-verify`), wipe→ship→touch so the compile is provably real:
* `cargo clippy -p pf-frame -p punktfunk-host --all-targets --release -- -D warnings` ✓
* `cargo test -p pf-frame --release` — 9/9 ✓
* `cargo test -p punktfunk-host --release audio::` — **83/83** ✓
* `cargo fmt --all --check` ✓
Not yet verified on glass: a box that reproduces the field stutter (none of ours does); the giving-up warning and the revert log line are the observable markers for a field follow-up.
Field report (2026-08-12): Punktfunk's audio devices tank Helldivers 2 to
1% lows of 2-5 FPS; uninstalling restores performance. Two host-side
mechanisms can plausibly do that, both fixed here.
The mint retry storm: minted::ensure_blocking() ran a FULL provisioning
pass on every mic-pump open with no cooldown, no in-flight guard, and no
give-up - and ensure_role() reached UpdateDriverForPlugAndPlayDevicesW
even when the devnode already existed. On a box where minting never
latches, the pump's reopen backoff (capped 60 s) turned that into a PnP
driver rebind + system-wide device-change broadcast roughly once a
minute, forever - and games rebuild their audio graph on each broadcast.
Now:
* ensure_role() gets a steady-state fast path: a marker devnode whose
endpoints are all live resolves without touching PnP or the
default-device policy.
* ensure_blocking() waits on an in-flight pass instead of racing a
second SetupAPI sweep against it (the dead-mic-air deploy race),
honours RETRY_COOLDOWN after a failed pass (first-ever resolve still
blocks, per the cold-boot mint contract), and
* five unlatched passes stop minting for the host lifetime (a service
restart re-arms) - counted across the worker and the blocking path.
The never-reverted session tuning: pf-frame's tune_process_once() put
the whole host at HIGH_PRIORITY_CLASS with timeBeginPeriod(1) and DWM
MMCSS on the first hot stream thread and documented 'reverts at process
exit' - but the host is a 24/7 service, so after one stream it competed
at HIGH class with a 1 ms global timer against whatever the user played
locally, forever. The process-wide tuning is now refcounted across the
hot threads via a TLS guard: the first hot thread applies it, the last
one's exit reverts it (timeEndPeriod, DwmEnableMMCSS(0), NORMAL class) -
the same thread-exit lifetime the MMCSS and execution-state effects
already ride. Every on_hot_thread() call site is a session-scoped
thread (capture/encode, packetizer, send, NVENC retrieve), so the
revert lands at session teardown.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Field report (2026-08-12): Punktfunk's audio devices make Helldivers 2 stutter — 1% lows of 2–5 FPS — and uninstalling restores the lost performance. Code triage found two host-side mechanisms that can do that to a locally played game; this fixes both.
1. The minted-endpoint retry storm
minted::ensure_blocking()ran a full provisioning pass on every virtual-mic open with no cooldown, no in-flight guard, and no give-up — andensure_role()reachedUpdateDriverForPlugAndPlayDevicesWeven when the devnode already existed. The mic pump reopens with backoff capped at 60 s, so on any box where minting cannot converge (driver refused, endpoints never appear), the host paid roughly once a minute, forever:SetDefaultEndpointrestores.A periodic hard hitch with fine average FPS is exactly a "1% lows of 2–5" signature. The fix, in layers:
ensure_role(): a marker devnode whose endpoints are all live resolves by ID and returns — no PnP touch, no default-device writes. ("Healthy" uses the same endpoint resolvers the full pass polls, so it's exactly the state the full pass would declare ready.)ensure_blocking()waits on an in-flight pass (bounded) instead of racing a second SetupAPI sweep against it — that race is how a pump once ended up wired to the cable while the worker minted (the dead-mic-air deploy race).RETRY_COOLDOWNnow applies to the blocking path too. The first-ever resolve still blocks unconditionally, preserving the cold-boot mint contract the function documents.2. Session tuning that never reverted
pf-frame'stune_process_once()put the whole host process atHIGH_PRIORITY_CLASSwithtimeBeginPeriod(1)and DWM MMCSS on the first hot stream thread, documented as "reverts at process exit" — but the host is a 24/7 service. After a single streaming session it competed at HIGH priority with a 1 ms global timer against whatever the user played locally, indefinitely.The process-wide tuning is now refcounted across the hot threads via a TLS guard: the first hot thread applies it, the last one's exit reverts it (
timeEndPeriod(1),DwmEnableMMCSS(0), NORMAL class) — the same thread-exit lifetime the per-thread MMCSS and execution-state effects already ride, so a session that ends tears everything down with no new bookkeeping. Everyon_hot_thread()call site was checked to be a session-scoped thread (capture/encode, packetizer, send, NVENC retrieve). The refcount transitions sit under a Mutex, not atomics: an interleaved add/sub pair could otherwise finish with a running session untuned.Notes
Verification
Gated on the windows-amd64 runner (
C:\pf-verify), wipe→ship→touch so the compile is provably real:cargo clippy -p pf-frame -p punktfunk-host --all-targets --release -- -D warnings✓cargo test -p pf-frame --release— 9/9 ✓cargo test -p punktfunk-host --release audio::— 83/83 ✓cargo fmt --all --check✓Not yet verified on glass: a box that reproduces the field stutter (none of ours does); the giving-up warning and the revert log line are the observable markers for a field follow-up.