/* Timesharing Computer Using Discrete State Simulation CS509 Assignment 2 Winter 1995 G. Back */ import sim.*; import queues.*; //////////////////////////////////////////////////////////////////////////// ///// CPU class //////////////////////////////////////////////////////////////////////////// class CPU { // 2 queues static Queue idle_CPUs = new Queue(); static Queue waiting_jobs = new Queue(); String name; int time_slice; // time slice (0 denotes infinity) int busy_time; // absolute busy time int const_time; // time of construction // create a new CPU CPU(String n, int ts) { name = n; time_slice = ts; const_time = scheduler.clock; busy_time = 0; // and see if we can help someone if( !waiting_jobs.IsEmpty() ) { job next = (job)waiting_jobs.Dequeue(); next.running_on_CPU = this; scheduler.activate( next ); } else { // otherwise put CPU in queue of idle CPUs idle_CPUs.Enqueue(this); } } void print() { System.out.println(name + ": duty cycle " + busy_time / (double)(scheduler.clock-const_time)); } // destroy CPU, remove it from the queue of idling CPUs // ASSUMES THAT CPU IS IDLE !!! void remove_cpu() { idle_CPUs.Remove(this); System.out.print("Time " + scheduler.clock + ": deleted "); print(); } }; //////////////////////////////////////////////////////////////////////////// ///// job class //////////////////////////////////////////////////////////////////////////// abstract class job extends process { int CPU_wait_time; CPU running_on_CPU; job(String name) { super(name); CPU_wait_time = 0; running_on_CPU = null; } // former destructor void remove_job() { System.out.println("Time " + scheduler.clock + ": " + name + " deleted; total CPU wait time "+CPU_wait_time); } // run for a certain amount of time void run(int left) { while(left > 0) { // see if I have to help myself if (!CPU.idle_CPUs.IsEmpty() && CPU.waiting_jobs.IsEmpty()) { running_on_CPU = (CPU)CPU.idle_CPUs.Dequeue(); } // if I couldn't help myself and nobody has already given // a CPU to me, I have to swallow the pill and wait if (running_on_CPU == null) { // store the time when we started waiting CPU_wait_time -= scheduler.clock; // wait for a CPU waitq( CPU.waiting_jobs ); // update waiting time CPU_wait_time += scheduler.clock; } // make sure I finally got one if( running_on_CPU == null) { scheduler.fatal_error("Didn't get a CPU"); } int run_for; if (running_on_CPU.time_slice == 0 || left <= running_on_CPU.time_slice) // case I: can run to completion run_for = left; else // case II: get only one timeslice run_for = running_on_CPU.time_slice; System.out.println("Time " + scheduler.clock + ": " + name + " begins running on " + running_on_CPU.name); scheduler.hold( run_for ); System.out.println("Time " + scheduler.clock + ": " + name + " stops running on " + running_on_CPU.name); running_on_CPU.busy_time += run_for; left -= run_for; // put CPU in queue of idle CPUs CPU.idle_CPUs.Enqueue(running_on_CPU); running_on_CPU = null; // see if I must provide someone with a CPU if (!CPU.waiting_jobs.IsEmpty()) { job next = (job)CPU.waiting_jobs.Dequeue(); next.running_on_CPU = (CPU)CPU.idle_CPUs.Dequeue(); scheduler.activate( next ); } } // end while(left > 0) } // print job name and CPU it is running on, if any public void print() { if (running_on_CPU != null) { System.out.print(name + " running on "); running_on_CPU.print(); } else System.out.println(name + " not running"); } }