Skip to content

Instantly share code, notes, and snippets.

@gatlin
Last active August 29, 2015 14:07
Show Gist options
  • Save gatlin/ca1e004fb923f187191f to your computer and use it in GitHub Desktop.
Save gatlin/ca1e004fb923f187191f to your computer and use it in GitHub Desktop.
Simple, toy coroutine mechanism in C
/*
* Simple coroutine mechanism in C
*
* Inspired by / stolen from:
*
* http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
*
* I found this very educational and wanted to publish a simple demonstration.
*
* Usage:
*
* $> gcc -o coro_switch coro_switch.c
* $> ./coro_switch
*
* Explanation: A function in C can allocate so-called static values, whose
* values are preserved between calls to the function.
*
* We initialize a static integer `__coro_state` to be 0 and use it as the
* argument to a switch statement. To yield a value `__coro_state` is set to an
* arbitrary but unique value (the source line number, provided by __LINE__)
* and the immediate next statement is a case expecting *precisely* that value.
*
* The next time the function is called, `__coro_state` will be different and
* we will switch directly to immediately after where we yielded.
*
* TODO:
* 1. Make this threadsafe by making all static variables part of some context
* struct.
*/
#include <stdio.h> /* For printf() */
#define coro_start static int __coro_state=0; switch(__coro_state) { case 0:
#define yield(X) do { __coro_state=__LINE__; return X; \
case __LINE__:; } while (0)
#define coro_finish }
int zero_to_nine(void) {
static int i;
coro_start;
for (i = 0; i < 10; i++) {
yield(i);
}
coro_finish;
}
int ten_to_nineteen(void) {
static int i;
coro_start;
for (i = 10; i < 20; i++) {
yield(i);
}
coro_finish;
}
int main(int argc, char **argv) {
int i;
int num_yielded;
for (i = 0; i < 20; i++) {
if (i % 2 == 0) {
num_yielded = zero_to_nine();
}
else {
num_yielded = ten_to_nineteen();
}
printf("Received: %d\n", num_yielded);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment