/* * Car Wash Example of Mitrani pp. 12-15 * I. Mitrani, Simulation techniques for discrete event systems * original version by G. Lindstrom */ #include #include #include #include "scheduler.h" #include "rnd_dist.h" static long SEED = 42; static int T; // simulation shut down time static int N; // capacity of car park static int car_park_contents = 0; // cars currently in car park struct car_wash { struct process super; // base class struct urnd gen_period; int fast_wash, slow_wash; bool busy; }; static struct car_wash *benz; static void car_wash_body(struct process *p) { struct car_wash *self = (struct car_wash *)p; struct scheduler *sched = p->scheduler; printf("Time %d: car wash %s created\n", sched->clock, p->name); urnd_init(&self->gen_period, self->fast_wash, self->slow_wash, SEED); while (sched->clock < T) { if (car_park_contents == 0) { self->busy = false; printf("Time %d: car wash goes idle\n", sched->clock); sched_passivate(sched); } /* have car waiting */ car_park_contents -= 1; self->busy = true; printf("Time %d: car wash begins service on car (%d now waiting)\n", sched->clock, car_park_contents); sched_hold(sched, urnd_draw(&self->gen_period)); printf("Time %d: car wash finishes service on car (%d now waiting)\n", sched->clock, car_park_contents); } printf("Time %d: car wash %s terminates\n", sched->clock, p->name); } static struct car_wash * car_wash_create(struct scheduler *sched, const char *name, int fast_wash, int slow_wash) { struct car_wash *cw = calloc(1, sizeof(*cw)); cw->fast_wash = fast_wash; cw->slow_wash = slow_wash; process_init(&cw->super, name, sched, car_wash_body); return cw; } struct car_arrival { struct process super; // base class struct urnd gen_period; // car interarrival times are drawn int low_period, high_period; // uniformly from [low_period, high_period] }; static void car_arrival_body(struct process *p) { struct car_arrival *self = (struct car_arrival *)p; struct scheduler *sched = p->scheduler; urnd_init(&self->gen_period, self->low_period, self->high_period, SEED); while (true) { sched_hold(sched, urnd_draw(&self->gen_period)); if (sched->clock >= T) return; printf ("Time %d: car arrives;", sched->clock); if (car_park_contents < N) { car_park_contents += 1; printf(" enters car park (%d) now waiting)\n", car_park_contents); if (!benz->busy) sched_activate_now(sched, &benz->super); } else { printf(" turned away from car park\n"); } } } static struct process * car_arrival_create(struct scheduler *sched, const char *name, int low_period, int high_period) { struct car_arrival *cw = calloc(1, sizeof(*cw)); cw->low_period = low_period; cw->high_period = high_period; process_init(&cw->super, name, sched, car_arrival_body); return &cw->super; } int main() { N = 1; T = 150; char *seed = getenv("SEED"); if (seed != NULL) SEED = atol(seed); struct scheduler *sched = sched_create(); benz = car_wash_create(sched, "Mr. Benz", 25, 35); sched_activate_now(sched, (struct process *)benz); sched_activate_now(sched, car_arrival_create(sched, "Car generator", 10, 25)); sched_run_simulation(sched); }