Skip to content

Instantly share code, notes, and snippets.

@JackyYin
Last active March 30, 2021 09:10
Show Gist options
  • Save JackyYin/c23785bb6150e0d981ef8caf659b1d43 to your computer and use it in GitHub Desktop.
Save JackyYin/c23785bb6150e0d981ef8caf659b1d43 to your computer and use it in GitHub Desktop.
a simple coroutine implementation
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#define COROUTINE_START int r = setjmp(current->context);\
switch (r) {\
case 0:
#define COROUTINE_PREEMPT if (current->iter % 500 == 0) {\
longjmp(m, 1);\
}\
case 1:;
#define COROUTINE_END }\
longjmp(m, 1);
struct Coroutine {
jmp_buf context;
void (*func)();
int started;
int iter;
int id;
};
struct Coroutine* current;
jmp_buf m;
void func()
{
COROUTINE_START;
while (1) {
printf ("function: %s, id: %d, iter: %d \n", __func__, current->id, ++current->iter);
COROUTINE_PREEMPT;
}
COROUTINE_END;
}
#define CO_NUMS 5
int main()
{
struct Coroutine *coroutines = malloc(sizeof(struct Coroutine) * CO_NUMS);
for (int i = 0; i < CO_NUMS; i++) {
coroutines[i].id = i;
coroutines[i].started = 0;
coroutines[i].iter = 0;
coroutines[i].func = func;
}
switch (setjmp(m)) {
case 0:
while (1) {
for (int i = 0; i < CO_NUMS; i++) {
current = &coroutines[i];
if (!current->started) {
current->started = 1;
current->func();
} else {
longjmp(current->context, 1);
}
case 1:;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment