@Alogani > Indeed moving a started coroutine can be (is certainly?) unsafe, because it > can contains GC memory, which will be hard to track.
You can't move a started coroutine without preemption. You need the coroutine cooperation, i.e. it should have suspension points where its state it saved and where it returns control to the scheduler. In susual code, async/await and spawn/sync calls are such implicit suspension points. But if you have a long period without such, you may block a runtime. > And because stackful coroutines are long living, there is IMHO a risk of load > unbalancing if they are never moved around threads. Stackful coroutines may be long-living but the task that run on top aren't or people should just use a long-running thread instead of coroutines. > That's the reason I think stackless coroutines are more fit for a M:N > environment. Boost has a fiber pool, Ubisoft has a fiber pool used in games, I've linked fibril which uses a fiber pool has well. It can be done. > Furthermore, is a work-stealing implementation appropriate when there could > be both CPU bound and I/O bound tasks ? I/O tasks are suspended often but are > frequent, whereas CPU bound task is suspended almost never. Yes, see Go scheduler: <https://assets.ctfassets.net/oxjq45e8ilak/48lwQdnyDJr2O64KUsUB5V/5d8343da0119045c4b26eb65a83e786f/100545_516729073_DMITRII_VIUKOV_Go_scheduler_Implementing_language_with_lightweight_concurrency.pdf> > So, a work stealing implementation would starve the event loop if there are > multiple CPU tasks. We could reserve threads for I/O, but that would mean > either useless threads or a computation speed close to a single threaded I/O > dispatcher. That's indeed the main problem that needs to be solved in Weave IO. Though IO threads can also block for a long-time, for example waiting for stdin. A simple way to solve this is that if a thread is the last active one, they create a new one before proceeding with the task. Go does this: <https://github.com/golang/go/blob/master/src/runtime/proc.go>, the scheduler procs are prefixed with runq and globalrunq