Compilation :
cc -g -fno-stack-protector -DSIDES -o pl-v11 pl-v11.c schedule.c
/* coroutines */
/* build : cc -fno-stack-protector -o coroutines_std_long coroutines_std_long.c */
#include <stdio.h>
#include <setjmp.h>
typedef struct coroutine { jmp_buf *caller; jmp_buf *called; } *coroutine;
// int stack[10000];
char *jmpval;
int *getsp ()
{
int *a;
a = (int *)&a;
a += 3;
return a;
}
int call_with_stack (int *stack, int (*f)(), int x)
{
int *sp;
sp = getsp();
{
int buf[sp-stack];
return (*f) (x);
}
}
char *start (coroutine cr, char *(*actions) (), char *intro, int *stack)
{
int result;
int *sp;
result = setjmp (*(cr->caller));
if (result == 0)
{
// _SP = (int *)123; _SP = stack; _SP = (int *)456;
sp = getsp();
{
int buf[sp-stack];
return (*actions) (cr, intro);
}
}
else return jmpval;
}
char *cont (coroutine cr, char *param)
{
int result;
result = setjmp (*(cr->caller));
if (result == 0)
{
jmpval = param;
longjmp (*(cr->called), 1);
}
else return jmpval;
}
char *coroutine_actions (coroutine me, char *intro)
{
struct coroutine you[1];
char *answer;
you->caller = me->called;
you->called = me->caller;
printf ("First got %s from Main\n", intro);
answer = cont (you, "Fine Main, and you ?");
printf ("Then got %s from Main\n", answer);
answer = cont (you, "Nice day, isn't it ?");
return "That's all !\n";
}
int main ()
{
jmp_buf my_env, your_env;
struct coroutine cr[1];
char *answer;
#define STACK_SIZE 1000
int stack[STACK_SIZE];
cr->caller = &my_env;
cr->called = &your_env;
answer = start (cr, coroutine_actions, "Hello Coroutine, how are you ?", stack+STACK_SIZE);
printf ("First got %s from Coroutine\n", answer);
answer = cont (cr, "And what else ?");
printf ("Then got %s from Coroutine\n", answer);
}
Running this program gives the following output :
First got Hello Coroutine, how are you ? from Main First got Fine Main, and you ? from Coroutine Then got And what else ? from Main Then got Nice day, isn't it ? from Coroutine