runtime: wake channel waiters after releasing locks#5513
Open
rdon-key wants to merge 1 commit into
Open
Conversation
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.
Schedule blocked channel senders and receivers only after releasing the channel and select locks.
With the
coresscheduler,scheduleTaskmay allow the woken task to resume immediately on another core. Previously, channel operations could make a waiter runnable while the waking goroutine still held the same channel lock and, for select operations,chanSelectLock.This PR changes
trySendandtryRecvto return the task that should be woken. Their callers schedule that task only after releasing all relevant locks.chanClosenow collects blocked waiters, marks the channel closed, releases the channel lock, and then wakes the collected tasks.Previous ordering
A waiter could immediately resume on another core and access the same channel before the locks were released.
New ordering
Testing
Tested on an RP2040 Pico with:
Blocking multi-state select
c01_multistate_blocking_select_wake_order.go
Details
This test uses a blocking 17-case select and therefore does not use the non-blocking single-state fast path from #5500.
Unmodified
dev:With this change:
Channel close
d02_close_receiver_reentry_stress.go
Details
This test repeatedly wakes blocked receivers by closing their channel. The receivers immediately access the same closed channel again after being woken.
Unmodified
dev:With this change:
Relation to #5500
#5500 adds a fast path for non-blocking single-state selects.
The
c01reproducer uses a blocking multi-state select, so that fast path cannot apply. This PR addresses the waiter wake-up ordering in the common channel runtime path and is independent of the optimization in #5500.