[ create a new paste ] login | about

Link: http://codepad.org/5rRIg5zT    [ raw code | output | fork ]

C++, pasted on Dec 4:
#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>

struct coroutine {

  enum{ STKPAD=1<<16, STKSAV=1<<10 };

  volatile uint state;
  volatile char* stkptrH;
  volatile char* stkptrL;
  jmp_buf PointA, PointB;
  char stack[STKSAV];

  coroutine() { state=0; }

  virtual void do_process( void )=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); 
    }
  }

  NOINLINE // necessary for MSC, to avoid allocation of stktmp before setjmp()
  void call_do_process() {
    char stktmp[STKPAD]; stkptrH = stktmp;
    do_process();
  }

  uint call( void ) {
    if( setjmp(PointA)==0 ) {
      if( state ) {
        memcpy( (char*)stkptrL, stack, stkptrH-stkptrL );
        longjmp(PointB,1); 
      }
      call_do_process();
    }
    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(), F2.call() );
  } printf( "\n" );

  return 0;
}


Output:
1
1:1 2:1 3:2 4:3 5:5 6:8 7:13 8:21 9:34 10:55 11:89 12:144 13:233 14:377 15:610 16:987 17:1597 18:2584 19:4181 20:6765 


Create a new paste based on this one


Comments: