diff options
author | Ayke van Laethem <[email protected]> | 2019-05-04 21:32:00 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2019-05-05 16:46:50 +0200 |
commit | 9a54ee4241a1ec252368eb7e7576a5b41723beec (patch) | |
tree | 15560a6ed4666a30b0281d4b0888aaff786874ff /src/runtime/scheduler.go | |
parent | 46d5ea8cf6bffd3606d64b7404656a51394b10aa (diff) | |
download | tinygo-9a54ee4241a1ec252368eb7e7576a5b41723beec.tar.gz tinygo-9a54ee4241a1ec252368eb7e7576a5b41723beec.zip |
compiler: allow larger-than-int values to be sent across a channel
Instead of storing the value to send/receive in the coroutine promise,
store only a pointer in the promise. This simplifies the code a lot and
allows larger value sizes to be sent across a channel.
Unfortunately, this new system has a code size impact. For example,
compiling testdata/channel.go for the BBC micro:bit, there is an
increase in code size from 4776 bytes to 4856 bytes. However, the
improved flexibility and simplicity of the code should be worth it. If
this becomes an issue, we can always refactor the code at a later time.
Diffstat (limited to 'src/runtime/scheduler.go')
-rw-r--r-- | src/runtime/scheduler.go | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/src/runtime/scheduler.go b/src/runtime/scheduler.go index 2503e18d5..b4af2360e 100644 --- a/src/runtime/scheduler.go +++ b/src/runtime/scheduler.go @@ -49,13 +49,17 @@ func (t *coroutine) promise() *taskState { func makeGoroutine(*uint8) *uint8 +// Compiler stub to get the current goroutine. Calls to this function are +// removed in the goroutine lowering pass. +func getCoroutine() *coroutine + // State/promise of a task. Internally represented as: // // {i8* next, i1 commaOk, i32/i64 data} type taskState struct { - next *coroutine - commaOk bool // 'comma-ok' flag for channel receive operation - data uint + next *coroutine + ptr unsafe.Pointer + data uint } // Queues used by the scheduler. @@ -107,12 +111,22 @@ func activateTask(task *coroutine) { runqueuePushBack(task) } -func setTaskData(task *coroutine, value unsafe.Pointer) { - task.promise().data = uint(uintptr(value)) +// getTaskPromisePtr is a helper function to set the current .ptr field of a +// coroutine promise. +func setTaskPromisePtr(task *coroutine, value unsafe.Pointer) { + task.promise().ptr = value +} + +// getTaskPromisePtr is a helper function to get the current .ptr field from a +// coroutine promise. +func getTaskPromisePtr(task *coroutine) unsafe.Pointer { + return task.promise().ptr } -func getTaskData(task *coroutine) unsafe.Pointer { - return unsafe.Pointer(uintptr(task.promise().data)) +// getTaskPromiseData is a helper function to get the current .data field of a +// coroutine promise. +func getTaskPromiseData(task *coroutine) uint { + return task.promise().data } // Add this task to the end of the run queue. May also destroy the task if it's |