mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-07 12:33:42 +00:00
compiler/runtime: move the channel blocked list onto the stack
Previously, chansend and chanrecv allocated a heap object before blocking on a channel. This object was used to implement a linked list of goroutines blocked on the channel. The chansend and chanrecv now instead accept a buffer to store this object in as an argument. The compiler now creates a stack allocation for this object and passes it in.
This commit is contained in:
+6
-4
@@ -446,7 +446,7 @@ type chanSelectState struct {
|
||||
// chanSend sends a single value over the channel.
|
||||
// This operation will block unless a value is immediately available.
|
||||
// May panic if the channel is closed.
|
||||
func chanSend(ch *channel, value unsafe.Pointer) {
|
||||
func chanSend(ch *channel, value unsafe.Pointer, blockedlist *channelBlockedList) {
|
||||
if ch.trySend(value) {
|
||||
// value immediately sent
|
||||
chanDebug(ch)
|
||||
@@ -462,10 +462,11 @@ func chanSend(ch *channel, value unsafe.Pointer) {
|
||||
sender := task.Current()
|
||||
ch.state = chanStateSend
|
||||
sender.Ptr = value
|
||||
ch.blocked = &channelBlockedList{
|
||||
*blockedlist = channelBlockedList{
|
||||
next: ch.blocked,
|
||||
t: sender,
|
||||
}
|
||||
ch.blocked = blockedlist
|
||||
chanDebug(ch)
|
||||
task.Pause()
|
||||
sender.Ptr = nil
|
||||
@@ -475,7 +476,7 @@ func chanSend(ch *channel, value unsafe.Pointer) {
|
||||
// It blocks if there is no available value to recieve.
|
||||
// The recieved value is copied into the value pointer.
|
||||
// Returns the comma-ok value.
|
||||
func chanRecv(ch *channel, value unsafe.Pointer) bool {
|
||||
func chanRecv(ch *channel, value unsafe.Pointer, blockedlist *channelBlockedList) bool {
|
||||
if rx, ok := ch.tryRecv(value); rx {
|
||||
// value immediately available
|
||||
chanDebug(ch)
|
||||
@@ -491,10 +492,11 @@ func chanRecv(ch *channel, value unsafe.Pointer) bool {
|
||||
receiver := task.Current()
|
||||
ch.state = chanStateRecv
|
||||
receiver.Ptr, receiver.Data = value, 1
|
||||
ch.blocked = &channelBlockedList{
|
||||
*blockedlist = channelBlockedList{
|
||||
next: ch.blocked,
|
||||
t: receiver,
|
||||
}
|
||||
ch.blocked = blockedlist
|
||||
chanDebug(ch)
|
||||
task.Pause()
|
||||
ok := receiver.Data == 1
|
||||
|
||||
Reference in New Issue
Block a user