/** * Updates the processing of cloudlets running under management of this scheduler. * * @param currentTime current simulation time * @param mipsShare array with MIPS share of each processor available to the scheduler * @return time predicted completion time of the earliest finishing cloudlet, or 0 if there is no * next events * @pre currentTime >= 0 * @post $none */ @Override public double updateVmProcessing(double currentTime, List<Double> mipsShare) { setCurrentMipsShare(mipsShare); double timeSpam = currentTime - getPreviousTime(); // time since last update double capacity = 0.0; int cpus = 0; for (Double mips : mipsShare) { // count the CPUs available to the VMM capacity += mips; if (mips > 0) { cpus++; } } currentCpus = cpus; capacity /= cpus; // average capacity of each cpu // each machine in the exec list has the same amount of cpu for (ResCloudlet rcl : getCloudletExecList()) { rcl.updateCloudletFinishedSoFar( (long) (capacity * timeSpam * rcl.getNumberOfPes() * 1000000)); } // no more cloudlets in this scheduler if (getCloudletExecList().size() == 0 && getCloudletWaitingList().size() == 0) { setPreviousTime(currentTime); return 0.0; } // update each cloudlet int finished = 0; List<ResCloudlet> toRemove = new ArrayList<ResCloudlet>(); for (ResCloudlet rcl : getCloudletExecList()) { // finished anyway, rounding issue... if (rcl.getRemainingCloudletLength() == 0) { toRemove.add(rcl); cloudletFinish(rcl); finished++; } } getCloudletExecList().removeAll(toRemove); // for each finished cloudlet, add a new one from the waiting list if (!getCloudletWaitingList().isEmpty()) { for (int i = 0; i < finished; i++) { toRemove.clear(); for (ResCloudlet rcl : getCloudletWaitingList()) { if ((currentCpus - usedPes) >= rcl.getNumberOfPes()) { rcl.setCloudletStatus(Cloudlet.INEXEC); for (int k = 0; k < rcl.getNumberOfPes(); k++) { rcl.setMachineAndPeId(0, i); } getCloudletExecList().add(rcl); usedPes += rcl.getNumberOfPes(); toRemove.add(rcl); break; } } getCloudletWaitingList().removeAll(toRemove); } } // estimate finish time of cloudlets in the execution queue double nextEvent = Double.MAX_VALUE; for (ResCloudlet rcl : getCloudletExecList()) { double remainingLength = rcl.getRemainingCloudletLength(); double estimatedFinishTime = currentTime + (remainingLength / (capacity * rcl.getNumberOfPes())); if (estimatedFinishTime - currentTime < 0.1) { estimatedFinishTime = currentTime + 0.1; } if (estimatedFinishTime < nextEvent) { nextEvent = estimatedFinishTime; } } setPreviousTime(currentTime); return nextEvent; }