// CPUScheduler.h Dave Reed // // CPUScheduler class implementation /////////////////////////////////////////////////////////////////////////////// #include #include #include #include "CPUScheduler.h" #include "Job.h" using namespace std; CPUScheduler::CPUScheduler() // Constructor: initializes counters for time slice and load time { sliceTimeRemaining = TIME_SLICE; loadTimeRemaining = LOAD_DELAY; } bool CPUScheduler::JobsRemaining() const // Returns: true if there is at least one job in either of the ready or wait queues { return (!ReadyQueue.empty() || !WaitQueue.empty()); } void CPUScheduler::AddNewJob(Job newJob, int time) // Assumes: time > 0 // Results: adds newJob to the back of the ready queue (at specified time) { ReadyQueue.push(newJob); cout << setw(4) << time << ": JOB " << newJob.GetID() << " ARRIVES" << endl; } void CPUScheduler::Execute(int time) // Assumes: time > 0 // Results: executes one CPU cycle (at specified time) -- this may involve moving jobs // from waiting to ready, loading a new job, performing one instruction // execution, and displaying theresults of the execution { while (!WaitQueue.empty() && WaitQueue.top().GetPriority() <= time) { Job newJob = (Job)WaitQueue.top(); // MOVE JOBS FROM WAIT QUEUE WaitQueue.pop(); // TO READY QUEUE AS NEEDED ReadyQueue.push(newJob); } if (!ReadyQueue.empty()) { // IF READY JOB IS AVAILABLE Job & currentJob = ReadyQueue.front(); // GET THE NEXT JOB if (loadTimeRemaining > 0) { // IF STILL LOADING, IDLE if (loadTimeRemaining == LOAD_DELAY) { cout << setw(4) << time << ": LOAD JOB " << currentJob.GetID() << " (delay = " << LOAD_DELAY << ")" << endl; } loadTimeRemaining--; } else { // OTHERWISE, PROCESS if (sliceTimeRemaining == TIME_SLICE) { // DISPLAY IF NEW JOB cout << setw(4) << time << ": START JOB " << currentJob.GetID() << " (burst = " << currentJob.GetRemainingBurst() << ")" << endl; } JobStatus status = currentJob.Execute(); // EXECUTE THE JOB AND sliceTimeRemaining--; // REDUCE ITS TIME SLICE if (status == DONE) { // IF JOB FINISHED cout << setw(4) << time+1 << ": FINISH JOB " << currentJob.GetID() << endl; ReadyQueue.pop(); // REMOVE FROM QUEUE AND sliceTimeRemaining = TIME_SLICE; // RESET COUNTS loadTimeRemaining = LOAD_DELAY; } else if (status == IO) { // IF REQUESTED I/O int delay = randomizer.RandomInt(IO_MIN_DELAY, IO_MAX_DELAY); cout << setw(4) << time+1 << ": I/O JOB " << currentJob.GetID() << " (delay = " << delay << ")" << endl; PriorityJob waitJob(currentJob, time+1+delay); ReadyQueue.pop(); // MOVE TO WAIT QUEUE WaitQueue.push(waitJob); // USING RANDOM DELAY, sliceTimeRemaining = TIME_SLICE; // AND RESET COUNTS loadTimeRemaining = LOAD_DELAY; } else if (sliceTimeRemaining == 0) { // IF TIME SLICE IS UP cout << setw(4) << time+1 << ": TIMEOUT JOB " << currentJob.GetID() << endl; Job readyJob = currentJob; ReadyQueue.pop(); // MOVE TO BACK OF QUEUE ReadyQueue.push(readyJob); sliceTimeRemaining = TIME_SLICE; // RESET TIME SLICE if (ReadyQueue.size() > 1) { // IF OTHER JOBS READY, loadTimeRemaining = LOAD_DELAY; // RESET LOAD COUNT } } } } }