// a system simulation for COP5614 Sp 2002 #include #include #include // job definition - each job terminates w/ zero // must have at least 0 // 'instructions' : // negative numbers indicate blocking io time // positive numbers indicate CPU burst time // first parameters are defined below #define NPARAMS 8 // number of parameters in header #define PID 0 // process id #define PRI 1 // priority #define LEN 2 // code length #define IN 3 // time in #define OUT 4 // time out #define OWNER 5 // owner id #define PC_HIGH 6 // current pc 'segment' #define PC_LOW 7 // current PC 'instr' #define CODE 8 // code starts 8 from front // ------- simulation globals //#define LONGNMESSY // will get detailed output //#define RR 2 // causes pre-emption (time n) if not commented out // comment out all but one QUE discipline! //#define FCFS #define PRIORITY //#define SJF int Clock=0; int Pid = 0; int Alarm=0; // global control variables int nFinished=0; // incremented as job go out int nRead =0; // incremented as jobs are read #define MAXNJOBS 100 #define MAXJOBSIZE 100 #define MAXJOBLEN 100 #define MAXRUNTIME 31 // ======== help functions ============== // ------------ job functions int shorter(int j1[], int j2[]) { return j1[CODE+j1[PC_HIGH]] - j1[PC_LOW] < j2[CODE+j2[PC_HIGH]] - j2[PC_LOW]; } int higherPri(int * j1,int * j2) { return j1[PRI]>j2[PRI]; } void print_job(int * job) { cout << "job: "; for (int i=0; i0) *(dest++)=*(src++); } // ============= elements of the state model #define QTYPE int * #include "queue.h" class Source { public: Source(int size){ Q=Queue(size);} QTYPE give(); // give a job & return 1 else 0 int accept(QTYPE); void print(){ cout << "Source: "; Q.print();} private: initial(int size); Queue Q; }; int Source:: accept(QTYPE job) { //cout << "inserting at " << job << "\n"; return Q.insert(job); } QTYPE Source::give() { if (Q.empty()) return NULL; if ((Q.peek())[IN]>Clock) return NULL; return Q.remove(); } Source source(MAXNJOBS); /// SOURCE OBJECT ///// //------ SINK class class Sink { public: Sink(){} void accept(QTYPE); private: QTYPE job; }; void Sink:: accept(QTYPE job) { job[OUT]=Clock; cout << "turnAround=" << job[OUT]-job[IN] << ":" ; print_job(job); nFinished++; } Sink sink; ///// SINK OBJECT ///// //======== READY state ------ class Ready { public: Ready(int size){ Q=Queue(size);} QTYPE give(); // give a job & return 1 else 0 int accept(QTYPE); void tick(); void print(){ cout << "Ready: "; Q.print();} private: initial(int size); Queue Q; }; void Ready::tick() { QTYPE j; while (j = source.give()) Q.insert(j); } int Ready:: accept(QTYPE job) { return Q.insert(job); } // --- implements FCFS QTYPE Ready::give() { #ifdef SJF return Q.shortest(); #endif #ifdef PRIORITY return Q.highestPri(); #endif return Q.remove(); } Ready ready(MAXNJOBS); /// READY OBJECT ///// // ========== BLOCKED state class Blocked { public: Blocked(); QTYPE give(); // give a job & return 1 else 0 int accept(QTYPE); void tick(); void print(); private: QTYPE jobs[MAXNJOBS]; }; void Blocked :: print(){ cout << "Blocked: "; for (int i=0; i< MAXNJOBS; i++) if (jobs[i]!=NULL) { cout << "(" << /*jobs[i][PID]*/ 1; cout << "," << /*jobs[i][PC_LOW]*/ 2 << ") "; } cout << "\n"; } Blocked::Blocked(){ for (int i=0; i= 0 void Blocked :: tick() { for (int i=0;i=job[CODE+job[PC_HIGH]]) { // finished step job[PC_HIGH]++; job[PC_LOW]= job[CODE+job[PC_HIGH]]; if( job[PC_LOW]==0){ // finished job sink.accept(job); job=NULL; } else if (job[PC_LOW]<0) { // instr < 0 => I/O blocked.accept(job); job=NULL; } } } if (job==NULL) get_job(); } Cpu cpu; /// CPU OBJECT /// // ==== general program functions void initial(int argc, char * argv[]) { int job[MAXJOBLEN+NPARAMS+1]; int nJobs=0; QTYPE j; if (argc>1) { ifstream data(argv[1]); // open job data file while (!data.eof()) { int i=0; for (i=0;i> job[i]; if (data.eof()) break; // no job while (!data.eof()) { // read data to zero or eof data >> job[i]; if (job[i]==0) {i++; break;} if (++i>MAXJOBLEN+NPARAMS){ // save instr's cerr << "Job was too long: "; printHdr(job); exit(2); } } init_job(i,job); print_job(job); j= new int[i]; // make copy of job inpt & Q to source copy(job, i, j); if (!source.accept(j)) { cerr << "source did not accept job: "; printHdr(job); } else nJobs++; } } else { cout << "Must code get data from input\n"; exit(2); } cerr << "Loaded " << nJobs << " jobs\n"; nRead = nJobs; } main(int argc, char * argv[]) { QTYPE job; int dummy; initial(argc, argv); while (Clock< MAXRUNTIME && nFinished=RR) cpu.preempt(); #endif #ifdef LONGNMESSY cout << "-- Time: " << Clock << "\n"; cpu.print(); ready.print(); blocked.print(); cin >> dummy; #endif Clock++; } return 0; }