fix(vcores): the core-wait escape at 2 s, not 250 ms (#1929) #2127

Merged
NotRexed merged 2 commits from fix/vcore-escape-2s into main 2026-11-11 04:40:13 +00:00
NotRexed commented 2026-11-11 04:14:33 +00:00 (Migrated from github.com)

Part of #1929. When a guest thread has waited too long for a virtual core, the scheduler lets it run without one (an "escape"). The holder is still running on that core, so the two threads share per-core state. That race is the risk #1929 is about.

On current main (after 9f42700e, "WaitAny's scan makes no vcore checkpoint while it holds mw_lock"), the waits that reach 250 ms end by themselves within about 1.2 s. The 250 ms escape fires anyway, 6-8 times per run. This raises both defaults (HOS_VCORE_ESCAPE_US, HOS_VCORE_ESCAPE_EQ_US) to 2 s. The escape stays as a deadlock breaker, and either value can still be set from the environment.

A/B, measured on current main: 25-minute route (Kokiri Forest, Hyrule Field, Kakariko), RTX 4060 Ti, docked 1440p, two rounds each, alternating.

run escapes longest core wait p99 p99.9 max frame crashes
250 ms, round 1 8 251 ms 28.9 ms 81.1 ms 641 ms 0
2 s, round 1 0 909 ms 28.6 ms 81.4 ms 619 ms 0
250 ms, round 2 6 252 ms 27.5 ms 77.4 ms 584 ms 0
2 s, round 2 0 1162 ms 27.4 ms 77.3 ms 573 ms 0

The longer waits do not show up as longer frames: the worst frame is the same or shorter at 2 s. An earlier A/B with a 5 s escape, before 9f42700e, did produce 5 s frames. Those long holds are gone on current main.

🤖 Generated with Claude Code

Part of #1929. When a guest thread has waited too long for a virtual core, the scheduler lets it run without one (an "escape"). The holder is still running on that core, so the two threads share per-core state. That race is the risk #1929 is about. On current main (after 9f42700e, "WaitAny's scan makes no vcore checkpoint while it holds mw_lock"), the waits that reach 250 ms end by themselves within about 1.2 s. The 250 ms escape fires anyway, 6-8 times per run. This raises both defaults (`HOS_VCORE_ESCAPE_US`, `HOS_VCORE_ESCAPE_EQ_US`) to 2 s. The escape stays as a deadlock breaker, and either value can still be set from the environment. **A/B, measured on current main:** 25-minute route (Kokiri Forest, Hyrule Field, Kakariko), RTX 4060 Ti, docked 1440p, two rounds each, alternating. | run | escapes | longest core wait | p99 | p99.9 | max frame | crashes | |---|---|---|---|---|---|---| | 250 ms, round 1 | 8 | 251 ms | 28.9 ms | 81.1 ms | 641 ms | 0 | | 2 s, round 1 | **0** | 909 ms | 28.6 ms | 81.4 ms | 619 ms | 0 | | 250 ms, round 2 | 6 | 252 ms | 27.5 ms | 77.4 ms | 584 ms | 0 | | 2 s, round 2 | **0** | 1162 ms | 27.4 ms | 77.3 ms | 573 ms | 0 | The longer waits do not show up as longer frames: the worst frame is the same or shorter at 2 s. An earlier A/B with a 5 s escape, before 9f42700e, did produce 5 s frames. Those long holds are gone on current main. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
mooki000 commented 2026-11-11 14:08:16 +00:00 (Migrated from github.com)

Measured after the merge on Linux (Arch, RTX 4090, NVIDIA 615.78.08, headless): the issue's start (fresh profile, Start
about 95 s into the title, 165 s per run), the build of this pull request's commit with HOS_VCORE_ESCAPE_US/_EQ_US
set to 250000 (the old default) against the same build as merged, three runs each, interleaved in one sitting. Not
exclusive: load average 4-8 at the start of four runs, 20 and 66 at the other two.

escapes per run longest core wait crashes after Start: fps / 1% low / worst frame
250 ms 7, 8, 2 251, 251, 251 ms 0 59.9 / 37.1 / 104 ms
2 s 0, 0, 0 983, 947, 1162 ms 0 59.8 / 33.2 / 76 ms

The same as on your route: no escapes at 2 s, the longest waits end within 1.2 s, frame times the same within the spread.
At a first start (the button-prompt textures written again; 30 s, three runs each) it was 1, 6 and 1 escapes at 250 ms
and none at 2 s. Where the waits over 250 ms came from on this machine, and two host waits that keep a core, are in my
comment on #1929.

Measured after the merge on Linux (Arch, RTX 4090, NVIDIA 615.78.08, headless): the issue's start (fresh profile, Start about 95 s into the title, 165 s per run), the build of this pull request's commit with `HOS_VCORE_ESCAPE_US`/`_EQ_US` set to 250000 (the old default) against the same build as merged, three runs each, interleaved in one sitting. Not exclusive: load average 4-8 at the start of four runs, 20 and 66 at the other two. | | escapes per run | longest core wait | crashes | after Start: fps / 1% low / worst frame | |---|---|---|---|---| | 250 ms | 7, 8, 2 | 251, 251, 251 ms | 0 | 59.9 / 37.1 / 104 ms | | 2 s | 0, 0, 0 | 983, 947, 1162 ms | 0 | 59.8 / 33.2 / 76 ms | The same as on your route: no escapes at 2 s, the longest waits end within 1.2 s, frame times the same within the spread. At a first start (the button-prompt textures written again; 30 s, three runs each) it was 1, 6 and 1 escapes at 250 ms and none at 2 s. Where the waits over 250 ms came from on this machine, and two host waits that keep a core, are in my comment on #1929.
Commenting is not possible because the repository is archived.
No description provided.