daemon: hand the parse lock off so a flood cannot starve pull answers #376
No reviewers
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis!376
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/375-parse-lock-starvation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #375.
Problem
Under a sustained flood, the Linux window stopped repainting until the output stopped. The PTY parse thread and the
session task share
ParseCore.std::sync::Mutexon Linux never hands the lock to a waiter: the parse thread took itback each time it released it, so the session task could not reliably acquire it to answer a frame pull. Under pull
pacing, an unanswered pull means the window never gets a cycle, never paints, and never pulls again.
Change
ParseCoreis now behindparking_lot::Mutex, which hands the lock to a waiter on average about every 0.5 ms.The guard is still
!Send, sincesend_guardis not enabled.implementation.mdandpipeline.md("Demand-driven emission") now say that this lock must hand off to waiters.They record the rejected alternatives and a "Revisit if" trigger.
measure_pull_cycles_under_floodis a new#[ignore]d measurement test. It needs a release build. It asserts nocycle count, because an unfair lock does not starve every run.
Evidence
DOOM-fire (10 s, Linux, niri, NVIDIA), same client binary:
std::sync::Mutexparking_lot::MutexHeadless measurement test, release build, 8 runs per lock, cycles in 10 s:
std::sync::Mutex: 1 to 11, plus one outlier at 477.parking_lot::Mutex: 268 to 519.catof 150 MB (ascii, unicode and csi, 2×3 runs per daemon) showed no difference beyond run-to-run noise.just checkpassed. pi (sol) reviewed the design and the code, and both rounds returned PASS. The one non-blockingfinding, a non-atomic counter in the test, is fixed in the second commit.
da99c04ff301228bae60