I remember blinking a few times the first time someone showed me Duff’s device. It made me ask “is that really legal C”. Simon Tatham’s article Coroutines in C comes very close to provoking the same response. Wacky, wacky code.
I remember blinking a few times the first time someone showed me Duff’s device. It made me ask “is that really legal C”. Simon Tatham’s article Coroutines in C comes very close to provoking the same response. Wacky, wacky code.
Pingback: Flutterby!
Pingback: 逸岚居
Pingback: Coroutines in C
Pingback: 逸岚居
Pingback: 用心感å—这个世界
Yeah. I knew this. In my piece about The Device, I mention something about a similar trick for interrupt-driven state machines
that is too horrible to go into. This is what I was referring to. I never thought it was an adequate general-purpose coroutine implementation because it’s not easy to have multiple simultaneous activations of a coroutine and it’s not possible using this method to have coroutines give up control anywhere but in their top-level routine. A simple assembly-language stack-switching library lets you do both of those.
Aha, I suspected as much. I’ve updated the page to upgrade my suspicion to a certainty.
On the occasions when I need a sub-coroutine (or is it a co-subroutine?) to give up control, I generally do it by fiddling with the semantics of the subroutine’s return value and having the subroutine call look something like “while (subroutine(ctx, params) == NOT_FINISHED_YET) return NOT_FINISHED_YET;”, so that the internal stack structure of the entire co-thread is torn down and rebuilt on each invocation.
I agree it’s not nearly as efficient as doing a proper stack switch in assembly language, but on the other hand it beats having to write the stack switcher separately for every different platform and compiler on which I plan to run my code. Porting is more than enough hassle as it is…
Pingback: Vidar Hokstad's random musings
Pingback: Coroutines in C | ??