Created
September 6, 2010 17:49
-
-
Save kikairoya/567317 to your computer and use it in GitHub Desktop.
This file contains 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 <setjmp.h> | |
#define SET_STACK(stack) asm("movl %0, %%esp": : "r"(stack)) | |
//#define SET_STACK(stack) asm("mov %0, sp" : : "r"(stack)); | |
template <typename FnctrT> | |
struct coroutine { | |
int operator ()() { | |
if (volatile int n = setjmp(jb_outer)) { | |
return n; | |
} else { | |
if (inited) { | |
longjmp(jb_inner, 1); | |
} else { | |
SET_STACK(stack); | |
longjmp(jb_outer, static_cast<FnctrT *>(this)->main()); | |
} | |
} | |
} | |
coroutine(void *st) { | |
stack = st; | |
inited = false; | |
exited = false; | |
} | |
bool exitp() const { return exited; } | |
protected: | |
jmp_buf jb_outer; | |
jmp_buf jb_inner; | |
void *stack; | |
bool inited; | |
bool exited; | |
void exit(volatile int code) { | |
exited = true; | |
setjmp(jb_inner); | |
longjmp(jb_outer, code); | |
} | |
void yield(volatile int n) { | |
inited = true; | |
if (setjmp(jb_inner)) { | |
return; | |
} else { | |
longjmp(jb_outer, n); | |
} | |
} | |
~coroutine(){} | |
}; | |
struct myroutine: coroutine<myroutine> { | |
myroutine(void *stack): coroutine<myroutine>(stack) { } | |
int main() { | |
for (int i=1; i<=9; ++i) { | |
for (int j=1; j<=9; ++j) yield(i*j); | |
} | |
exit(0); | |
} | |
}; | |
#include <stdio.h> | |
unsigned char stack[1024]; | |
int main() { | |
myroutine r(&stack[1020]); | |
while (!r.exitp()) printf("%d\n", r()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment