-
Notifications
You must be signed in to change notification settings - Fork 997
Refactor Tasks #828
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor Tasks #828
Conversation
19b7638 to
25de588
Compare
|
This PR attempts to create a clean API for interacting with tasks for implementing low level concurrency in the standard library. In the process, coroutine lowering was overhauled and moved into the Main changes:
|
|
I tried to merge this locally into current |
|
There is probably another silent merge conflict. I guess I can re-fix that in a bit. |
3c0a5a9 to
d5c997a
Compare
|
Fixed. |
|
So far I have done testing with the following programs/boards:
All of the above programs worked exactly as expected. 👍 |
9dabba2 to
95ada00
Compare
aykevl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the high-level overview! It definitely sounds like a good improvement.
I still need to take a deep dive in the code, but here are some superficial remarks while scrolling through it.
aykevl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The IR generator now emits the same IR for starting a goroutine on all schedulers. This eliminates some logic in the compiler and means that we do not need to worry about as many variations in the IR.
Are you referring to internal/task.start? The IR for it looks a lot simpler now. Apparently internal/task.start creates/starts the new coroutine instead of starting it wherever that call appears.
08648f3 to
48c4fac
Compare
Yes, that is what I was referring to. |
aykevl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've looked mainly at the tasks scheduler. Hopefully I can look at the coroutines scheduler soon. So far, it looks good but I have a few nits here and there to make the code easier to understand and read.
One thing I'm missing is some sort of high level overview of the new/improved/refactored coroutines scheduler. It has changed in a few ways, but I'm finding it hard to see how exactly (and thus how it works now). There used to be one in src/runtime/scheduler_coroutines.go but it is now gone. I'm not sure what the best place would be, perhaps src/internal/task/task_coroutine.go? Some questions it should probably answer: how are parameters passed to newly started goroutines? How does call/return work? What happens when you do a blocking operation (such as time.Sleep)? Such documentation is super valuable not just to me, but also to people new to the project that want to improve the scheduler.
|
So would it be correct to say that this PR needs some docs, and then can be merged? In either case, I suggest adding a separate page for "Task Scheduler" in https://github.com/tinygo-org/tinygo-site/tree/master/content/compiler-internals |
|
@deadprogram I added the docs requested in @aykevl 's comment. I could add some additional documentation later. |
aykevl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have reviewed all the code now. It looks very clean, just a few nits here and there.
In either case, I suggest adding a separate page for "Task Scheduler" in https://github.com/tinygo-org/tinygo-site/tree/master/content/compiler-internals
That might be useful but at the same time I'd rather avoid duplicating documentation. You could perhaps put a link to https://github.com/tinygo-org/tinygo/tree/master/transform/coroutines.go where the canonical documentation is kept.
| } | ||
|
|
||
| // supplyTaskOperands fills in the task operands of async calls. | ||
| func (c *coroutineLoweringPass) supplyTaskOperands() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could eventually be done by the compiler directly. It would avoid the issue of possibly optimized out parameters etc. But not in this PR.
52f76ce to
b049521
Compare
|
I fixed those issues and rebased on dev. |
aykevl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked code size and in nearly all cases (including WebAssembly!) programs get bigger. Usually not enormously, but still significantly (typically 300-1000 bytes). Do you know why this is the case?
A few examples:
- ./testdata/alias.go went from 1204 to 2276 bytes on microbit.
- ./testdata/interface.go stayed at 14760 bytes on microbit, as one of very few tests that stays the same size.
- ./testdata/stdlib.go went from 72896 to 74404 bytes on WebAssembly.
It looks like something doesn't get optimized out properly when not using the scheduler, because in very small tests (testdata/zeroalloc.go) the size increase is pretty big (+1148 bytes).
I used the following script to compare a whole lot of code at the same time:
#!/bin/sh
for t in testdata/*.go; do echo $t; tinygo build -o test.elf -no-debug -size=short $t; done
for t in testdata/*.go; do echo $t; tinygo build -o wasm.wasm -no-debug $t; /bin/ls -l wasm.wasm; done
for t in testdata/*.go; do echo $t; tinygo build -o test.elf -target microbit -no-debug -size=short $t; done
make smoketest
| c.builder.SetInsertPointBefore(user) | ||
| raw := user.Operand(1) | ||
| if !raw.IsAUndefValue().IsNil() || raw.IsNull() { | ||
| return errors.New("undefined task") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one can also be changed to errorAt.
| @@ -0,0 +1,83 @@ | |||
| // +build scheduler.tasks, cortexm | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I discovered an issue here while playing around with -scheduler=none: this file is still included. Removing the extra space (to make it scheduler.tasks,cortexm) fixes the issue.
|
I tested #895 rebased on top of this branch and the size is very similar to what it is now when I add |
|
Merged! 🎉 |
|
@jaddr2line thank you very much for your incredible work on this contribution, and thanks @aykevl for getting it reviewed, this was a big one! |
No description provided.