fix: reuse exited mutator slots instead of growing the registry - #811
Merged
Conversation
The cycle collector's mutator registry was push-only: an exited thread's slot was marked MUTATOR_EXITED but never reclaimed, so on the os-thread backend — where every task is a fresh thread — the vec grew for the life of the process under PITH_CYCLE_GC. register_new_slot now resurrects an exited slot (EXITED -> RUNNING CAS under the registry lock) before allocating a new one, so the registry plateaus at the peak number of concurrently live mutators. A resurrected slot has exactly a fresh slot's contract: EXITED means the owning thread's teardown already ran and it can never gate again, and the adopting thread's first gate poll observes any stop already in progress before it mutates — the same reasoning that makes a fresh registration safe mid-rendezvous. This closes the last flag-quality issue from the #216 benchmark. The collector's contract is unchanged and stays as documented: off by default, weak-first is the language's answer to cycles, and the flag plus explicit gc_collect() is the escape hatch. ## what was tested - new unit test exited_mutator_slots_are_reused_not_accumulated: 64 sequential short-lived threads grow the registry by at most 2 slots - full runtime suite 196 passed, 0 failed; the serial world-stop suite (make test-cycle-gc) 23 passed, 0 failed - end-to-end probe: 20k sequential spawn/await tasks under PITH_GREEN=0 PITH_CYCLE_GC=1, peak rss flat at 2.5mb - make run-regressions-only against the rebuilt runtime: 369 passed
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.
Closes the last flag-quality issue from the #216 cycle-collector benchmark (task #231): the mutator registry was push-only — an exited thread's slot was marked
MUTATOR_EXITEDbut never reclaimed — so on the os-thread backend, where every task is a fresh thread, the vec grew for the life of the process underPITH_CYCLE_GC.register_new_slotnow resurrects an exited slot (EXITED → RUNNINGCAS under the registry lock) before allocating a new one, so the registry plateaus at the peak number of concurrently live mutators. A resurrected slot has exactly a fresh slot's contract:EXITEDmeans the owning thread's teardown already ran (it can never gate again), and the adopting thread's first gate poll observes any stop already in progress before it mutates — the same reasoning that makes a fresh registration safe mid-rendezvous.This also settles the sprint's cycle-collector either/or the way #216's measurements already pointed: weak-first stays the loud, documented default (docs/ownership.md has said so since the no-flip decision — cycles leak by default,
weakis the first-class fix, the flag plus explicitgc_collect()is the escape hatch), and this fix makes that escape hatch non-self-defeating on the os-thread backend. #220 (threshold-mode churn) stays open as a documented limitation of a mode the recipe already tells users not to rely on.what was tested
exited_mutator_slots_are_reused_not_accumulated: 64 sequential short-lived threads grow the registry by at most 2 slotsmake test-cycle-gc) 23 passed, 0 failedPITH_GREEN=0 PITH_CYCLE_GC=1, peak RSS flat at 2.5 MBmake run-regressions-onlyagainst the rebuilt runtime: 369 passed, 0 failed