Skip to content

Instantly share code, notes, and snippets.

Created December 9, 2017 19:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/765f189ddd13665256b140ade76d0533 to your computer and use it in GitHub Desktop.
Save anonymous/765f189ddd13665256b140ade76d0533 to your computer and use it in GitHub Desktop.
#include <Windows.h>
#include <stdio.h>
enum {
CORO_IDLE,
CORO_YIELD,
CORO_DONE,
};
typedef struct {
void *caller_context;
void *callee_context;
void *ret;
volatile char state;
} coroutine;
typedef void (WINAPI coro_func)(void *);
void yield(coroutine *c, void *arg)
{
c->state = CORO_YIELD;
c->ret = arg;
SwitchToFiber(c->caller_context);
c->state = CORO_DONE;
}
int next(coroutine *c)
{
SwitchToFiber(c->callee_context);
if (c->state != CORO_DONE) {
return 1;
}
return 0;
}
void call(coroutine *c, coro_func *f, void *arg)
{
c->state = CORO_IDLE;
c->callee_context = CreateFiber(64 * 1024, f, arg);
SwitchToFiber(c->callee_context);
}
void start(coroutine *c)
{
SwitchToFiber(c->caller_context);
}
void finish(coroutine *c)
{
c->state = CORO_DONE;
SwitchToFiber(c->caller_context);
}
struct iter {
coroutine *c;
int max_x, max_y;
};
struct xy_pair {
int x, y;
};
void WINAPI iterate(void *arg)
{
struct iter *it = arg;
struct xy_pair pair;
int x, y;
start(it->c);
for (x = 0; x < it->max_x; x++) {
for (y = 0; y < it->max_y; y++) {
pair.x = x;
pair.y = y;
yield(it->c, &pair);
}
}
finish(it->c);
}
int main(void)
{
coroutine c;
struct iter it = { &c, 2, 2 };
puts("running coroutine test...");
c.caller_context = ConvertThreadToFiber(&it);
call(&c, &iterate, &it);
while (next(it.c)) {
struct xy_pair *pair = it.c->ret;
printf("%d %d\n", pair->x, pair->y);
}
puts("can I reuse coroutines?");
call(&c, &iterate, &it);
while (next(it.c)) {
struct xy_pair *pair = it.c->ret;
printf("%d %d\n", pair->x, pair->y);
}
getchar();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment