codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
#include <stdio.h> #include <stdlib.h> #include <memory.h> typedef unsigned int uint; typedef unsigned short word; typedef unsigned char byte; #ifdef __GNUC__ #define NOINLINE __attribute__((noinline)) #else #define NOINLINE __declspec(noinline) #endif #include <setjmp.h> //#include "my_setjmp.h" enum{ STKPAD=1<<16, STKSAV=1<<10 }; struct coroutine { volatile uint state; volatile char* stkptrH; volatile char* stkptrL; jmp_buf PointA, PointB; char stack[STKSAV]; coroutine() { state=0; } NOINLINE // necessary for IntelC + my_setjmp.h void yield( int value ) { char curtmp; stkptrL=(&curtmp)-16; // -16 is necessary for MSC if( setjmp(PointB)==0 ) { state = value; memcpy( stack, (char*)stkptrL, stkptrH-stkptrL ); longjmp(PointA,1); } } template <typename T> NOINLINE // necessary for MSC, to avoid allocation of stktmp before setjmp() void call_do_process() { char stktmp[STKPAD]; stkptrH = stktmp; ((T*)this)->do_process(); } template <typename T> uint call( T& child ) { if( setjmp(PointA)==0 ) { if( state ) { memcpy( (char*)stkptrL, stack, stkptrH-stkptrL ); longjmp(PointB,1); } call_do_process<T>(); } return state; } }; struct index : coroutine { void do_process( void ) { uint a=1; while(1) { yield( a ); a++; } } } F1; struct fibonacci : coroutine { void do_process( void ) { uint a=0,b=1; while(1) { yield( b ); b = b + a; a = b - a; } } } F2; int main( int argc, char** argv ) { for( int i=0; i<20; i++ ) { printf( "%i:%i ", F1.call(F1), F2.call(F2) ); } printf( "\n" ); return 0; }
Private
[
?
]
Run code
Submit