Repository navigation
fix: park contended area locks without losing wakeups - #13
Merged
Merged
Conversation
PluginsKers
force-pushed
the
fix/area-lock-contention
branch
from
October 19, 2026 05:36
bc9d644 to
0528d66
Compare
R00tB33rMan
approved these changes
Oct 19, 2026
R00tB33rMan
left a comment
There was a problem hiding this comment.
Can confirm that this patch does in fact resolve what it claims. Tried against squaremap, where it derives from
R00tB33rMan
added a commit
to MagnoliaLLC/Canvas
that referenced
this pull request
Oct 19, 2026
concurrentutil's ReentrantAreaLock stopped waiting in the multi-section lock when it moved to Notifier, so a thread blocked on an area spins until the area frees. A virtual thread holding a section can park, and once spinners hold every carrier it never resumes: the region threads and chunk workers wanting the same sections stall for good. Wait on the holder's notifier after a failed grab, and retire a rolled-back node instead of reusing it, since a contender may start waiting on it after the notification. From Tuinity/LeafPile#13 by PluginsKers; drop this once a LeafPile release carries it.
Contributor
Author
Thanks for confirming the fix with squaremap |
Euphillya
added a commit
to Fidorial/Fidorial
that referenced
this pull request
Oct 20, 2026
Member
|
I noticed that another issue with the acquire logic is that the break logic was incorrectly done, it incorrectly only broke out of the coordinate x loop - allowing it to acquire more nodes even when contended. I also don't think that the node needs to be created again, the node can be re-used by simply re-blocking it before acquiring more nodes (after waiting for a notification from the contended node). |
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.
The multi-section
ReentrantAreaLock.lock(fromX, fromY, toX, toY)overload rolls back a conflicting acquisition and immediately retries, repeatedly updating the concurrent hash table while the owner is still holding the area. Wait on the conflicting node's notifier after rolling back the partial acquisition, matching the single-section path.Permanently notify and retire each partially acquired node before retrying. A contender can observe that node before rollback and start waiting afterwards; resetting its notifier with
notifyThreadsAndBlock()can miss the notification and leave overlapping acquisitions waiting indefinitely. A fresh node keeps notifications associated with their original acquisition attempt.This path appeared during a Folia profile using concurrentutil 1.2.4: one roughly 862 ms stall had 22 region threads waiting in
ThreadedTicketLevelPropagator$UpdateQueue.await, while 435 of 438 execution samples from the other 22 region threads were inReentrantAreaLock.lockand the concurrent table'sputIfAbsentpath. The same retry loop is present on master.