A really good library that we use is libco[0], it supports different architectures and mechanisms. We use it extensively on Fluent Bit[1] to manage async IO network operations (epoll + coroutines).<p>- [0] <a href="https://byuu.org/library/libco/" rel="nofollow">https://byuu.org/library/libco/</a><p>- [1] <a href="https://fluentbit.io" rel="nofollow">https://fluentbit.io</a>
A cool library that implements C coroutines, available for both idiomatic C (<a href="http://libdill.org/" rel="nofollow">http://libdill.org/</a>) and in the same style as Go (<a href="http://libmill.org/" rel="nofollow">http://libmill.org/</a>) with line by line translations
I ran with this idea last year and wrote a proof of concept library that wraps libev using using this concept to allow you to write async C code inline. It's about 250 lines of macro abuse and the resulting code looks pretty funky but it ultimately works. I have a simple echo server example here: <a href="https://github.com/jeremycw/zasync/blob/master/echo_server.c" rel="nofollow">https://github.com/jeremycw/zasync/blob/master/echo_server.c</a>
As an OOP dev this kind of horrifies me, even though it works okay (though it's surely not thread-safe?)<p>Nevertheless, even in C, I'd find it conceptually simpler to understand if the functions were written as pure functions, returning a tuple with (c, state) and passing the state back into the caller. Using non-idiomatic tricks and macros in this way is harder to read and understand.
And here is my C++ version of Simon's idea, C++ generators in 10 lines header file:<p><a href="https://www.codeproject.com/Tips/29524/Generators-in-C" rel="nofollow">https://www.codeproject.com/Tips/29524/Generators-in-C</a>
We tried to implement coroutines based on the CoroutineTS here: <a href="https://github.com/LoopPerfect/conduit" rel="nofollow">https://github.com/LoopPerfect/conduit</a><p>CoroutineTS uses coroutines that are implemented on the LLVM-IR level, as a result they get optimized away in many cases.<p>Unfortunately the CoroutineTS has also some design flaws around allocations and ownership
Has anyone used these to write interrupt service routines? Seems like there's an opportunity here. You can take your existing synchronous code and not have to rewrite it into something like continuation-passing style. This is a source of a lot of bugs.
Isn't this just an application of a protothread[1]?<p>There are implementations that use the GCC goto and label pointer, which then avoid the need for a switch statement.<p>[1] <a href="http://dunkels.com/adam/pt/" rel="nofollow">http://dunkels.com/adam/pt/</a>
What's the purpose of this code in the original decompressor? Assuming c is an uchar, aren't EOF and 0xFF equal?<p><pre><code> if (c == 0xFF) {
len = getchar();
c = getchar();
while (len--)
emit(c);
}</code></pre>
I guess one of the applications of Coroutines could be WebAssembly. When you run WebAssembly on a website which needs 100% of the CPU for more than a few ms, you have to use the "setTimeout(fn, 0)" trick to prevent the "this website stopped responding" message. That means you have to store the current state at some point and continue in the function fn (after waiting 0 ms). Languages which support coroutines out of the box would help a lot here.
That page uses very simple HTML. Just paragraphs of text divided into sections with headings. Some code examples laid out side-by-side with a table. Tiny stylesheet. No JS. Loads quickly, easy to read. Warms the cockles of my heart.