// CPUScheduler.h Dave Reed 1/28/06 /////////////////////////////////////////////////////////////////////////////// #include #include #include #include "CPUScheduler.h" #include "Job.h" using namespace std; CPUScheduler::CPUScheduler(int delay, int slice) // Constructor: initializes counters for time slice and load time { loadDelay = delay; timeSlice = slice; sliceTimeRemaining = 0; loadTimeRemaining = 0; currentTime = 0; } int CPUScheduler::getTime() const // Returns: current time in the simulation { return currentTime; } bool CPUScheduler::jobsRemaining() const // Returns: true if there is at least one job in either of the ready or wait queues { return !readyQueue.empty(); } void CPUScheduler::addNewJob(Job newJob) // Assumes: time > 0 // Results: adds newJob to the back of the ready queue (at specified time) { readyQueue.push(newJob); cout << setw(4) << currentTime << ": JOB " << newJob.getID() << " ARRIVES" << endl; } void CPUScheduler::execute() // Assumes: time > 0 // Results: executes one CPU cycle (at specified time) -- this may involve // loading a new job, performing one instruction, interrupting a job, // and displaying the results of the execution { if (!readyQueue.empty()) { // IF READY JOB IS AVAILABLE Job & currentJob = readyQueue.front(); // GET FRONT JOB if (currentJob.getStatus() == READY) { // IF IT NEEDS LOADING if (loadTimeRemaining == 0) { cout << setw(4) << currentTime << ": LOAD JOB " << currentJob.getID() << " (delay = " << loadDelay << ")" << endl; loadTimeRemaining = loadDelay; } currentTime++; loadTimeRemaining--; if (loadTimeRemaining == 0) { currentJob.setStatus(LOADED); } } else { //OTHERWISE, if (currentJob.getStatus() == LOADED) { // IF READY TO START cout << setw(4) << currentTime << ": START JOB " << readyQueue.front().getID() << " (length = " << readyQueue.front().getRemaining() << ")" << endl; sliceTimeRemaining = timeSlice; } currentJob.execute(); // EXECUTE THE JOB FOR currentTime++; // ONE UNIT OF TIME AND sliceTimeRemaining--; // REDUCE ITS TIME SLICE if (currentJob.getStatus() == DONE) { // IF JOB IS FINISHED finishJob(); } else if (sliceTimeRemaining == 0) { // IF TIME SLICE IS UP interruptJob(); } } } else { currentTime++; } } void CPUScheduler::finishJob() { cout << setw(4) << currentTime << ": FINISH JOB " << readyQueue.front().getID() << endl; readyQueue.pop(); // REMOVE JOB FROM QUEUE } void CPUScheduler::interruptJob() { cout << setw(4) << currentTime << ": TIMEOUT JOB " << readyQueue.front().getID() << endl; if (readyQueue.size() > 1) { // IF MORE THAN ONE JOB readyQueue.front().setStatus(READY); // SET TO READY STATE readyQueue.push(readyQueue.front()); // AND MOVE TO THE readyQueue.pop(); // BACK OF THE QUEUE } else { // OTHERWISE, readyQueue.front().setStatus(LOADED); // MARK LONE JOB AS LOADED } }