3 ms·
You emphasize that stackfull coroutines could get down to a single allocation, but I'm not sure exactly what you mean. I could trivially get a stackfull corouti
by withoutboats 8y ago
You emphasize that stackfull coroutines could get down to a single allocation, but I'm not sure exactly what you mean. I could trivially get a stackfull coroutine down to a single allocation, the same way that systems thread do it: by allocating a defined stack size and raising a seg fault when you go over it.
The trick that "stackless coroutines" can achieve, and do achieve in Rust, is not just getting a single allocation, but getting a single perfectly sized alloc every time. It is exactly big enough to hold all the data it could ever need to hold, no more no less. You mention we have a lot of annotations, but the annotations that I know of that can achieve that are annotating every yield point so we can compute the stack space we need to store at that point, which is exactly what async/await notation is for.
- gpderetta 8y agoBy single stack frame I mean exactly that: a single perfectly sized (as it is known at compile time) allocation as opposed to a potentially runtime unbounded list of stack frames requuring a full stack (whatever form that mught take). I think that the optimization of converting the unbound stack to a fixed size stack frame can done for stackfull coroutines iff the continuation of the calling coroutine (i.e. the one that was suspended to activate the curren one) never escapes the coroutine function or any non-mutually recursive function called from the coroutine that the compiler can see though (either via inlineing or interprocedural optimization). Interestingly this is similar to the analysis required to completely optimize a way the coroutine stack frame allocation. And because rust type system is good at tracking lifetimes and nested scopes, I think it might be possible to extend it ti guarantee this sort of optimization. Unfortunately this way beyond my pay grade.