Skip to content

requesthandler: Measure GetStats CPU usage per session - #19

Open
rdoupe wants to merge 1 commit into
obs-rust:masterfrom
rdoupe:fix/cpu-usage-per-session
Open

rdoupe wants to merge 1 commit into
obs-rust:masterfrom
rdoupe:fix/cpu-usage-per-session

Conversation

@rdoupe

@rdoupe rdoupe commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Every client shared one os_cpu_usage_info_t (src/obs-websocket.cpp line 64). os_cpu_usage_info_query() moves its last times forward on every call, so a client's GetStats reported the CPU usage since the last GetStats from any client, not since its own. With two clients polling at different rates, the slower one saw only the slice since the faster one's last call: mostly 0, sometimes a whole core's worth. The query also ran without a lock, while requests run in parallel on the thread pool, which is a data race on the shared state. In the Rust obs-util it also means two &mut references to it at once.

Each session now has its own CPU usage state. It starts when the client connects and is queried under a lock, so cpuUsage covers the time since the same client's previous GetStats (or since it connected). Requests without a session (vendor requests) still use the shared state, now also under a lock. The cpuUsage description in the request docs and in docs/generated says so.

Measured end to end: OBS recording a 640x360 scene, client A polling GetStats every 50 ms and client B every 2 s. B's cpuUsage is compared with OBS's own CPU time over B's interval, read from /proc/<pid>/stat:

Build Client B's cpuUsage (actual)
v0.1.0-beta.20261018 AppImage (submodule 0d663ee) 0.00% (5.37), 0.00% (4.81), 6.25% (4.65), 0.00% (4.71), 3.12% (4.59), 0.00% (4.50)
This branch, C libobs lane 4.38% (4.37), 4.34% (4.34), 4.38% (4.37), 4.34% (4.34), 4.35% (4.37), 4.34% (4.34)
This branch, Rust libobs lane 4.34% (4.34), 4.34% (4.34), 4.34% (4.34), 4.31% (4.31), 4.34% (4.34), 4.35% (4.37)

Tested in obs-rust/obs-studio with test_ws_cpu_usage, which sends GetStats through RequestHandler with two sessions. It burns CPU, polls from session a, idles as long, then polls from session b. At 0d663ee, b reports 0.000% against a's 6.250% in both libobs lanes. With this branch, b reports about half of a's usage (3.047% against 6.094%), 5 of 5 runs in each lane. A second case sends GetStats from 8 threads at once, with and without a session.

Refs obs-rust/obs-studio#1346. The obs-rust/obs-studio PR that moves the submodule to this commit carries the regression test and closes the issue.

Every client shared one os_cpu_usage_info_t, and
os_cpu_usage_info_query() moves its last times forward on every call.
A client's GetStats reported the CPU usage since the last GetStats from
any client, not since its own: with two clients polling, each saw only
the slice since the other one's call, often 0. The query also ran
without a lock while requests run in parallel on the thread pool, a
data race on the shared state.

Each session now has its own CPU usage state, started when it connects
and queried under a lock, so cpuUsage covers the time since the same
client's previous GetStats. Requests without a session (vendor
requests) use the shared state, now also under a lock.

Refs obs-rust/obs-studio#1346
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.

1 participant