zlacker

[parent] [thread] 2 comments
1. ambonv+(OP)[view] [source] 2026-02-03 21:30:50
I am not familiar with Mojo, so I do not know.

Compared to the coroutine implementations I do know, none of them quite met what I as looking for. The «trampoline» has been mentioned. I also needed a calling convention that fit the higher-level process model with a self pointer and a context, and a signal return value from each context switch. It also has to be thread safe to survive the pthreads. Not very difficult to do, but needs to be designed in from the beginning.

Same thing with random number generators. It will not work very well to keep state between calls in a static local variable or some global construction, needs to be kept thread local somewhere. Not difficult, but needs to be there from the start both for the basic generator and for the distributions on top of it.

Quite a bit more here: https://cimba.readthedocs.io/en/latest/background.html#

replies(1): >>anfilt+kE3
2. anfilt+kE3[view] [source] 2026-02-04 20:54:04
>>ambonv+(OP)
Speaking of Coroutine libraries, I wrote this stackful one a few years ago: https://github.com/Keith-Cancel/Bunki

It has the ability to add context to each coroutine.

replies(1): >>ambonv+bj7
◧◩
3. ambonv+bj7[view] [source] [discussion] 2026-02-05 21:33:16
>>anfilt+kE3
Yes, I did actually look at Bunki as well before building this. Liked the imagery. :)

What did not quite fit for my purpose was having the asymmetric coroutines as the fundamental layer, meaning that the dispatcher also is tied to that layer. Building the next level dispatcher on top of that is probably possible, but seemed a bit complicated.

I instead started with symmetric coroutines as the fundamental building block and built the dispatcher at the next (process) layer where it can deal with the event queue to determine who goes next. The process level resume() call is always made from some event executed by the dispatcher on the main stack, making the processes asymmetric coroutines even if the lowest level coroutines are symmetric with transfer() calls.

Making asymmetric coroutines from symmetric ones is easy, just yield(void) { transfer(parent); } and resume(target) { transfer(target); } in slightly abbreviated code, while going the other way around requires an extra context switch via the dispatcher on the way there.

[go to top]