

Coroutines in C with Arbitrary Arguments - rumcajz
http://250bpm.com/blog:48

======
david-given
That is _majestically_ vile. It took me a while before I figured out how it
was assigning the new coroutine's stack pointer, and then I was filled with
admiration and a little nausea.

I'm not sure if this will work in real life; it looks like it's relying
heavily on C compiler magic to ensure that the stack's laid out the way it
wants. (Plus, allocating stacks with malloc() doesn't work on some
architectures, and I have encountered pthreads implementations that get very
unhappy if you change stacks on them).

But it's still a deeply impressive piece of lateral thinking.

~~~
userbinator
It should be possible to do this without malloc(), by allocating the co-stack
as an array within the current stack. Something like this...

    
    
        char stack[STACK_SIZE];
        int anchor_[unoptimisable_];
        char filler_[(char*)&anchor_ - (char*)(stack + STACK_SIZE)];
        ...
    

(Haven't tested it, but it's basically the same principle. The same caveats
about stack layout and VLAs apply.)

~~~
mtanski
You would also need to align the stack per. target requirements (gcc keyword,
or offset the address). The aliment guarantees for char[] placed on stack are
probably insufficient for many machines.

~~~
userbinator
If none of the variables on the stack are smaller than your desired alignment
size, and the stack starts out aligned (which it should), then it will remain
aligned.

------
amelius
Would it be possible to make a coroutine implementation that allows the stacks
to grow dynamically? (If there are N coroutines, you will need N stacks, so
for large N it does not suffice to have a statically conservatively
preallocated stack for each coroutine).

Also, how is Rust's support for coroutines?

~~~
errordeveloper
I have recently found this: [https://github.com/rustcc/coroutine-
rs](https://github.com/rustcc/coroutine-rs)

~~~
amelius
Interesting, but the documentation does not seem to describe how stacks/memory
management is done.

~~~
keeperofdakeys
From a quick look at the code, it seems to use segmented stacks with memory
mapping. [https://github.com/rustcc/coroutine-
rs/blob/master/src/stack...](https://github.com/rustcc/coroutine-
rs/blob/master/src/stack.rs)

------
aninteger
Semi off topic, but are there examples of coroutine usage in any relatively
popular open source C or C++ code bases? The only thing that comes to mind is
the MAME and MESS code bases (I could be wrong here). We see coroutine
articles on HN from time to time but I've always wondered who or what software
out there are using these types of techniques.

~~~
userbinator
QEMU is another one that I know of:
[http://blog.vmsplice.net/2014/01/coroutines-in-qemu-
basics.h...](http://blog.vmsplice.net/2014/01/coroutines-in-qemu-basics.html)

Coroutines seem like the type of concept that relatively few programmers
understand and use, but when they are used well, it can simplify the code flow
greatly.

~~~
pm215
Speaking as a QEMU developer, I really don't like the coroutine use. They're a
portability mess, they tend to expose bugs in dusty corners of the compiler,
and they can be painful to debug around. I would much rather take a view that
C is simply not a language with coroutines in it, and not try to retrofit them
without explicit support from the compiler and runtime...

