/* * Sieve of Eratosthenes * * This test exercises the scheduler's core directly. * * Original version by Gary Lindstrom. */ #include #include #include "scheduler.h" struct filter { struct process super; struct process *higher; struct process *lower; int p; }; int val; static struct process * filter_create(struct scheduler *sched, const char *s, int p_); static void filter_body(struct process *p) { struct filter *self = (struct filter *)p; struct scheduler *sched = p->scheduler; while (val != 0) { /* not shut down yet */ if (val % self->p != 0) { /* val is not a multiple of this filter stage's p */ if (self->higher == NULL) { /* next stage needs to be created */ self->higher = filter_create(sched, "filter", val); } else sched_pass_baton(sched, self->higher); } /* get next val */ sched_pass_baton(sched, self->lower); } /* do shut down */ printf("%d is prime.\n", self->p); if (self->higher != NULL) { sched_pass_baton(sched, self->higher); } sched_pass_baton_and_die(sched, self->lower); } static struct process * filter_create(struct scheduler *sched, const char *s, int p_) { struct filter *self = calloc(1, sizeof(*self)); self->p = p_; self->lower = sched->current; process_init(&self->super, s, sched, filter_body); return &self->super; } static void filter_base_body(struct process *p) { struct filter *self = (struct filter *)p; self->higher = filter_create(p->scheduler, "filter_2", 2); for (int i = 3; i <= 1000; i++) { val = i; sched_pass_baton(p->scheduler, self->higher); } /* signal shut down */ val = 0; sched_pass_baton(p->scheduler, self->higher); } int main() { struct scheduler *sched = sched_create(); struct filter sieve = { .lower = NULL, .higher = NULL }; process_init(&sieve.super, "filter base", sched, filter_base_body); sched_pass_baton(sched, &sieve.super); process_terminate(&sieve.super); }