diff options
author | Ayke van Laethem <[email protected]> | 2019-06-08 16:12:30 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2019-06-12 18:26:52 +0200 |
commit | 8890a0f3c845154d54d1f41a00daf9f626865aa0 (patch) | |
tree | 9363a0c26d98d9bd343649d2977f34f6dd555c8d /src/runtime/chan.go | |
parent | 5be412dabea213d7279c738ea2791fc52bf885fd (diff) | |
download | tinygo-8890a0f3c845154d54d1f41a00daf9f626865aa0.tar.gz tinygo-8890a0f3c845154d54d1f41a00daf9f626865aa0.zip |
compiler,runtime: store channel size in the channel itself
This may have a small effect on code size sometimes, but will simplify
the implementation of the select statement.
Diffstat (limited to 'src/runtime/chan.go')
-rw-r--r-- | src/runtime/chan.go | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/src/runtime/chan.go b/src/runtime/chan.go index 60c690507..d9851df4c 100644 --- a/src/runtime/chan.go +++ b/src/runtime/chan.go @@ -28,8 +28,9 @@ import ( ) type channel struct { - state uint8 - blocked *coroutine + elementSize uint16 // the size of one value in this channel + state uint8 + blocked *coroutine } const ( @@ -45,7 +46,7 @@ func deadlockStub() // complete immediately (there is a goroutine waiting for a value), it sends the // value and re-activates both goroutines. If not, it sets itself as waiting on // a value. -func chanSend(sender *coroutine, ch *channel, value unsafe.Pointer, size uintptr) { +func chanSend(sender *coroutine, ch *channel, value unsafe.Pointer) { if ch == nil { // A nil channel blocks forever. Do not scheduler this goroutine again. return @@ -58,7 +59,7 @@ func chanSend(sender *coroutine, ch *channel, value unsafe.Pointer, size uintptr case chanStateRecv: receiver := ch.blocked receiverPromise := receiver.promise() - memcpy(receiverPromise.ptr, value, size) + memcpy(receiverPromise.ptr, value, uintptr(ch.elementSize)) receiverPromise.data = 1 // commaOk = true ch.blocked = receiverPromise.next receiverPromise.next = nil @@ -80,7 +81,7 @@ func chanSend(sender *coroutine, ch *channel, value unsafe.Pointer, size uintptr // sender, it receives the value immediately and re-activates both coroutines. // If not, it sets itself as available for receiving. If the channel is closed, // it immediately activates itself with a zero value as the result. -func chanRecv(receiver *coroutine, ch *channel, value unsafe.Pointer, size uintptr) { +func chanRecv(receiver *coroutine, ch *channel, value unsafe.Pointer) { if ch == nil { // A nil channel blocks forever. Do not scheduler this goroutine again. return @@ -89,7 +90,7 @@ func chanRecv(receiver *coroutine, ch *channel, value unsafe.Pointer, size uintp case chanStateSend: sender := ch.blocked senderPromise := sender.promise() - memcpy(value, senderPromise.ptr, size) + memcpy(value, senderPromise.ptr, uintptr(ch.elementSize)) receiver.promise().data = 1 // commaOk = true ch.blocked = senderPromise.next senderPromise.next = nil @@ -103,7 +104,7 @@ func chanRecv(receiver *coroutine, ch *channel, value unsafe.Pointer, size uintp ch.state = chanStateRecv ch.blocked = receiver case chanStateClosed: - memzero(value, size) + memzero(value, uintptr(ch.elementSize)) receiver.promise().data = 0 // commaOk = false activateTask(receiver) case chanStateRecv: @@ -115,7 +116,7 @@ func chanRecv(receiver *coroutine, ch *channel, value unsafe.Pointer, size uintp // chanClose closes the given channel. If this channel has a receiver or is // empty, it closes the channel. Else, it panics. -func chanClose(ch *channel, size uintptr) { +func chanClose(ch *channel) { if ch == nil { // Not allowed by the language spec. runtimePanic("close of nil channel") @@ -133,7 +134,7 @@ func chanClose(ch *channel, size uintptr) { case chanStateRecv: // The receiver must be re-activated with a zero value. receiverPromise := ch.blocked.promise() - memzero(receiverPromise.ptr, size) + memzero(receiverPromise.ptr, uintptr(ch.elementSize)) receiverPromise.data = 0 // commaOk = false activateTask(ch.blocked) ch.state = chanStateClosed |