gpui: Settle benchmark app state between task iterations - #62587
Merged
Conversation
Dropped entities are released only inside an update's effect flush, and releases cascade across flushes. BenchAppContext callers that only pump the executor between iterations therefore saw torn-down state linger in the entity map until some woken task happened to run an update, letting per-iteration state accumulate across a measurement. Add BenchAppContext::settle, which alternates draining queued work with update cycles until the dispatcher is idle, and call it before each batched task iteration's setup so the previous iteration's state is fully released outside the timed interval.
mikayla-maki
approved these changes
Aug 13, 2026
Its only caller is BenchAppContext::settle, and the bench_context module only compiles with the bench feature, so builds without it failed the dead-code lint. Also wait out the timer future's initial poll in the is_idle unit test; it runs on a worker thread and raced the assertion.
HyacinthHaru
pushed a commit
to HyacinthHaru/z3rm
that referenced
this pull request
Aug 16, 2026
…ies#62587) Dropped entities are released only inside an update's effect flush, and releases cascade: one flush drops the entities whose handles are gone, their drops release further handles and can queue foreground work, and a later flush collects those. `BenchAppContext` callers that only pump the executor between iterations therefore saw torn-down state linger in the entity map until some woken task happened to run an update — in a downstream benchmark this looked like a per-iteration leak of the whole app graph (~35 MB per iteration), releasing on an apparently timer-bound schedule. This adds `BenchAppContext::settle`, which alternates draining queued work with GPUI update cycles until the dispatcher reports idle, mirroring the update cadence production gets for free from frames and input events. `bench_batched_task` now settles before each iteration's setup (outside the timed interval), so the previous iteration's state is fully released and cannot accumulate across a measurement. A new `ThreadedDispatcher::is_idle` predicate backs the loop's termination and is covered by a unit test. Release Notes: - N/A (cherry picked from commit 0307288)
playdohface
pushed a commit
to playdohface/zed
that referenced
this pull request
Aug 29, 2026
…ies#62587) Dropped entities are released only inside an update's effect flush, and releases cascade: one flush drops the entities whose handles are gone, their drops release further handles and can queue foreground work, and a later flush collects those. `BenchAppContext` callers that only pump the executor between iterations therefore saw torn-down state linger in the entity map until some woken task happened to run an update — in a downstream benchmark this looked like a per-iteration leak of the whole app graph (~35 MB per iteration), releasing on an apparently timer-bound schedule. This adds `BenchAppContext::settle`, which alternates draining queued work with GPUI update cycles until the dispatcher reports idle, mirroring the update cadence production gets for free from frames and input events. `bench_batched_task` now settles before each iteration's setup (outside the timed interval), so the previous iteration's state is fully released and cannot accumulate across a measurement. A new `ThreadedDispatcher::is_idle` predicate backs the loop's termination and is covered by a unit test. Release Notes: - N/A
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dropped entities are released only inside an update's effect flush, and releases cascade: one flush drops the entities whose handles are gone, their drops release further handles and can queue foreground work, and a later flush collects those.
BenchAppContextcallers that only pump the executor between iterations therefore saw torn-down state linger in the entity map until some woken task happened to run an update — in a downstream benchmark this looked like a per-iteration leak of the whole app graph (~35 MB per iteration), releasing on an apparently timer-bound schedule.This adds
BenchAppContext::settle, which alternates draining queued work with GPUI update cycles until the dispatcher reports idle, mirroring the update cadence production gets for free from frames and input events.bench_batched_tasknow settles before each iteration's setup (outside the timed interval), so the previous iteration's state is fully released and cannot accumulate across a measurement. A newThreadedDispatcher::is_idlepredicate backs the loop's termination and is covered by a unit test.Release Notes: