/* * Title: CloudSim Toolkit Description: CloudSim (Cloud Simulation) Toolkit for Modeling and * Simulation of Clouds Licence: GPL - http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2009-2012, The University of Melbourne, Australia */ package org.cloudbus.cloudsim; import java.util.ArrayList; import java.util.List; import org.cloudbus.cloudsim.core.CloudSim; /** * CloudletSchedulerTimeShared implements a policy of scheduling performed by a virtual machine * to run its {@link Cloudlet Cloudlets}. * Cloudlets execute in time-shared manner in VM. * Each VM has to have its own instance of a CloudletScheduler. * * @author Rodrigo N. Calheiros * @author Anton Beloglazov * @since CloudSim Toolkit 1.0 */ public class CloudletSchedulerTimeShared extends CloudletScheduler { /** The number of PEs currently available for the VM using the scheduler, * according to the mips share provided to it by * {@link #updateVmProcessing(double, java.util.List)} method. */ protected int currentCPUs; /** * Creates a new CloudletSchedulerTimeShared object. This method must be invoked before starting * the actual simulation. * * @pre $none * @post $none */ public CloudletSchedulerTimeShared() { super(); currentCPUs = 0; } @Override public double updateVmProcessing(double currentTime, List<Double> mipsShare) { setCurrentMipsShare(mipsShare); double timeSpam = currentTime - getPreviousTime(); for (ResCloudlet rcl : getCloudletExecList()) { rcl.updateCloudletFinishedSoFar((long) (getCapacity(mipsShare) * timeSpam * rcl.getNumberOfPes() * Consts.MILLION)); } if (getCloudletExecList().size() == 0) { setPreviousTime(currentTime); return 0.0; } // check finished cloudlets double nextEvent = Double.MAX_VALUE; List<ResCloudlet> toRemove = new ArrayList<ResCloudlet>(); for (ResCloudlet rcl : getCloudletExecList()) { long remainingLength = rcl.getRemainingCloudletLength(); if (remainingLength == 0) {// finished: remove from the list toRemove.add(rcl); cloudletFinish(rcl); continue; } } getCloudletExecList().removeAll(toRemove); // estimate finish time of cloudlets for (ResCloudlet rcl : getCloudletExecList()) { double estimatedFinishTime = currentTime + (rcl.getRemainingCloudletLength() / (getCapacity(mipsShare) * rcl.getNumberOfPes())); if (estimatedFinishTime - currentTime < CloudSim.getMinTimeBetweenEvents()) { estimatedFinishTime = currentTime + CloudSim.getMinTimeBetweenEvents(); } if (estimatedFinishTime < nextEvent) { nextEvent = estimatedFinishTime; } } setPreviousTime(currentTime); return nextEvent; } /** * Gets the individual MIPS capacity available for each PE available for the scheduler, * considering that all PEs have the same capacity. * * @param mipsShare list with MIPS share of each PE available to the scheduler * @return the capacity of each PE */ protected double getCapacity(List<Double> mipsShare) { double capacity = 0.0; int cpus = 0; for (Double mips : mipsShare) { capacity += mips; if (mips > 0.0) { cpus++; } } currentCPUs = cpus; int pesInUse = 0; for (ResCloudlet rcl : getCloudletExecList()) { pesInUse += rcl.getNumberOfPes(); } if (pesInUse > currentCPUs) { capacity /= pesInUse; } else { capacity /= currentCPUs; } return capacity; } @Override public Cloudlet cloudletCancel(int cloudletId) { boolean found = false; int position = 0; // First, looks in the finished queue found = false; for (ResCloudlet rcl : getCloudletFinishedList()) { if (rcl.getCloudletId() == cloudletId) { found = true; break; } position++; } if (found) { return getCloudletFinishedList().remove(position).getCloudlet(); } // Then searches in the exec list position=0; for (ResCloudlet rcl : getCloudletExecList()) { if (rcl.getCloudletId() == cloudletId) { found = true; break; } position++; } if (found) { ResCloudlet rcl = getCloudletExecList().remove(position); if (rcl.getRemainingCloudletLength() == 0) { cloudletFinish(rcl); } else { rcl.setCloudletStatus(Cloudlet.CANCELED); } return rcl.getCloudlet(); } // Now, looks in the paused queue found = false; position=0; for (ResCloudlet rcl : getCloudletPausedList()) { if (rcl.getCloudletId() == cloudletId) { found = true; rcl.setCloudletStatus(Cloudlet.CANCELED); break; } position++; } if (found) { return getCloudletPausedList().remove(position).getCloudlet(); } return null; } @Override public boolean cloudletPause(int cloudletId) { boolean found = false; int position = 0; for (ResCloudlet rcl : getCloudletExecList()) { if (rcl.getCloudletId() == cloudletId) { found = true; break; } position++; } if (found) { // remove cloudlet from the exec list and put it in the paused list ResCloudlet rcl = getCloudletExecList().remove(position); if (rcl.getRemainingCloudletLength() == 0) { cloudletFinish(rcl); } else { rcl.setCloudletStatus(Cloudlet.PAUSED); getCloudletPausedList().add(rcl); } return true; } return false; } @Override public void cloudletFinish(ResCloudlet rcl) { rcl.setCloudletStatus(Cloudlet.SUCCESS); rcl.finalizeCloudlet(); getCloudletFinishedList().add(rcl); } @Override public double cloudletResume(int cloudletId) { boolean found = false; int position = 0; // look for the cloudlet in the paused list for (ResCloudlet rcl : getCloudletPausedList()) { if (rcl.getCloudletId() == cloudletId) { found = true; break; } position++; } if (found) { ResCloudlet rgl = getCloudletPausedList().remove(position); rgl.setCloudletStatus(Cloudlet.INEXEC); getCloudletExecList().add(rgl); // calculate the expected time for cloudlet completion // first: how many PEs do we have? double remainingLength = rgl.getRemainingCloudletLength(); double estimatedFinishTime = CloudSim.clock() + (remainingLength / (getCapacity(getCurrentMipsShare()) * rgl.getNumberOfPes())); return estimatedFinishTime; } return 0.0; } @Override public double cloudletSubmit(Cloudlet cloudlet, double fileTransferTime) { ResCloudlet rcl = new ResCloudlet(cloudlet); rcl.setCloudletStatus(Cloudlet.INEXEC); for (int i = 0; i < cloudlet.getNumberOfPes(); i++) { rcl.setMachineAndPeId(0, i); } getCloudletExecList().add(rcl); // use the current capacity to estimate the extra amount of // time to file transferring. It must be added to the cloudlet length double extraSize = getCapacity(getCurrentMipsShare()) * fileTransferTime; long length = (long) (cloudlet.getCloudletLength() + extraSize); cloudlet.setCloudletLength(length); return cloudlet.getCloudletLength() / getCapacity(getCurrentMipsShare()); } @Override public double cloudletSubmit(Cloudlet cloudlet) { return cloudletSubmit(cloudlet, 0.0); } @Override public int getCloudletStatus(int cloudletId) { for (ResCloudlet rcl : getCloudletExecList()) { if (rcl.getCloudletId() == cloudletId) { return rcl.getCloudletStatus(); } } for (ResCloudlet rcl : getCloudletPausedList()) { if (rcl.getCloudletId() == cloudletId) { return rcl.getCloudletStatus(); } } return -1; } @Override public double getTotalUtilizationOfCpu(double time) { /* * @todo */ double totalUtilization = 0; for (ResCloudlet gl : getCloudletExecList()) { totalUtilization += gl.getCloudlet().getUtilizationOfCpu(time); } return totalUtilization; } @Override public boolean isFinishedCloudlets() { return getCloudletFinishedList().size() > 0; } @Override public Cloudlet getNextFinishedCloudlet() { if (getCloudletFinishedList().size() > 0) { return getCloudletFinishedList().remove(0).getCloudlet(); } return null; } @Override public int runningCloudlets() { return getCloudletExecList().size(); } @Override public Cloudlet migrateCloudlet() { ResCloudlet rgl = getCloudletExecList().remove(0); rgl.finalizeCloudlet(); return rgl.getCloudlet(); } @Override public List<Double> getCurrentRequestedMips() { List<Double> mipsShare = new ArrayList<Double>(); return mipsShare; } @Override public double getTotalCurrentAvailableMipsForCloudlet(ResCloudlet rcl, List<Double> mipsShare) { /*@todo It isn't being used any the the given parameters.*/ return getCapacity(getCurrentMipsShare()); } @Override public double getTotalCurrentAllocatedMipsForCloudlet(ResCloudlet rcl, double time) { //@todo The method is not implemented, in fact return 0.0; } @Override public double getTotalCurrentRequestedMipsForCloudlet(ResCloudlet rcl, double time) { //@todo The method is not implemented, in fact // TODO Auto-generated method stub return 0.0; } @Override public double getCurrentRequestedUtilizationOfRam() { double ram = 0; for (ResCloudlet cloudlet : cloudletExecList) { ram += cloudlet.getCloudlet().getUtilizationOfRam(CloudSim.clock()); } return ram; } @Override public double getCurrentRequestedUtilizationOfBw() { double bw = 0; for (ResCloudlet cloudlet : cloudletExecList) { bw += cloudlet.getCloudlet().getUtilizationOfBw(CloudSim.clock()); } return bw; } }