|
|
|
|
|
by naasking
1359 days ago
|
|
A userspace thread captures full a stack context, a delimited continuation used in async programming captures only the referenced variables needed for the remaining computation. This is a strict subset of the userspace thread state. For instance: fn f() { var v1 = ..., var v2 = ...; g(v2); }
fn g(v2) { await; /* do something with v2 */ } // await is a context switch
A userspace thread captures v1 and v2, an async computation typically only captures v2. Compound this by all variables on the stack up to the await point, and the difference can be substantial. |
|
Generally stackfull continuations can capture more than stackless, but do not have to. If the context switch in f resumes into g, then only v2 needs to be captured.
If it resumes in an (indirect) caller of f then v1 will have to be captured if still live, but then again, this is not expressible at all with stackless coroutines, without explicitly or implicitly suspending all immediate callers (which would end up capturing v1 anyway).
That is, a stackful continuation equivalent to a stackless one only need to capture the same amount of state.
Also I don't think that defining as delimited the async continuations as opposed to the stackful ones is correct. You can have stackful delimited continuations.