#include #include using namespace std; struct process; struct simple_int_channel; struct count_to_three; struct printer; struct count_to_n; typedef int (*process_func)(process *p); struct process { process_func f; int pc; }; struct simple_int_channel { int value; process *waiting; }; struct count_to_three { process p; simple_int_channel *out; }; struct printer { process p; simple_int_channel *in; }; struct count_to_n { process p; simple_int_channel *out; int n; int c; }; inline void start(process *p); inline int resume(process *p); int count_to_three_f(process *p); int printer_f(process *p); int count_to_n_f(process *p); void run(void); void step(void); int main(void); deque q; inline void start(process *p) { q.push_back(p); } inline int resume(process *p) { int rv = (*p->f)(p); if(rv) { p->pc = rv; } return rv; } int count_to_three_f(process *p) { count_to_three *d = (count_to_three *)p; switch(p->pc) { case 0: if(!d->out->waiting) { p->pc = 1; d->out->waiting = p; return 0; } case 1: d->out->value = 1; start(d->out->waiting); d->out->waiting = NULL; if(!d->out->waiting) { p->pc = 2; d->out->waiting = p; return 0; } case 2: d->out->value = 2; start(d->out->waiting); d->out->waiting = NULL; if(!d->out->waiting) { p->pc = 3; d->out->waiting = p; return 0; } case 3: d->out->value = 3; start(d->out->waiting); d->out->waiting = NULL; } return 0; } int printer_f(process *p) { printer *d = (printer *)p; switch(p->pc) { case 0: while(1) { if(d->in->waiting) { start(d->in->waiting); } p->pc = 1; d->in->waiting = p; return 0; case 1: printf("%d\n", d->in->value); } } return 0; } int count_to_n_f(process *p) { count_to_n *d = (count_to_n *)p; switch(p->pc) { case 0: d->c = 1; while(d->c <= d->n) { if(!d->out->waiting) { p->pc = 1; d->out->waiting = p; return 0; } case 1: d->out->value = d->c; start(d->out->waiting); d->out->waiting = NULL; ++ (d->c); } } return 0; } void run(void) { while(!q.empty()) { step(); } } void step(void) { process *p = q.front(); q.pop_front(); if(resume(p)) { q.push_back(p); } } int main(void) { simple_int_channel ch ; ch.waiting = NULL; count_to_three c3 = { { count_to_three_f, 0 }, &ch }; printer pr = { { printer_f, 0 }, &ch }; start(&c3.p); start(&pr.p); run(); count_to_n cn = { { count_to_n_f, 0 }, &ch, 10 }; start(&cn.p); run(); return 0; }