Thank you for this article. I also really like coroutines but how they manifest in codebases can sometimes be hard to follow (async Rust, async Python).
I have played around with protothreads and use generators in Python but Marce Coll has an amazing blog post about coroutines in assembly, which is down right now.
If you save the RSP register somewhere and restore it later, you can switch stacks.
I'm currently working on an architecture to unify coroutines and threads. I am taking inspiration from "Bulk synchronous parallel programming" in that I am using barriers. I hope to apply structured concurrency to it too. A coroutine can be remote in a thread or in a different current thread and parallel.
The previous coroutine state needs to be recovered onto the stack and registers for the coroutine to function correctly from its previous point. Temporal memoizes API calls and replays the same function deterministically, so it doesn't attempt to jump into half way into a function, that a coroutine could do.
Memory management for stacks has tricky questions about how much address space to reserve for each stack and how to ensure there are guard pages to catch stack overflows.
I have played around with protothreads and use generators in Python but Marce Coll has an amazing blog post about coroutines in assembly, which is down right now.
If you save the RSP register somewhere and restore it later, you can switch stacks.
I'm currently working on an architecture to unify coroutines and threads. I am taking inspiration from "Bulk synchronous parallel programming" in that I am using barriers. I hope to apply structured concurrency to it too. A coroutine can be remote in a thread or in a different current thread and parallel.
I am curious about stackless python.