Last active
January 2, 2016 08:49
-
-
Save arms22/8278912 to your computer and use it in GitHub Desktop.
C言語用コルーチン。マイクロスレッドとかファイバーとかそんなやつ。Arduino用に極力シンプルに実装。gccのラベル拡張使ってるからgcc専用。実行結果:fiber test0 0 1 1 1 1 2 2 2 3 3 4 4 5 9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef FIBER_H | |
#define FIBER_H | |
#define FIBER_NEST_ENABLE 1 | |
typedef void* fiber_t; | |
#define FIBER_INIT { ((void*)0) } | |
#define FIBER_LINE2(x) FIBER_LINE_ ## x | |
#define FIBER_LINE(x) FIBER_LINE2(x) | |
#if FIBER_NEST_ENABLE | |
static fiber_t __fb_softstack[8]; | |
static fiber_t* __fb_sp = __fb_softstack; | |
#define __fb_return__ (*(__fb_sp - 1)) | |
#define __fb_current__ (*(__fb_sp - 0)) | |
#define fiber_run(fb) \ | |
for(*__fb_sp++ = &&FIBER_LINE(__LINE__), *__fb_sp = (fb) \ | |
;(fb) != &&FIBER_LINE(__LINE__) \ | |
;(fb) = &&FIBER_LINE(__LINE__), __fb_sp--) \ | |
if(__fb_current__) { \ | |
goto *__fb_current__; \ | |
FIBER_LINE(__LINE__): \ | |
(fb) = __fb_current__; \ | |
__fb_sp--; \ | |
break; \ | |
} \ | |
else | |
#else | |
static fiber_t __fb_current__; | |
static fiber_t __fb_return__; | |
#define fiber_run(fb) \ | |
__fb_current__ = (fb); \ | |
(fb) = __fb_return__ = &&FIBER_LINE(__LINE__); \ | |
if(__fb_current__) { \ | |
goto *__fb_current__; \ | |
FIBER_LINE(__LINE__): \ | |
(fb) = __fb_current__; \ | |
} \ | |
else | |
#endif | |
#define yield() \ | |
do { \ | |
__fb_current__ = &&FIBER_LINE(__LINE__); \ | |
goto *__fb_return__; \ | |
FIBER_LINE(__LINE__): \ | |
; \ | |
} while(0); | |
#define wait_until(cond) \ | |
while(!(cond)) { \ | |
yield(); \ | |
} | |
#define fiber_init(fb) \ | |
do { \ | |
(fb) = FIBER_INIT; \ | |
} while (0) | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "fiber.h" | |
fiber_t fb0 = FIBER_INIT; | |
fiber_t fb1 = FIBER_INIT; | |
fiber_t fb2 = FIBER_INIT; | |
fiber_t fb3 = FIBER_INIT; | |
fiber_t fb4 = FIBER_INIT; | |
fiber_t fb5 = FIBER_INIT; | |
fiber_t fb6 = FIBER_INIT; | |
int main(int argc, char *argv[]) | |
{ | |
int c = 0; | |
do { | |
fiber_run(fb0) { | |
printf("fiber test\n"); | |
} | |
fiber_run(fb1) { | |
printf("%c\n", c + '0'); | |
yield(); | |
} | |
fiber_run(fb2) { | |
yield(); | |
printf(" %c\n", c+'0'); | |
} | |
fiber_run(fb3) { | |
yield(); | |
printf(" %c\n", c+'0'); | |
yield(); | |
printf(" %c\n", c+'0'); | |
yield(); | |
} | |
fiber_run(fb4) { | |
do { | |
printf(" %c\n", c+'0'); | |
yield(); | |
} while(c < 5); | |
} | |
#if FIBER_NEST_ENABLE | |
fiber_run(fb5) { | |
do { | |
yield(); | |
printf(" %c\n", c+'0'); | |
fiber_run(fb6) { | |
wait_until(c == 9); | |
printf(" %c\n", c+'0'); | |
} | |
} while(1); | |
} | |
#else | |
fiber_run(fb5) { | |
do { | |
yield(); | |
printf(" %c\n", c+'0'); | |
} while(c < 5); | |
} | |
fiber_run(fb6) { | |
wait_until(c == 9); | |
printf(" %c\n", c+'0'); | |
} | |
#endif | |
} while(c++ < 10); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment