セミコルーチンの実装(x86 only)
手っ取り早く、手ぬきで実装するとこんな感じになります。
他のマシンで実行したい場合は、jmp_bufの中身をよく観察して、適切なインデックスに突っ込めば、大抵OKです。
#include <stdio.h> #include <stdlib.h> #include <setjmp.h> typedef struct co { void (*proc)(void); jmp_buf jb; } co_t; static jmp_buf org; static co_t *cur = NULL; static void *del = NULL; static void co_run(void) { (*cur->proc)(); del = cur; longjmp(org, 1); } static void * co_create(void (*proc)(void), size_t size) { co_t *co = malloc(size + sizeof(co_t)); setjmp(co->jb); co->jb[0] = (typeof(co->jb[0])) co_run; co->jb[2] = (typeof(co->jb[0])) (char *)(co + 1) + size; co->proc = proc; cur = co; return co; } static void co_suspend(void) { if (setjmp(cur->jb) == 0) longjmp(org, 1); } static int co_resume(void *obj) { co_t *co = (co_t *)obj; if (setjmp(org) == 0) { longjmp(co->jb, 1); } else if (del) { free(del); del = NULL; return 0; } return 1; } static void co(void) { int i; for (i = 0; i < 20; i++) { printf("%d\n", i); co_suspend(); } } int main(int argc, char **argv) { void *obj; obj = co_create(co, 8000); while (co_resume(obj)) ; return EXIT_SUCCESS; }