Skip to content

obs-gpu-status: Back off from slow GPU usage sources - #1287

Merged
zackees merged 3 commits into
obs-rust:masterfrom
vpacher:feat/1022-usage-backoff
Oct 17, 2026
Merged

zackees merged 3 commits into
obs-rust:masterfrom
vpacher:feat/1022-usage-backoff

Conversation

@vpacher

@vpacher vpacher commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Refs #1022

Go-ahead for this part of #1022 (the claim bot only sees the issue-level claim): #1022 (comment)

What and why

The backoff follow-up from #1022 (zackees' proposal, claimed in #1022 (comment)): a usage source that is slow must not keep the obs-gpu-usage thread busy, must not leave an old number on the label, and must not be asked forever. It applies to every source (NVML, amdgpu, IOKit, PDH). #1271 makes PDH's normal cost small; this covers the degenerate case.

This PR (the defaults from the claim):

  1. Duty cycle: usage::next_interval(elapsed) = 9 × the sample's duration, at least 1 s, at most 30 s. Sampling takes at most about a tenth of the thread's time; the next fast sample gives 1 s again.
  2. Staleness: the thread publishes each sample with its time and the pause in force. usage::current() drops a reading older than 3 pauses, also while a sample hangs. The label shows GPU: n/a and the tooltip "The GPU reading is late." (new en-US key Basic.StatusBar.Gpu.Stale, not the "no source" text); the JSON usage is null.
  3. Demotion: Sampler times each source call (injectable clock). A call over 2 s is slow; 3 slow calls in a row demote the source for the session, and the next source answers. A fast call resets the count. Each demotion is reported once.
  4. Log line: a demotion becomes one OBS log line, for example GPU usage: pdh is too slow (2500 ms, 3000 ms, 2100 ms); not asked again in this session. The thread queues it; the frontend takes it with the new obs_gpu_status_take_log() in GpuStatus::Query() and logs it with blog(LOG_WARNING). Not in the report JSON, so a GetStats call cannot swallow it.
  5. Single flight: unchanged, one thread.
  6. Docs: a "Slow sources" paragraph in docs/gpu-status.md; the ledger line in docs/features.md.

Differences from the claim: the stale tooltip says "The GPU reading is late." instead of reusing the "no source" text, which would be wrong for a source that exists; the pacing is a function (next_interval), not a Pacer type; and the PR does not wait for #1271, because it is independent of it.

Independent of #1264 and #1271 (different files, apart from separate paragraphs in the docs); the tests use Source::Iokit as the slow source, so they do not need Source::Pdh.

RED → GREEN

  • RED e334b2f: Tier 1 tests with a fake clock that each fake source advances by its cost. With stubs that keep 1 s, never age a reading and never demote, 6 fail: the pause (left: 1s, right: 1.8s), staleness (left: Some(..), right: None), demotion (left: [], right: [Demotion { source: Iokit, times: [2.5s, 3s, 2.1s] }]), a slow source without a reading, the stale tooltip (NoSource vs Stale) and the en-US readout keys (4 vs 5). "A fast sample resets the count" passes with the stubs.
  • GREEN b88e572: 136/136 crate tests pass (with an FFI test for obs_gpu_status_take_log). clippy -D warnings finishes clean for aarch64-apple-darwin and x86_64-pc-windows-msvc (checked on the Finished line). clang-format (ci/local_gate.py --only clang-format, 22.1.3) is clean.
  • Real app: a RelWithDebInfo macOS build of this branch on an M1 Max (33.0.0-beta6-1528-gb88e57200), fresh config: the status bar shows GPU: 99% under a Metal compute load (ioreg: 99), the startup log says GPU acceleration: green, and no GPU usage line is logged (no source is slow). The slow paths are covered by the Tier 1 tests; no real source on this machine is slow.

Checklist

  • Base is master (or the description starts with a Stacked: note)
  • I claimed the issue, or no one else has an open PR for it (the backoff part of obs-gpu-status: Windows GPU utilization through PDH GPU Engine counters #1022, claimed there)
  • Characterization test (if the unit had none), then RED, then GREEN commits
  • User-visible change: its line in docs/features.md is added or updated
  • (Optional) Local gate passed and the pushed head is stamped; otherwise PR CI runs the full suite
  • Warning or flag changes (-W..., ratchets): built with scripting ON (a flag change under cmake/ or build-aux/ runs the full builds) and cross-checked with clang and MSVC (not applicable: no flag changes)
  • Intentional differences from C listed in the parity test header and rust/README.md (ports) (not applicable: new code, no C original)

🤖 Generated with Claude Code

vpacher and others added 2 commits October 17, 2026 19:18
…1022)

Tier 1 tests with a fake clock that fake sources advance by their cost:
the pause after a sample grows with its duration (9 times, 1 s to 30 s)
and recovers; a reading older than 3 intervals is not shown, and the
tooltip says it is late; a source slow (over 2 s) 3 times in a row is
demoted once, with its call times, and the next source answers. With
stubs that keep 1 s, never age a reading and never demote, 6 fail
(5 backoff tests and the en-US readout keys); a fast sample resetting
the count passes with the stubs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t#1022)

next_interval pauses 9 times the sample's duration, 1 s to 30 s, so a
slow source takes at most about a tenth of the obs-gpu-usage thread's
time and a fast sample gives 1 s again. current drops a reading older
than 3 pauses, also while a sample hangs: the label shows "GPU: n/a"
and the tooltip "The GPU reading is late." (new en-US key). The Sampler
times each source call; a source over 2 s three times in a row is not
asked again, and the next source answers.

The thread publishes each sample with its time and pause; the report
checks its age. A demotion becomes one OBS log line ("GPU usage: <source>
is too slow (<times>); not asked again in this session") that the
frontend takes with the new obs_gpu_status_take_log() in Query() and
logs once. 136/136 crate tests pass; clippy -D warnings finishes clean
for macOS and x86_64-pc-windows-msvc; clang-format is clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vpacher
vpacher requested a review from zackees as a code owner October 17, 2026 17:23
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zackees
zackees added this pull request to the merge queue Oct 17, 2026
Merged via the queue into obs-rust:master with commit c3230a7 Oct 17, 2026
24 checks passed
@vpacher
vpacher deleted the feat/1022-usage-backoff branch October 17, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants