/******* ** ** To compile: pcc resource1.pc -sync seq -o resource1.seq -lm ** Adapted for PARSEC 10-9-97 by Monnica Terwilliger ** *******/ /************************************************************************ ** ** Resource Manager Simulation ** ** This program simulates a physical system consisting of one CPU ** server, one Disk server, and several Jobs. Jobs requests service ** from the CPU and the Disk. Both CPU and Disk servers serves the ** Jobs in FIFO order. ** ** The program use the following entities: ** (1) dirver: initiates the simulation ** (2) source: initiates job entities ** (3) cpu: models the cpu server ** (4) diskmanager: models the disk manager to assure ** mutual exclusion among the jobs ** (5) job: simulates a job instance ** ************************************************************************/ #include #include #include #define MAXTIME 5000 /* Maximum simulation time */ #define CPU_MEAN 10 /* Mean CPU service time */ #define DISK_MEAN 10 /* Mean Disk service time */ #define ARRIVAL 0.1 /* Job arrival rate */ int Job_wait_t = 0; /* For statistics collecting */ int Job_no =0; message end{ }; /* End of simulation from driver */ message req { ename id;} ; /* Request message from jobs */ message release { ename id;} ; /* Release message from jobs */ message ack { } ; message finish { } ; int expon(int, unsigned short[3]); /******* ** ** DISKMANAGER: (1) Accepts request message from jobs only if the disk ** is not currently occupied by other jobs. ** (2) or accepts the release message only if the sender ** is the one using the Disk. ** *******/ entity diskmanager () { message req oldreq; /* Request message from jobs */ int busy; /* == 1, if Disk is occupied */ int start, end, i, total; /* Statistics clooecting */ busy = 0; for( start = end = total = i=0;;) { receive (req temp) when (!busy) { oldreq = temp; busy = 1; i++; start = (float)simclock(); send ack{} to oldreq.id; } /* Accepts the release only if */ or receive (release release_msg) /* the sender is using the DISK */ when (ename_cmp(oldreq.id, release_msg.id)) { busy = 0; end = (float)simclock(); total += end - start; } or receive(end signal) when (!busy) break; /* End of simulation */ } end = (float)simclock(); printf("Disk:\tserves %d jobs\tutilization %f\n", i, (float)(total)/(float)(end)); } /*********** ** ** CPU: accepts requests from jobs. The service time is assumed to ** have exponential distribution with mean equals to the input ** variable: mean. ** ***********/ entity cpu ( int mean ) { message req req_job; int i, t, start, end, t_wait; unsigned short seed[3]; seed[0] = seed[1] = seed[2] = (short) mean; for(i= t_wait = 0;;i++) { start = (float)simclock(); receive (req req_job) { end = (float)simclock(); t_wait += end-start; receive (end signal) break; or timeout after (expon(mean, seed)); send finish{ } to req_job.id; } or receive (end signal) break; } end = (float)simclock(); printf("CPU:\tserves %d jobs\tutilization %f\n", i,(float)(end-t_wait)/(float)end); } /********** ** ** JOB: Requests service from the CPU, requests for the access ** privilege from the diskmanager, and the release the privilege. ** The disk accessing time is assumed to have exponential ** distribution with mean equals to the input variable: dmean. ** **********/ entity job (ename cpu, ename disk, int dmean ) { int i, t, end, start, t_wait, tid; unsigned short seed[3]; seed[0] = seed[1] = seed[2] = (short) dmean; send req {self} to cpu ; receive (finish signal); send req {self} to disk ; start = (float)simclock(); receive (ack signal); end = (float)simclock(); Job_wait_t += (t_wait = end - start); Job_no++; end = start + (t = expon(dmean, seed)); hold (t); send release {self} to disk; } /********* ** ** SOURCE: Initiates jobs with arrival rate equals to the input ** variables: arrival. ** *********/ entity source (ename cpu, ename disk, float arrival, int dmean ) { unsigned short seed[3]; seed[0] = seed[1] = seed[2] = (short) dmean; for(;;) { receive (end signal) { break; } or timeout after (expon((int)(1/arrival), seed)) { new job (cpu, disk, dmean); } } printf("Job:\taverage waiting time\t%f\n",(float)Job_wait_t/(float)Job_no); } /********** ** ** DRIVER: Start the simulation. ** **********/ entity driver() { ename disk, cpu, source; disk = new diskmanager ( ); cpu = new cpu (CPU_MEAN); source = new source (cpu, disk, (float)ARRIVAL, DISK_MEAN ); hold (MAXTIME); send end{} to cpu; send end{} to disk ; send end{} to source; } /********** ** ** EXPON(): Returns a value with exponential distribution. ** **********/ int expon(int mean, unsigned short seed[3]) { double a; a =(double)((double)((pc_nrand(seed))%MAXINT)/(double)MAXINT); return((int)(-1*log(a)*mean+1)); }