Hi all, after reading some post that reminds me of Duff device.
I wrote some helper function+macro to make coroutine in C by borrowing some ideas from Coroutines in C and rob pike Newsqueak
This is for sure not complete yet.
Still need improvement....
Feel free to give suggestion and idea/code/...
Code:
typedef struct {
	int pc;
	char stack[];
} context;

void new_context(context **c,void *local_context,size_t size)
{
	if(*c) {
		memcpy(local_context,(*c)->stack,size);
		return ;
	}
	context *p;
	
	p = malloc(sizeof *p + size);
	memset(p,0,sizeof *p + size);
	p->pc = 0;
	memcpy(p->stack,local_context,size);
	
	*c = p;

}
void c_return(context *c,void *local_c,size_t size)
{

	memcpy(c->stack,local_c,size);

}


#define begin_context		struct { 
#define end_context			} Context
#define coroutine_init(c)		new_context(c,&Context,sizeof(Context) )
#define coroutine_start(c)		switch((*c)->pc) { case 0: 
#define coroutine_return(c,v)		do { (*c)->pc=__LINE__;  c_return(*c,&Context,sizeof(Context) ); return (v); case __LINE__:; } while(0)
#define coroutine_finish(c,v)		}	free(*c); *c = 0; return (v)
Usage:
Code:
int ascending(context **c)
{
	begin_context
		int i;

	end_context;
	
	coroutine_init(c);
	
	coroutine_start(c);
	
	for(Context.i = 0; ; Context.i++) {

		coroutine_return(c,Context.i);
	}
	
	coroutine_finish(c,-1);
}

int series(context **c)
{
	begin_context
		context *as_c;
		int n;
	end_context;
	coroutine_init(c);
	
	
	coroutine_start(c);
		Context.as_c = NULL;
		while(1) {
			int val = ascending(&Context.as_c);
			Context.n = val * val;
			coroutine_return(c,Context.n);
		}
	coroutine_finish(c,-1);
}



int sum_series(context **c)
{
	begin_context
		context *series_c;
		int sum;
	end_context;
	
	coroutine_init(c);
	coroutine_start(c);
		Context.series_c = NULL;
		Context.sum = 0;
		while(1){
			int val = series(&Context.series_c);
			Context.sum += val;
			coroutine_return(c,Context.sum);
		}
	coroutine_finish(c,-1);
}



int main(void)
{

	context *c = 0;
	context *c1 = 0;
	context *c2 = 0;
	int i;
	printf("x  \t  x * x  \t  sig(xi) \n");
	for(i=0;i<10;i++) {
		printf("%d \t %d \t %d\n",ascending(&c1),series(&c),sum_series(&c2));
	}

return 0;
}
Output:

Code:
x  	  x * x  	  sig(xi) 
0 	 0 	 0
1 	 1 	 1
2 	 4 	 5
3 	 9 	 14
4 	 16 	 30
5 	 25 	 55
6 	 36 	 91
7 	 49 	 140
8 	 64 	 204
9 	 81 	 285