/******* ** ** This program also shows how trace works. ** ** To compile: mc -trace tandem.m -o tandem -lm ** ** "@(#)tandem.m 1.1 - 96/01/05" *******/ /*********************************************************************** ** ** Tandem Queue Simulation ** ** This is a simulation of tandem queues with 8 FIFO servers. The ** program simulates MAX_JOB jobs flow through these FIFO ** servers. The simulation collects the utilization of servers ** and the average waiting time of jobs. ** ** Entities defined in the program: ** (1) SERVER: A FIFO server ** (2) SINK: Sink entity to compute average job ** wait time in a server ** (3) DRIVER: Initiate the simulation ** **********************************************************************/ #include #include #include "maisie.h" #define MAX_JOB 100 #define MAX_SERVER 8 #define MEAN 10 #define ARRIVAL 0.1 #define NOW (cti(sclock(self))) /********** ** ** SERVER: Service jobs with mean service time: mean. ** **********/ entity server {int id, int mean, ename next} { int i, start, t_wait, job_wait; message job {int t_send, t_wait;} job; message end {} end; /* trace 2 when (id == 0 && i < 2); /* Print trace information of */ /* the first server for the */ /* first two jobs */ for(start=NOW, t_wait = i=0;;) wait until{ mtype(job) { i++; t_wait += (NOW - start); job_wait = NOW - msg.job.t_send + msg.job.t_wait; wait expon(mean) until mtype(timeout); invoke next with job {NOW, job_wait}; start=NOW; } or mtype(end) { t_wait += (NOW - start); invoke next with end{}; printf("\tCPU %d:\tutilization %f\n", id, (float)(NOW-t_wait)/(float)NOW); return; } } } /*********** ** ** SINK: Accumulate jobs and compute the average wait time. ** **********/ entity sink {} { int total_wait, i; message job job; message end end; for(total_wait= i = 0;;) wait until { mtype(job) { i++; total_wait += msg.job.t_wait; } or mtype(end) { printf("\tJOB:\taverage wait time in a server: %f\n", (float)total_wait/(float)(i*MAX_SERVER)); return; } } } /************ ** ** DRIVER: Initiate the simulation and act as a SOURCE entity. ** ************/ entity driver { } { ename s[MAX_SERVER+1]; int i; s[i=MAX_SERVER] = new sink{}; for(--i; i >= 0 ; i--) s[i] = new server { i, MEAN, s[i+1] }; for(i = 0; i < MAX_JOB; i++) { invoke s[0] with job{NOW, 0}; wait expon((int)((float)1/((float)ARRIVAL))) until mtype(timeout); } invoke s[0] with end{}; printf("\nTandem Queues Simulation:\n\tNumber of Servers:\t%d\n",MAX_SERVER); printf("\tNumber of Jobs:\t%d\n\n", MAX_JOB); } /********** ** ** EXPON(): Returns a value with exponential distribution. ** **********/ int expon(int mean) { return(int)((-log((double)(1.0-drand48()))) * ((double) mean)); }