package org.cloudbus.cloudsim.container.schedulers;
/**
* Created by sareh on 14/07/15.
*/
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.Consts;
import org.cloudbus.cloudsim.ResCloudlet;
import org.cloudbus.cloudsim.core.CloudSim;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
public class ContainerCloudletSchedulerDynamicWorkload extends ContainerCloudletSchedulerTimeShared {
/** The mips. */
private double mips;
/** The number of PEs. */
private int numberOfPes;
/** The total mips. */
private double totalMips;
/** The under allocated mips. */
private Map<String, Double> underAllocatedMips;
/** The cache previous time. */
private double cachePreviousTime;
/** The cache current requested mips. */
private List<Double> cacheCurrentRequestedMips;
/**
* Instantiates a new vM scheduler time shared.
*
* @param mips the mips
* @param numberOfPes the pes number
*/
public ContainerCloudletSchedulerDynamicWorkload (double mips, int numberOfPes) {
super();
setMips(mips);
setNumberOfPes(numberOfPes);
setTotalMips(getNumberOfPes() * getMips());
setUnderAllocatedMips(new HashMap<String, Double>());
setCachePreviousTime(-1);
}
/**
* Updates the processing of cloudlets running under management of this scheduler.
*
* @param currentTime current simulation time
* @param mipsShare array with MIPS share of each Pe 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 updateContainerProcessing(double currentTime, List<Double> mipsShare) {
setCurrentMipsShare(mipsShare);
double timeSpan = currentTime - getPreviousTime();
double nextEvent = Double.MAX_VALUE;
List<ResCloudlet> cloudletsToFinish = new ArrayList<>();
for (ResCloudlet rcl : getCloudletExecList()) {
rcl.updateCloudletFinishedSoFar((long) (timeSpan
* getTotalCurrentAllocatedMipsForCloudlet(rcl, getPreviousTime()) * Consts.MILLION));
if (rcl.getRemainingCloudletLength() == 0) { // finished: remove from the list
cloudletsToFinish.add(rcl);
} else { // not finish: estimate the finish time
double estimatedFinishTime = getEstimatedFinishTime(rcl, currentTime);
if (estimatedFinishTime - currentTime < CloudSim.getMinTimeBetweenEvents()) {
estimatedFinishTime = currentTime + CloudSim.getMinTimeBetweenEvents();
}
if (estimatedFinishTime < nextEvent) {
nextEvent = estimatedFinishTime;
}
}
}
for (ResCloudlet rgl : cloudletsToFinish) {
getCloudletExecList().remove(rgl);
cloudletFinish(rgl);
}
setPreviousTime(currentTime);
if (getCloudletExecList().isEmpty()) {
return 0;
}
cloudletsToFinish.clear();
return nextEvent;
}
/**
* Receives an cloudlet to be executed in the VM managed by this scheduler.
*
* @param cl the cl
* @return predicted completion time
* @pre _gl != null
* @post $none
*/
@Override
public double cloudletSubmit(Cloudlet cl) {
return cloudletSubmit(cl, 0);
}
/**
* Receives an cloudlet to be executed in the VM managed by this scheduler.
*
* @param cl the cl
* @param fileTransferTime the file transfer time
* @return predicted completion time
* @pre _gl != null
* @post $none
*/
@Override
public double cloudletSubmit(Cloudlet cl, double fileTransferTime) {
ResCloudlet rcl = new ResCloudlet(cl);
rcl.setCloudletStatus(Cloudlet.INEXEC);
for (int i = 0; i < cl.getNumberOfPes(); i++) {
rcl.setMachineAndPeId(0, i);
}
getCloudletExecList().add(rcl);
return getEstimatedFinishTime(rcl, getPreviousTime());
}
/**
* Processes a finished cloudlet.
*
* @param rcl finished cloudlet
* @pre rgl != $null
* @post $none
*/
@Override
public void cloudletFinish(ResCloudlet rcl) {
rcl.setCloudletStatus(Cloudlet.SUCCESS);
rcl.finalizeCloudlet();
getCloudletFinishedList().add(rcl);
}
/**
* Get utilization created by all cloudlets.
*
* @param time the time
* @return total utilization
*/
@Override
public double getTotalUtilizationOfCpu(double time) {
double totalUtilization = 0;
for (ResCloudlet rcl : getCloudletExecList()) {
totalUtilization += rcl.getCloudlet().getUtilizationOfCpu(time);
}
return totalUtilization;
}
/**
* Gets the current mips.
*
* @return the current mips
*/
@Override
public List<Double> getCurrentRequestedMips() {
if (getCachePreviousTime() == getPreviousTime()) {
return getCacheCurrentRequestedMips();
}
List<Double> currentMips = new ArrayList<>();
double totalMips = getTotalUtilizationOfCpu(getPreviousTime()) * getTotalMips();
double mipsForPe = totalMips / getNumberOfPes();
for (int i = 0; i < getNumberOfPes(); i++) {
currentMips.add(mipsForPe);
}
setCachePreviousTime(getPreviousTime());
setCacheCurrentRequestedMips(currentMips);
return currentMips;
}
/**
* Gets the current mips.
*
* @param rcl the rcl
* @param time the time
* @return the current mips
*/
@Override
public double getTotalCurrentRequestedMipsForCloudlet(ResCloudlet rcl, double time) {
return rcl.getCloudlet().getUtilizationOfCpu(time) * getTotalMips();
}
/**
* Gets the total current mips for the clouddlet.
*
* @param rcl the rcl
* @param mipsShare the mips share
* @return the total current mips
*/
@Override
public double getTotalCurrentAvailableMipsForCloudlet(ResCloudlet rcl, List<Double> mipsShare) {
double totalCurrentMips = 0.0;
if (mipsShare != null) {
int neededPEs = rcl.getNumberOfPes();
for (double mips : mipsShare) {
totalCurrentMips += mips;
neededPEs--;
if (neededPEs <= 0) {
break;
}
}
}
return totalCurrentMips;
}
/**
* Gets the current mips.
*
* @param rcl the rcl
* @param time the time
* @return the current mips
*/
@Override
public double getTotalCurrentAllocatedMipsForCloudlet(ResCloudlet rcl, double time) {
double totalCurrentRequestedMips = getTotalCurrentRequestedMipsForCloudlet(rcl, time);
double totalCurrentAvailableMips = getTotalCurrentAvailableMipsForCloudlet(rcl, getCurrentMipsShare());
if (totalCurrentRequestedMips > totalCurrentAvailableMips) {
return totalCurrentAvailableMips;
}
return totalCurrentRequestedMips;
}
/**
* Update under allocated mips for cloudlet.
*
* @param rcl the rgl
* @param mips the mips
*/
public void updateUnderAllocatedMipsForCloudlet(ResCloudlet rcl, double mips) {
if (getUnderAllocatedMips().containsKey(rcl.getUid())) {
mips += getUnderAllocatedMips().get(rcl.getUid());
}
getUnderAllocatedMips().put(rcl.getUid(), mips);
}
/**
* Get estimated cloudlet completion time.
*
* @param rcl the rcl
* @param time the time
* @return the estimated finish time
*/
public double getEstimatedFinishTime(ResCloudlet rcl, double time) {
return time
+ ((rcl.getRemainingCloudletLength()) / getTotalCurrentAllocatedMipsForCloudlet(rcl, time));
}
/**
* Gets the total current mips.
*
* @return the total current mips
*/
public int getTotalCurrentMips() {
int totalCurrentMips = 0;
for (double mips : getCurrentMipsShare()) {
totalCurrentMips += mips;
}
return totalCurrentMips;
}
/**
* Sets the total mips.
*
* @param mips the new total mips
*/
public void setTotalMips(double mips) {
totalMips = mips;
}
/**
* Gets the total mips.
*
* @return the total mips
*/
public double getTotalMips() {
return totalMips;
}
/**
* Sets the pes number.
*
* @param pesNumber the new pes number
*/
public void setNumberOfPes(int pesNumber) {
numberOfPes = pesNumber;
}
/**
* Gets the pes number.
*
* @return the pes number
*/
public int getNumberOfPes() {
return numberOfPes;
}
/**
* Sets the mips.
*
* @param mips the new mips
*/
public void setMips(double mips) {
this.mips = mips;
}
/**
* Gets the mips.
*
* @return the mips
*/
public double getMips() {
return mips;
}
/**
* Sets the under allocated mips.
*
* @param underAllocatedMips the under allocated mips
*/
public void setUnderAllocatedMips(Map<String, Double> underAllocatedMips) {
this.underAllocatedMips = underAllocatedMips;
}
/**
* Gets the under allocated mips.
*
* @return the under allocated mips
*/
public Map<String, Double> getUnderAllocatedMips() {
return underAllocatedMips;
}
/**
* Gets the cache previous time.
*
* @return the cache previous time
*/
protected double getCachePreviousTime() {
return cachePreviousTime;
}
/**
* Sets the cache previous time.
*
* @param cachePreviousTime the new cache previous time
*/
protected void setCachePreviousTime(double cachePreviousTime) {
this.cachePreviousTime = cachePreviousTime;
}
/**
* Gets the cache current requested mips.
*
* @return the cache current requested mips
*/
protected List<Double> getCacheCurrentRequestedMips() {
return cacheCurrentRequestedMips;
}
/**
* Sets the cache current requested mips.
*
* @param cacheCurrentRequestedMips the new cache current requested mips
*/
protected void setCacheCurrentRequestedMips(List<Double> cacheCurrentRequestedMips) {
this.cacheCurrentRequestedMips = cacheCurrentRequestedMips;
}
}