Skip to content

Instantly share code, notes, and snippets.

@kikairoya
Created September 6, 2010 17:49
Show Gist options
  • Save kikairoya/567317 to your computer and use it in GitHub Desktop.
Save kikairoya/567317 to your computer and use it in GitHub Desktop.
#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