import java.util.*; import java.util.concurrent.*; /** * Models a basic CPU that cannot be interrupted. * @author Kyle Burke */ public class CPU { //fields //whether to print everything that's going on private boolean verbosePrinting; //the completed jobs private List<Job> completed; //name of this CPU private String name; //incoming job list private BlockingQueue<Job> incoming; //whether this is ready to stop private boolean readyToStop; //only opens up when it's completed private Semaphore isDone; //start time of the whole cpu private long startTime; //time this spent running private long runningTime; //the number of jobs this will process private int numJobs; //constructor public CPU(String name, BlockingQueue<Job> incoming, boolean verbosePrinting) { this.name = name; this.incoming = incoming; this.verbosePrinting = verbosePrinting; this.completed = new ArrayList<Job>(); this.readyToStop = false; this.isDone = new Semaphore(0); this.numJobs = -1; } public void blockUntilDone() { this.isDone.acquireUninterruptibly(); this.isDone.release(); } public void setNumJobs(int numJobs) { this.numJobs = numJobs; } //ends this when the incoming queue is empty public void shutDown() { this.readyToStop = true; } //starts this CPU running public void start() { this.startTime = System.currentTimeMillis(); Thread t = new Thread(() -> run()); t.start(); System.out.println("CPU " + name + " is chugging along!"); } private void run() { //while (!this.readyToStop || this.incoming.getNumElements() > 0) { while (this.completed.size() < this.numJobs) { try { Job next = this.incoming.take(); if (this.verbosePrinting) { System.out.println("Next job on " + this.name + ": " + next.toString()); } /* long runningTime = next.getLength(); next.run(); try { Thread.sleep(runningTime); } catch (Exception e) { } next.pause(); if (!next.isDone()) { System.err.println("Job didn't finish!!!!"); }*/ next.run(this); if (next.getLength() > 0) { completed.add(next); if (this.verbosePrinting) { System.out.println("Completed on " + this.name + ": " + next.toString()); System.out.println("We've run " + this.completed.size() + " jobs."); } else if (this.completed.size() % (this.numJobs / 10) == 0) { System.out.println("CPU " + name + " has completed " + this.completed.size() + " jobs."); } } } catch (InterruptedException e) { System.err.println("Waiting to get the next job got interrupted!"); } } this.isDone.release(); this.runningTime = System.currentTimeMillis() - this.startTime; long totalLength = this.getTotalJobLengths(); long totalLatency = this.getTotalLatency(); int numMadeDeadline = this.getTotalDeadlinesMade(); System.out.println("CPU " + this.name + " finished!\n - Total lengths: " + totalLength + "\n - Total latency: " + totalLatency + "\n - Utility: " + this.getUtilityPercentage() + "%\n - Total wait time: " + this.getTotalWaitTime() + "\n - Average wait time: " + this.getAverageWaitTime() + "\n - Max wait time: " + this.getMaxWaitTime() + "\n - # Made deadline: " + numMadeDeadline + "/" + this.completed.size()); } public long getTotalJobLengths() { long total = 0; //this shouldn't be executed until it's done... this.isDone.acquireUninterruptibly(); for (Job job : this.completed) { total += job.getLength(); } this.isDone.release(); return total; } public long getTotalLatency() { long total = 0; //this shouldn't be executed until it's done... this.isDone.acquireUninterruptibly(); for (Job job : this.completed) { total += job.getLatency(); } this.isDone.release(); return total; } public int getTotalDeadlinesMade() { int total = 0; this.isDone.acquireUninterruptibly(); for (Job job : this.completed) { if (job.madeDeadline()) { total += 1; } } this.isDone.release(); return total; } public long getTotalWaitTime() { return this.getTotalLatency() - this.getTotalJobLengths(); } public long getMaxWaitTime() { long max = 0; this.isDone.acquireUninterruptibly(); for (Job job : this.completed) { long wait = job.getWaitTime(); if (wait > max) { max = wait; } } this.isDone.release(); return max; } public List<Job> getCompleted() { List<Job> completedCopy = new ArrayList<>(); for (Job job : this.completed) { completedCopy.add(job.clone()); } return completedCopy; } public int getNumJobsCompleted() { return this.completed.size(); } public long getAverageWaitTime() { return this.getTotalWaitTime() / this.getNumJobsCompleted(); } public long getEfficiency() { return (100 * this.getTotalJobLengths() / this.getTotalLatency()); } public int getUtilityPercentage() { return (int) (100 * this.getTotalJobLengths() / this.runningTime); } } //end of CPU.java