diff --git a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/Cloudlet.java b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/Cloudlet.java index d38f41050..b4c1938da 100644 --- a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/Cloudlet.java +++ b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/Cloudlet.java @@ -667,38 +667,6 @@ void assignCloudletToDatacenter( * @post $none */ boolean setCloudletFinishedSoFar(final long length); - - /** - * Gets the virtual runtime (vruntime) that indicates how long the Cloudlet - * has been executing by a {@link CloudletScheduler} (in seconds). - * The default value of this attribute is zero and each scheduler - * implementation might or not set a value to such attribute - * so that the scheduler might use to perform context switch, - * preempting running Cloudlets to enable other ones to start executing. - * By this way, the attribute is just used internally by specific CloudletSchedulers. - * - * @return - */ - double getVirtualRuntime(); - - /** - * Adds a given time to the {@link #getVirtualRuntime() virtual runtime}. - * - * @param timeToAdd time to add to the virtual runtime (in seconds) - * @return the new virtual runtime (in seconds) - * @pre timeToAdd >= 0 - */ - double addVirtualRuntime(double timeToAdd); - - /** - * Sets the virtual runtime (vruntime) that indicates how long the Cloudlet - * has been executing by a {@link CloudletScheduler} (in seconds). This attribute is used - * just internally by specific CloudletSchedulers. - * - * @param virtualRuntime the value to set (in seconds) - * @see #getVirtualRuntime() - */ - void setVirtualRuntime(double virtualRuntime); /** * Gets the listener object that will be notified every time when @@ -824,7 +792,7 @@ void assignCloudletToDatacenter( @Override public long getCloudletFinishedSoFar() { return 0L; } @Override public long getCloudletFinishedSoFar(int datacenterId) { return 0L; } @Override public String getCloudletHistory() { return ""; }; - @Override public int getId() { return 0; } + @Override public int getId() { return -1; } @Override public long getCloudletLength() { return 0L; } @Override public long getCloudletOutputSize() { return 0L; } @Override public Status getCloudletStatus() { return Status.FAILED; } @@ -839,12 +807,12 @@ void assignCloudletToDatacenter( @Override public int getNumberOfPes(){ return 0; } @Override public double getProcessingCost(){ return 0.0; } @Override public List getRequiredFiles() { return Collections.emptyList();} - @Override public int getReservationId() { return 0; } - @Override public int getDatacenterId() { return 0; } + @Override public int getReservationId() { return -1; } + @Override public int getDatacenterId() { return -1; } @Override public Status getStatus() { return getCloudletStatus(); } @Override public double getDatacenterArrivalTime() { return 0.0; } @Override public double getSubmissionTime(int datacenterId) { return 0.0; } - @Override public int getUserId() { return 0; } + @Override public int getUserId() { return -1; } @Override public UtilizationModel getUtilizationModelBw() { return UtilizationModel.NULL; } @Override public UtilizationModel getUtilizationModelCpu() { return UtilizationModel.NULL; } @Override public UtilizationModel getUtilizationModelRam() { return UtilizationModel.NULL; } @@ -888,8 +856,5 @@ void assignCloudletToDatacenter( @Override public double registerArrivalOfCloudletIntoDatacenter() { return -1; } @Override public boolean isBoundedToVm() { return false; } @Override public int compareTo(Cloudlet o) { return 0; } - @Override public double getVirtualRuntime() { return 0; } - @Override public void setVirtualRuntime(double virtualRuntime) {} - @Override public double addVirtualRuntime(double timeToAdd) { return 0; } }; } diff --git a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/CloudletAbstract.java b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/CloudletAbstract.java index ba1f1b34a..883251b5a 100644 --- a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/CloudletAbstract.java +++ b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/CloudletAbstract.java @@ -11,11 +11,6 @@ * @author Manoel Campos da Silva Filho */ public abstract class CloudletAbstract implements Cloudlet { - /** - * @see #getVirtualRuntime() - */ - private double virtualRuntime; - /** * The list of every {@link Datacenter} where the cloudlet has been executed. In case * it starts and finishes executing in a single datacenter, without @@ -38,7 +33,6 @@ protected CloudletAbstract(){ */ executionInDatacenterInfoList = new ArrayList<>(2); lastExecutedDatacenterIndex = NOT_ASSIGNED; - virtualRuntime = 0; } @Override @@ -69,24 +63,6 @@ protected void setLastExecutedDatacenterIndex(int lastExecutedDatacenterIndex) { protected List getExecutionInDatacenterInfoList() { return executionInDatacenterInfoList; } - - @Override - public double getVirtualRuntime() { - return virtualRuntime; - } - - @Override - public void setVirtualRuntime(double virtualRuntime) { - this.virtualRuntime = virtualRuntime; - } - - @Override - public double addVirtualRuntime(double timeToAdd) { - if(timeToAdd >= 0) { - setVirtualRuntime(virtualRuntime + timeToAdd); - } - return getVirtualRuntime(); - } /** * Internal class that keeps track of Cloudlet's movement in different diff --git a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/CloudletExecutionInfo.java b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/CloudletExecutionInfo.java index 2168f5c43..8270feee5 100644 --- a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/CloudletExecutionInfo.java +++ b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/CloudletExecutionInfo.java @@ -10,6 +10,7 @@ import org.cloudbus.cloudsim.Cloudlet.Status; import org.cloudbus.cloudsim.core.CloudSim; import org.cloudbus.cloudsim.resources.Pe; +import org.cloudbus.cloudsim.schedulers.CloudletScheduler; /** * Stores execution information about a Cloudlet submitted to a Datacenter for @@ -22,7 +23,7 @@ * placeholder for maintaining the amount of resource share allocated at various * times for simulating any scheduling using internal events. *

- * + * *

As the VM where the Cloudlet is running might migrate to another * Datacenter, each CloudletExecutionInfo object represents the data about * execution of the cloudlet when the Vm was in a given Datacenter.

@@ -34,7 +35,7 @@ public class CloudletExecutionInfo { /** - * @see #getCloudlet() + * @see #getCloudlet() */ private final Cloudlet cloudlet; @@ -53,7 +54,7 @@ public class CloudletExecutionInfo { * The time when the Cloudlet has finished completely * (not just in a given Datacenter, but finished at all). * If the cloudlet wasn't finished completely yet, - * the value is equals to {@link #NOT_FOUND}. + * the value is equals to {@link Cloudlet#NOT_ASSIGNED}. */ private double finishedTime; @@ -118,7 +119,17 @@ public class CloudletExecutionInfo { * The reservation id. */ private final int reservationId; - + + /** + * @see #getVirtualRuntime() + */ + private double virtualRuntime; + + /** + * @see #getTimeSlice() + */ + private double timeSlice; + /** * Instantiates a new CloudletExecutionInfo object upon the arrival of a Cloudlet object. * The arriving time is determined by @@ -164,6 +175,8 @@ public CloudletExecutionInfo(Cloudlet cloudlet, long startTime, int duration, in this.finishedTime = Cloudlet.NOT_ASSIGNED; // Cannot finish in this hourly slot. this.totalCompletionTime = 0.0; this.startExecTime = 0.0; + this.virtualRuntime = 0; + //In case a Cloudlet has been executed partially by some other host this.cloudletFinishedSoFar = cloudlet.getCloudletFinishedSoFar() * Consts.MILLION; @@ -516,7 +529,7 @@ public String getUid() { * Gets the time to transfer the list of files required by the Cloudlet * from the Datacenter storage (such as a Storage Area Network) * to the Vm of the Cloudlet. - * @return + * @return */ public double getFileTransferTime() { return fileTransferTime; @@ -548,25 +561,65 @@ public double getLastProcessingTime() { public void setLastProcessingTime(double lastProcessingTime) { this.lastProcessingTime = lastProcessingTime; } - + /** - * Gets the virtual runtime of the related Cloudlet. - * @return - * - * @see Cloudlet#getVirtualRuntime() + * Gets the virtual runtime (vruntime) that indicates how long the Cloudlet + * has been executing by a {@link CloudletScheduler} (in seconds). + * The default value of this attribute is zero and each scheduler + * implementation might or not set a value to such attribute + * so that the scheduler might use to perform context switch, + * preempting running Cloudlets to enable other ones to start executing. + * By this way, the attribute is just used internally by specific CloudletSchedulers. + * + * @return */ public double getVirtualRuntime(){ - return cloudlet.getVirtualRuntime(); + return virtualRuntime; + } + + /** + * Adds a given time to the {@link #getVirtualRuntime() virtual runtime}. + * + * @param timeToAdd time to add to the virtual runtime (in seconds) + * @return the new virtual runtime (in seconds) + * @pre timeToAdd >= 0 + */ + public double addVirtualRuntime(double timeToAdd) { + if(timeToAdd >= 0) { + setVirtualRuntime(virtualRuntime + timeToAdd); + } + return getVirtualRuntime(); + } - + /** - * Sets the virtual runtime of the related Cloudlet. - * @param virtualRuntime the virtual runtime to set - * - * @see Cloudlet#setVirtualRuntime(double) + * Sets the virtual runtime (vruntime) that indicates how long the Cloudlet + * has been executing by a {@link CloudletScheduler} (in seconds). This attribute is used + * just internally by specific CloudletSchedulers. + * + * @param virtualRuntime the value to set (in seconds) + * @see #getVirtualRuntime() */ public void setVirtualRuntime(double virtualRuntime){ - cloudlet.setVirtualRuntime(virtualRuntime); + this.virtualRuntime = virtualRuntime; + } + + /** + * Gets the timeslice assigned by a CloudletScheduler for a Cloudlet, that is the amount + * of time (in seconds) that such a Cloudlet will have to use the PEs + * of a Vm. Each CloudletScheduler implementation can make use of this attribute or not. + * CloudletSchedulers that use it, are in charge to compute the timeslice to + * assign to each Cloudlet. + * + * @return Cloudlet timeslice (in seconds) + * + */ + public double getTimeSlice() { + return timeSlice; + } + + public void setTimeSlice(double timeSlice) { + this.timeSlice = timeSlice; } @Override @@ -574,9 +627,16 @@ public String toString() { return String.format("Cloudlet %d", getCloudletId()); } + @Override + public boolean equals(Object obj) { + return (obj instanceof CloudletExecutionInfo) && + ((CloudletExecutionInfo)obj).getCloudletId() == this.getCloudletId(); + } + /** * A property that implements the Null Object Design Pattern for {@link CloudletExecutionInfo} * objects. */ public static final CloudletExecutionInfo NULL = new CloudletExecutionInfo(Cloudlet.NULL); + } diff --git a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerAbstract.java b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerAbstract.java index fb30c7b87..7272e9d9f 100644 --- a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerAbstract.java +++ b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerAbstract.java @@ -70,11 +70,11 @@ public abstract class CloudletSchedulerAbstract implements CloudletScheduler { * @see #getCloudletFailedList() */ private final List cloudletFailedList; - + /** * @see #getCloudletWaitingList() */ - private Collection cloudletWaitingList; + private Collection cloudletWaitingList; /** * @see #getVm() @@ -136,17 +136,17 @@ public List getCurrentMipsShare() { /** * Gets a Collection of cloudlets being executed on the VM. * It is used a Collection instead of List in order to enable different - * schedulers to define what implementation has to be used for such + * schedulers to define what implementation has to be used for such * Collection (if a ordered Set as the TreeSet or a regular List as the ArrayList). * * @return the cloudlet exec collection * @see #addCloudletToExecList(CloudletExecutionInfo) - * @see #removeCloudletFromExecListAndSetFinishTime(org.cloudbus.cloudsim.CloudletExecutionInfo) + * @see #removeCloudletFromExecListAndSetFinishTime(org.cloudbus.cloudsim.CloudletExecutionInfo) */ protected Collection getCloudletExecList() { return cloudletExecList; } - + protected final void setCloudletWaitingList(Collection cloudletWaitingList){ this.cloudletWaitingList = cloudletWaitingList; } @@ -177,7 +177,7 @@ protected List getCloudletPausedList() { public List getCloudletFinishedList() { return cloudletFinishedList; } - + protected void addCloudletToFinishedList(CloudletExecutionInfo cloudlet){ cloudletFinishedList.add(cloudlet); } @@ -194,7 +194,7 @@ protected List getCloudletFailedList() { /** * Gets a Collection of cloudlet waiting to be executed on the VM. * It is used a Collection instead of List in order to enable different - * schedulers to define what implementation has to be used for such + * schedulers to define what implementation has to be used for such * Collection (if a ordered Set as the TreeSet or a regular List as the ArrayList). * * @return the cloudlet waiting list @@ -202,7 +202,7 @@ protected List getCloudletFailedList() { protected Collection getCloudletWaitingList() { return cloudletWaitingList; } - + @Override public double cloudletSubmit(Cloudlet cloudlet) { return cloudletSubmit(cloudlet, 0.0); @@ -211,19 +211,33 @@ public double cloudletSubmit(Cloudlet cloudlet) { @Override public double cloudletSubmit(Cloudlet cl, double fileTransferTime) { CloudletExecutionInfo rcl = new CloudletExecutionInfo(cl); - if(canAddCloudletToExecutionList(rcl)){ - rcl.setCloudletStatus(Cloudlet.Status.INEXEC); - rcl.setFileTransferTime(fileTransferTime); - rcl.setLastProcessingTime(CloudSim.clock()); - addCloudletToExecList(rcl); - return fileTransferTime + (cl.getCloudletLength() / getProcessor().getCapacity()); - } - - // No enough free PEs, then add Cloudlet to the waiting queue - addCloudletToWaitingList(rcl); - return 0.0; + return processCloudletSubmit(rcl, fileTransferTime); } - + + /** + * Process a Cloudlet after it is received by the {@link #cloudletSubmit(Cloudlet, double)} method, + * that creates a {@link CloudletExecutionInfo} object to encapsulate the submitted Cloudlet + * and record execution information. + * + * @param rcl the CloudletExecutionInfo that encapsulates the Cloudlet object + * @param fileTransferTime time required to move the required files from the SAN to the VM + * @return expected finish time of this cloudlet (considering the time to transfer required + * files from the Datacenter to the Vm), or 0 if it is in a waiting queue + */ + protected double processCloudletSubmit(CloudletExecutionInfo rcl, double fileTransferTime) { + if(canAddCloudletToExecutionList(rcl)){ + rcl.setCloudletStatus(Status.INEXEC); + rcl.setFileTransferTime(fileTransferTime); + rcl.setLastProcessingTime(CloudSim.clock()); + addCloudletToExecList(rcl); + return fileTransferTime + (rcl.getCloudletLength() / getProcessor().getCapacity()); + } + + // No enough free PEs, then add Cloudlet to the waiting queue + addCloudletToWaitingList(rcl); + return 0.0; + } + /** * Adds a Cloudlet to the collection of cloudlets in execution. * @@ -232,7 +246,7 @@ public double cloudletSubmit(Cloudlet cl, double fileTransferTime) { protected void addCloudletToExecList(CloudletExecutionInfo cloudlet) { cloudlet.setCloudletStatus(Cloudlet.Status.INEXEC); cloudletExecList.add(cloudlet); - addUsedPes(cloudlet.getNumberOfPes()); + addUsedPes(cloudlet.getNumberOfPes()); } @Override @@ -276,7 +290,7 @@ public Cloudlet getCloudletToMigrate() { rcl.finalizeCloudlet(); return rcl.getCloudlet(); }; - + return getCloudletExecList().stream() .findFirst() @@ -297,10 +311,10 @@ public int getCloudletStatus(int cloudletId) { */ protected Optional findCloudletInAllLists(double cloudletId) { //Concatenate all lists into a strem - Stream> streamOfAllLists = + Stream> streamOfAllLists = Stream.of(getCloudletExecList(), getCloudletPausedList(), getCloudletWaitingList(), getCloudletFinishedList(), getCloudletFailedList()); - + //Gets all elements in each list and makes them a single full list, //returning the first Cloudlet with the given id return streamOfAllLists @@ -422,7 +436,7 @@ private Cloudlet changeStatusOfCloudletIntoList( .map(removeCloudletFromListAndUpdateItsStatus) .orElse(Cloudlet.NULL); } - + @Override public double updateVmProcessing(double currentTime, List mipsShare) { setCurrentMipsShare(mipsShare); @@ -432,9 +446,9 @@ public double updateVmProcessing(double currentTime, List mipsShare) { return Double.MAX_VALUE; } - updateCloudletsProcessing(currentTime); + updateCloudletsProcessing(currentTime); removeFinishedCloudletsFromExecutionList(); - moveNextCloudletsFromWaitingToExecList(); + moveNextCloudletsFromWaitingToExecList(); double nextEvent = getEstimatedFinishTimeOfSoonerFinishingCloudlet(currentTime); setPreviousTime(currentTime); @@ -521,11 +535,11 @@ protected long cloudletExecutionTotalLengthForElapsedTime(CloudletExecutionInfo actualProcessingTime = timeSpan(currentTime); double executedInstructions = - (processor.getAvailableMipsByPe() * rcl.getNumberOfPes() * + (processor.getAvailableMipsByPe() * rcl.getNumberOfPes() * actualProcessingTime * Consts.MILLION); Log.println(Log.Level.DEBUG, getClass(), currentTime, "Cloudlet: %d Processing time: %.2f Last processed time: %.2f Actual process time: %.2f MI so far: %d", - rcl.getCloudletId(), currentTime, rcl.getLastProcessingTime(), + rcl.getCloudletId(), currentTime, rcl.getLastProcessingTime(), actualProcessingTime, rcl.getCloudlet().getCloudletFinishedSoFar()); return (long)executedInstructions; @@ -541,7 +555,7 @@ protected long cloudletExecutionTotalLengthForElapsedTime(CloudletExecutionInfo */ private boolean hasCloudletFileTransferTimePassed(CloudletExecutionInfo rcl, double currentTime) { return rcl.getFileTransferTime() == 0 || - currentTime - rcl.getLastProcessingTime() > rcl.getFileTransferTime() || + currentTime - rcl.getLastProcessingTime() > rcl.getFileTransferTime() || rcl.getCloudlet().getCloudletFinishedSoFar() > 0; } @@ -593,9 +607,10 @@ protected void removeCloudletFromExecListAndSetFinishTime(CloudletExecutionInfo * Removes a Cloudlet from the list of cloudlets in execution. * * @param cloudlet the Cloudlet to be removed - * @return true if the Cloudlet was found and remove from the execution list. + * @return true if the Cloudlet was found and remove from the execution list. */ protected boolean removeCloudletFromExecList(CloudletExecutionInfo cloudlet) { + removeUsedPes(cloudlet.getNumberOfPes()); return cloudletExecList.remove(cloudlet); } @@ -657,16 +672,16 @@ protected double getEstimatedFinishTimeOfCloudlet(CloudletExecutionInfo rcl, dou * to the execution list in order to start executing them. * While there is enough free PEs, the method try to find a suitable * Cloudlet in the list, until it reaches the end of such a list. - * + * * The method might also exchange some cloudlets in the execution list * with some in the waiting list. Thus, some running - * cloudlets may be preempted to give opportunity to previously waiting + * cloudlets may be preempted to give opportunity to previously waiting * cloudlets to run. This is a process called context switch. * However, each CloudletScheduler implementation decides how * such a process is implemented. For instance, Space-Shared schedulers may just * perform context switch just after currently running Cloudlets completely * finish executing. - * + * *

This method is called internally by the {@link #updateVmProcessing(double, java.util.List)} one.

* * @pre currentTime >= 0 @@ -709,9 +724,9 @@ protected Optional findSuitableWaitingCloudletToStartExec .filter(this::isThereEnoughFreePesForCloudlet) .findFirst() .map(changeCloudletStatusToExecAndReturnIt); - + optional.ifPresent(this::removeCloudletFromWaitingList); - + return optional; } @@ -738,31 +753,31 @@ public void setVm(Vm vm) { /** * Gets the number of currently used {@link Pe}'s. - * @return - * + * @return + * * @todo The number of free and used PEs should be inside the Processor class. - * However, a new instance of the class is created every time the - * updateVmProcessing is called, what will make the information about the + * However, a new instance of the class is created every time the + * updateVmProcessing is called, what will make the information about the * number of usedPes to be lost. */ public int getUsedPes() { return usedPes; } - + /** * Gets the number of PEs currently not being used. - * @return + * @return */ protected int getFreePes() { return getProcessor().getNumberOfPes() - getUsedPes(); - } - + } + /** * Adds a given number of PEs to the amount of currently used PEs. * * @param usedPesToAdd number of PEs to add to the amount of used PEs */ - protected void addUsedPes(int usedPesToAdd) { + private void addUsedPes(int usedPesToAdd) { this.usedPes += usedPesToAdd; } @@ -771,9 +786,9 @@ protected void addUsedPes(int usedPesToAdd) { * * @param usedPesToRemove number of PEs to subtract from the amount of used PEs */ - protected void removeUsedPes(int usedPesToRemove) { + private void removeUsedPes(int usedPesToRemove) { this.usedPes -= usedPesToRemove; } - + } diff --git a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerCompletelyFair.java b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerCompletelyFair.java index dc8c6d36d..89c803ca1 100644 --- a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerCompletelyFair.java +++ b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerCompletelyFair.java @@ -3,21 +3,25 @@ import java.util.Collection; import org.cloudbus.cloudsim.Cloudlet; import org.cloudbus.cloudsim.CloudletExecutionInfo; +import org.cloudbus.cloudsim.core.CloudSim; import org.cloudbus.cloudsim.resources.Pe; import java.util.List; import java.util.Set; import java.util.TreeSet; +import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.stream.Stream; + import static java.util.stream.Collectors.toList; import org.cloudbus.cloudsim.Log; /** * A Completely Fair Scheduler (CFS) * that is the default scheduler used for most tasks on recent Linux Kernel. It is a time-shared - * scheduler that shares CPU cores between running applications by preempting + * scheduler that shares CPU cores between running applications by preempting * them after a time period (timeslice) to allow other ones to start executing - * during their timeslices. + * during their timeslices. * *

* It is a basic implementation that covers that covers the following features: @@ -38,9 +42,9 @@ * is the process of removing an application that is using a CPU core * to allow another one to start executing. This is the task preemption * process that allows a core to be shared between several applications. - * + * *

Since this scheduler does not consider - * context switch + * context switch * overhead, there is only one runqueue for all CPU cores because * each application is not in fact assigned to a specific CPU core. * The scheduler just computes how much computing power (in MIPS) @@ -57,7 +61,7 @@ * The implementation was based on the book of Robert Love: Linux Kernel Development, 3rd ed. Addison-Wesley, 2010 * and some other references listed below. *

- * + * *

* O scheduler é baseado no time-shared mas deve funcionar de maneira diferente. *

    @@ -65,35 +69,35 @@ * * A getCloudletExecutionList deve representar * apenas as cloudlets que estão executando de fato no momento atual. - * A diferença é que no construtor, tal lista deve ser instanciada como um + * A diferença é que no construtor, tal lista deve ser instanciada como um * {@link Set} para manter a ordem dos elementos de acordo com o vruntime. * *
  • - * + * *
  • * Adicionar vruntime ao CloudletExecutionInfo para permitir * ordenar a execution list por ele. Isso vai facilitar remover uma cloudlet - * desta lista, considerando aquela que tiver o maior vruntime (que já rodou mais + * desta lista, considerando aquela que tiver o maior vruntime (que já rodou mais * que as outras). * *
  • - * + * *
  • A lista pode ser ordenada de forma descrescente para * permitir usar stream pra pegar o primeiro elemento.
  • - * + * *
  • A waiting list é que será de fato a runqueue, contendo * a lista de cloudlets que devem rodar em seguida (conforme definição da wikipedia).
  • - * + * *
  • Ela, diferente do CloudletSchedulerTimeShared, * deve sim ter cloudlets. O CFS deve de fato implementar a preempção, * removendo processos na execution list para dar a vez * (mesmo que tais processos não tenhma terminado) para outros processos * na runqueue (waiting list).
  • - * + * *
  • A waiting list sim é que deve ser implementada como uma Red-Black tree.
  • *
*

- * + * * * @author Manoel Campos da Silva Filho * @@ -108,7 +112,7 @@ public final class CloudletSchedulerCompletelyFair extends CloudletSchedulerTime * @see #getMininumGranularity() */ private int mininumGranularity = 2; //The default value for linux schedueler is 0.001 s - + /** * @see #getLatency() */ @@ -119,21 +123,6 @@ public CloudletSchedulerCompletelyFair(){ setCloudletExecList(new TreeSet<>(this::executingCloudletsComparator)); setCloudletWaitingList(new TreeSet<>(this::waitingCloudletsComparator)); } - - /** - * A comparator used to descendingly sort running Cloudlets into the execution list - * based on their virtual runtime. By this way, the Cloudlets in the beginning - * of this list will be that ones which have run the most and thus, are the - * first to be preempted to allow Cloudlets in the waiting list to run. - * - * @param c1 first Cloudlet to compare - * @param c2 second Cloudlet to compare - * @return a negative value if c2 is lower than c1, zero if they are equals, - * a positive value if c2 is greater than c1 - */ - private int executingCloudletsComparator(CloudletExecutionInfo c1, CloudletExecutionInfo c2){ - return (int)(c2.getCloudlet().getVirtualRuntime() - c1.getCloudlet().getVirtualRuntime()); - } /** * A comparator used to ascendingly sort Cloudlets into the waiting list @@ -141,14 +130,46 @@ private int executingCloudletsComparator(CloudletExecutionInfo c1, CloudletExecu * of this list will be that ones which have run the least and have to be * prioritized when getting Cloudlets from this list to add to the execution * list. - * + * * @param c1 first Cloudlet to compare * @param c2 second Cloudlet to compare * @return a negative value if c1 is lower than c2, zero if they are equals, * a positive value if c1 is greater than c2 */ private int waitingCloudletsComparator(CloudletExecutionInfo c1, CloudletExecutionInfo c2){ - return (int)(c1.getCloudlet().getVirtualRuntime() - c2.getCloudlet().getVirtualRuntime()); + if(c1.equals(c2)) + return 0; + + double diff = c1.getVirtualRuntime() - c2.getVirtualRuntime(); + + /*If the difference between the virtual runtime is equal to zero, the comparator considers + * that the objects are the same and this causes issues when adding or removing + * elements into a TreeSet that accepts just unique objects. + * By this way, if the diff is zero, uses the priorities difference. + * If the diff is yet zero, uses the IDs difference.*/ + if(diff == 0) + diff = c1.getCloudlet().getPriority()-c2.getCloudlet().getPriority(); + if(diff == 0) + diff = c1.getCloudletId()-c2.getCloudletId(); + + return (int)diff; + } + + /** + * A comparator used to descendingly sort running Cloudlets into the execution list + * based on their virtual runtime. By this way, the Cloudlets in the beginning + * of this list will be that ones which have run the most and thus, are the + * first to be preempted to allow Cloudlets in the waiting list to run. + * + * @param c1 first Cloudlet to compare + * @param c2 second Cloudlet to compare + * @return a negative value if c2 is lower than c1, zero if they are equals, + * a positive value if c2 is greater than c1 + */ + private int executingCloudletsComparator(CloudletExecutionInfo c1, CloudletExecutionInfo c2){ + /*Calling the other comparator just inverting the parameters order will change the sorting + order.*/ + return waitingCloudletsComparator(c2, c1); } /** @@ -167,7 +188,7 @@ private int waitingCloudletsComparator(CloudletExecutionInfo c1, CloudletExecuti * frequent CPU context switches (that reduces CPU throughput). * However, CPU context switch overhead is not being considered. *

- * @return + * @return */ public int getLatency() { return latency; @@ -186,17 +207,17 @@ public void setLatency(int latency) { * of time (in seconds) that such a Cloudlet will have to use the PEs, * considering all Cloudlets in the {@link #getCloudletExecList() executing list}. * - *

The timeslice is computed considering the {@link #getCloudletWeight(Cloudlet) Cloudlet weight} + *

The timeslice is computed considering the {@link #getCloudletWeight(CloudletExecutionInfo) Cloudlet weight} * and what it represents in percentage of the {@link #getWeightSumOfRunningCloudlets() weight sum} of * all cloudlets in the execution list.

* * @param cloudlet Cloudlet to get the timeslice * @return Cloudlet timeslice (in seconds) * - * @see #getCloudletWeight(Cloudlet) + * @see #getCloudletWeight(CloudletExecutionInfo) * @see #getWeightSumOfRunningCloudlets() */ - protected double computeCloudletTimeSlice(Cloudlet cloudlet){ + protected double computeCloudletTimeSlice(CloudletExecutionInfo cloudlet){ final double timeslice = getLatency() * getCloudletWeightPercentBetweenAllCloudlets(cloudlet); return Math.min(timeslice, getMininumGranularity()); } @@ -211,8 +232,8 @@ protected double computeCloudletTimeSlice(Cloudlet cloudlet){ * @param cloudlet Cloudlet to get the nice value * @return the cloudlet niceness */ - protected double getCloudletNiceness(Cloudlet cloudlet){ - return -cloudlet.getPriority(); + protected double getCloudletNiceness(CloudletExecutionInfo cloudlet){ + return -cloudlet.getCloudlet().getPriority(); } /** @@ -220,7 +241,7 @@ protected double getCloudletNiceness(Cloudlet cloudlet){ * defined based on its niceness. As greater is the weight, * more time the Cloudlet will have to use the PEs. * - *

As the {@link #computeCloudletTimeSlice(Cloudlet) timelice} assigned to a Cloudlet to use the CPU is defined + *

As the {@link #computeCloudletTimeSlice(CloudletExecutionInfo) timelice} assigned to a Cloudlet to use the CPU is defined * exponentially instead of linearly according to its niceness, * this method is used as the base to correctly compute the timeslice. *

@@ -228,9 +249,9 @@ protected double getCloudletNiceness(Cloudlet cloudlet){ * * @param cloudlet Cloudlet to get the weight to use PEs * @return the cloudlet weight to use PEs - * @see #getCloudletNiceness(Cloudlet) + * @see #getCloudletNiceness(CloudletExecutionInfo) */ - protected double getCloudletWeight(Cloudlet cloudlet){ + protected double getCloudletWeight(CloudletExecutionInfo cloudlet){ return 1024.0/(Math.pow(1.25, getCloudletNiceness(cloudlet))); } @@ -241,7 +262,7 @@ protected double getCloudletWeight(Cloudlet cloudlet){ * @param cloudlet Cloudlet to get its weight percentage * @return the cloudlet weight percentage between all Cloudlets in the execution list */ - private double getCloudletWeightPercentBetweenAllCloudlets(Cloudlet cloudlet) { + private double getCloudletWeightPercentBetweenAllCloudlets(CloudletExecutionInfo cloudlet) { return getCloudletWeight(cloudlet) / getWeightSumOfRunningCloudlets(); } @@ -250,7 +271,6 @@ private double getCloudletWeightPercentBetweenAllCloudlets(Cloudlet cloudlet) { */ private double getWeightSumOfRunningCloudlets() { return getCloudletExecList().stream() - .map(CloudletExecutionInfo::getCloudlet) .mapToDouble(this::getCloudletWeight) .sum(); } @@ -266,7 +286,7 @@ private double getWeightSumOfRunningCloudlets() { * By this way, it just ensures that each Cloudlet will not use the CPU * for less than the minimum granularity.

* - * @return + * @return * @see #getLatency() */ public int getMininumGranularity() { @@ -286,21 +306,28 @@ public void setMininumGranularity(int mininumGranularity) { /** * {@inheritDoc} - * + * *

It also sets the initial virtual runtime for the given Cloudlet * in order to define how long the Cloudlet has executed yet.
- * - * See {@link #computeCloudletInitialVirtualRuntime(org.cloudbus.cloudsim.Cloudlet)} + * + * See {@link #computeCloudletInitialVirtualRuntime(org.cloudbus.cloudsim.CloudletExecutionInfo)} * for more details.

- * - * @param cl {@inheritDoc} + * + * @param rcl {@inheritDoc} * @param fileTransferTime {@inheritDoc} */ @Override - public double cloudletSubmit(Cloudlet cl, double fileTransferTime) { - cl.setVirtualRuntime(computeCloudletInitialVirtualRuntime(cl)); - Log.printFormattedLine("\tCloudlet %d submitted VRuntime: %16.2f sec Timeslice: %.2f sec", cl.getId(), cl.getVirtualRuntime(), computeCloudletTimeSlice(cl)); - double result = super.cloudletSubmit(cl, fileTransferTime); + public double processCloudletSubmit(CloudletExecutionInfo rcl, double fileTransferTime) { + rcl.setVirtualRuntime(computeCloudletInitialVirtualRuntime(rcl)); + rcl.setTimeSlice(computeCloudletTimeSlice(rcl)); + if(rcl.getCloudletId() == 5) { + System.out.println("\tCloudlets submitted:"); + Stream.concat(getCloudletExecList().stream(), getCloudletWaitingList().stream()) + .forEach(c-> System.out.printf("\t\t%d vruntime: %16.2f timeslice: %.2f\n", + c.getCloudletId(), c.getVirtualRuntime(), c.getTimeSlice())); + + } + double result = super.processCloudletSubmit(rcl, fileTransferTime); return result; } @@ -312,12 +339,11 @@ public double cloudletSubmit(Cloudlet cl, double fileTransferTime) { */ @Override public double updateVmProcessing(double currentTime, List mipsShare) { - super.updateVmProcessing(currentTime, mipsShare); + super.updateVmProcessing(currentTime, mipsShare); double nextExpiringTimeSlice = getCloudletExecList().stream() - .map(CloudletExecutionInfo::getCloudlet) - .mapToDouble(this::computeCloudletTimeSlice) + .mapToDouble(CloudletExecutionInfo::getTimeSlice) .min().orElse(Double.MAX_VALUE); - System.out.println("\tNext expiring timeslice: "+nextExpiringTimeSlice); + System.out.printf("\tTime %.2f updateVmProcessing - Next expiring timeslice: %.2f\n", currentTime, nextExpiringTimeSlice); return nextExpiringTimeSlice; } @@ -333,12 +359,10 @@ public void updateCloudletProcessing(CloudletExecutionInfo rcl, double currentTi } double cloudletTimeSpan = currentTime - rcl.getLastProcessingTime(); - super.updateCloudletProcessing(rcl, currentTime); - - System.out.printf("\tCloudlet %d time span: %f - curTime %f last %f\n", - rcl.getCloudletId(), cloudletTimeSpan, - currentTime, rcl.getLastProcessingTime()); - rcl.getCloudlet().addVirtualRuntime(cloudletTimeSpan); + super.updateCloudletProcessing(rcl, currentTime); + + //System.out.printf("\tCloudlet %d time span: %f - curTime %f last %f vruntime %f\n", rcl.getCloudletId(), cloudletTimeSpan, currentTime, rcl.getLastProcessingTime(), rcl.getVirtualRuntime()); + rcl.addVirtualRuntime(cloudletTimeSpan); } /** @@ -346,12 +370,12 @@ public void updateCloudletProcessing(CloudletExecutionInfo rcl, double currentTi * This virtual runtime is updated as long as the Cloudlet is executed. * The initial value is negative to indicate the Cloudlet hasn't started * executing yet. The virtual runtime is computed based on the Cloudlet priority. - * - * @param cloudlet Cloudlet to compute the initial virtual runtime + * + * @param rcl Cloudlet to compute the initial virtual runtime * @return the computed initial virtual runtime as a negative value * to indicate that the Cloudlet hasn't started executing yet */ - private double computeCloudletInitialVirtualRuntime(Cloudlet cloudlet) { + private double computeCloudletInitialVirtualRuntime(CloudletExecutionInfo rcl) { /* A negative virtual runtime indicates the cloudlet has never been executed yet. This math was used just to ensure that the first added cloudlets @@ -359,7 +383,7 @@ private double computeCloudletInitialVirtualRuntime(Cloudlet cloudlet) { If all cloudlets have the same priority, the first addedd will start executing first. */ - + /* Inverses the Cloudlet ID dividing the Integer.MAX_VALUE by it, because the ID is in fact int. This will make that the lower @@ -369,21 +393,21 @@ private double computeCloudletInitialVirtualRuntime(Cloudlet cloudlet) { can be understood as resulting in "higher negative" values, that is, extreme negative values. */ - double inverseOfCloudletId = Integer.MAX_VALUE/(cloudlet.getId()+1.0); + double inverseOfCloudletId = Integer.MAX_VALUE/(rcl.getCloudletId()+1.0); - return -Math.abs(cloudlet.getPriority() + inverseOfCloudletId); + return -Math.abs(rcl.getCloudlet().getPriority() + inverseOfCloudletId); } /** * Checks if a Cloudlet can be submitted to the execution list. - * + * * This scheduler, different from its time-shared parent, only adds * submitted Cloudlets to the execution list if there is enough free PEs. * Otherwise, such Cloudlets are added to the waiting list, * really enabling time-sharing between running Cloudlets. * By this way, some Cloudlets have to be preempted to allow other ones * to be executed. - * + * * @param cloudlet {@inheritDoc} * @return {@inheritDoc} */ @@ -391,23 +415,23 @@ private double computeCloudletInitialVirtualRuntime(Cloudlet cloudlet) { public boolean canAddCloudletToExecutionList(CloudletExecutionInfo cloudlet) { return isThereEnoughFreePesForCloudlet(cloudlet); } - + @Override protected boolean removeCloudletFromWaitingList(CloudletExecutionInfo cloudlet) { - return super.removeCloudletFromWaitingList(cloudlet); + return super.removeCloudletFromWaitingList(cloudlet); } - + /** * {@inheritDoc} - * + * *

Prior to start executing, a Cloudlet is added to this Collection. * When the Cloudlet vruntime reaches its timeslice (the amount of time * it can use the CPU), it is removed from this Collection and added * back to the {@link #getCloudletWaitingList()}.

- * - *

The sum of the PEs of Cloudlets into this Collection cannot exceeds + * + *

The sum of the PEs of Cloudlets into this Collection cannot exceeds * the number of PEs available for the scheduler. If the sum of PEs of such Cloudlets - * is less than the number of existing PEs, there are + * is less than the number of existing PEs, there are * idle PEs. Since the CPU context switch overhead is not regarded * in this implementation and as result, it doesn't matter which * PEs are running which Cloudlets, there is not such information @@ -417,35 +441,35 @@ protected boolean removeCloudletFromWaitingList(CloudletExecutionInfo cloudlet) * at the 3º position in this Collection, indicating that now it is using * the 3º and 4º Pe, which doesn't change anything. In real schedulers, * usually a process is pinned to a specific set of cores until it - * finishes executing, to avoid the overhead of changing processes from + * finishes executing, to avoid the overhead of changing processes from * a run queue to another unnecessarily.

- * - * @return + * + * @return */ @Override public Collection getCloudletExecList() { - return super.getCloudletExecList(); + return super.getCloudletExecList(); } /** * Gets a read-only {@link TreeSet} (a implementation of a Red-Black Tree) that stores the list of Cloudlets - * that are waiting to run, the so called - * run queue. + * that are waiting to run, the so called + * run queue. * Each key in this map is the virtual runtime (vruntime), * which indicates the amount of time the Cloudlet has run. * This runtime increases as the Cloudlet executes, what makes * it to change its position inside the map. * Each value represents a Cloudlet * running into a group of PE (defined by the number of - * PEs the Cloudlet requires). - * + * PEs the Cloudlet requires). + * *

- * NOTE: Different from real implementations, this scheduler uses just one run queue + * NOTE: Different from real implementations, this scheduler uses just one run queue * for all processor cores (PEs). Since CPU context switch is not concerned, * there is no point in using different run queues. *

- * - * @return + * + * @return */ @Override public Collection getCloudletWaitingList() { @@ -457,53 +481,68 @@ public Collection getCloudletWaitingList() { * equals to its allocated time slice and preempt them and gets * the most priority Cloudlets in the waiting list (that is those ones * in the beginning of the list). - * - * @see #preemptExecCloudletsWithExpiredVRuntimeAndMoveToWaitingList() + * + * @see #preemptExecCloudletsWithExpiredVRuntimeAndMoveToWaitingList() */ @Override protected void moveNextCloudletsFromWaitingToExecList() { - preemptExecCloudletsWithExpiredVRuntimeAndMoveToWaitingList(); + List preemptedCloudlets = preemptExecCloudletsWithExpiredVRuntimeAndMoveToWaitingList(); super.moveNextCloudletsFromWaitingToExecList(); + + /*After preempted Cloudets are moved to the waitingn list + and next Cloudlets on the beginning of this list are moved + to the execution list, the virtual runtime of these preempted Cloudlets + is reseted so that they can compete with other waiting Cloudlets to use + the processor again.*/ + for(CloudletExecutionInfo c: preemptedCloudlets) { + c.setVirtualRuntime(computeCloudletInitialVirtualRuntime(c)); + } } /** * Checks which Cloudlets in the execution list have an expired virtual - * runtime (that have reached the execution time slice) and move + * runtime (that have reached the execution time slice) and move * preempt its execution, moving them to the waiting list. - * + * + * @return The list of preempted Cloudlets, that were removed from the execution list + * and must have their virtual runtime reseted after the next cloudlets are put into + * the execution list. + * */ - private void preemptExecCloudletsWithExpiredVRuntimeAndMoveToWaitingList() { - Predicate cloudletThatVirtualTimeHasReachedItsTimeSlice = - c -> c.getVirtualRuntime() >= computeCloudletTimeSlice(c.getCloudlet()); - + private List preemptExecCloudletsWithExpiredVRuntimeAndMoveToWaitingList() { + Predicate cloudletThatVirtualRuntimeHasReachedItsTimeSlice = + c -> c.getVirtualRuntime() >= c.getTimeSlice(); + + Consumer printCloudlet = + c->System.out.printf("\t\tid %d vruntime %.2f timeslice: %.2f\n", + c.getCloudletId(), c.getVirtualRuntime(), c.getTimeSlice()); + List expiredVRuntimeCloudlets = getCloudletExecList().stream() - .filter(cloudletThatVirtualTimeHasReachedItsTimeSlice) + .filter(cloudletThatVirtualRuntimeHasReachedItsTimeSlice) .collect(toList()); if(!getCloudletExecList().isEmpty()){ - System.out.print("\tRunning cloudlets vruntime: "); - getCloudletExecList().stream() - .map(CloudletExecutionInfo::getVirtualRuntime) - .forEach(c->System.out.print(c+" ")); + System.out.printf("\tTime %.2f - Running cloudlets: \n", CloudSim.clock()); + getCloudletExecList().stream().forEach(printCloudlet); System.out.println(); } - + if(!expiredVRuntimeCloudlets.isEmpty()){ - System.out.print("\tExpired cloudlets: "); - expiredVRuntimeCloudlets.stream() - .map(CloudletExecutionInfo::toString) - .forEach(c->System.out.print(c+" ")); + System.out.println("\tExpired cloudlets: "); + expiredVRuntimeCloudlets.stream().forEach(printCloudlet); System.out.println(); } - + for(CloudletExecutionInfo c: expiredVRuntimeCloudlets) { - //Virtual runtime is reseted so that preempted Cloudlets can return to waiting list - c.setVirtualRuntime(computeCloudletInitialVirtualRuntime(c.getCloudlet())); - removeCloudletFromExecList(c); + if(!removeCloudletFromExecList(c)){ + System.out.printf("Cloudlet %d was not removed from exec list\n", c.getCloudletId()); + } addCloudletToWaitingList(c); } + + return expiredVRuntimeCloudlets; } - + } diff --git a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerSpaceShared.java b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerSpaceShared.java index 8c44b9745..0b4a60f19 100644 --- a/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerSpaceShared.java +++ b/cloudsim-plus/src/main/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerSpaceShared.java @@ -41,12 +41,6 @@ public CloudletSchedulerSpaceShared() { super(); } - @Override - public void cloudletFinish(CloudletExecutionInfo rcl) { - super.cloudletFinish(rcl); - removeUsedPes(rcl.getNumberOfPes()); - } - @Override public double cloudletResume(int cloudletId) { Optional optional = findCloudletInList(cloudletId, getCloudletPausedList()); @@ -134,7 +128,7 @@ public List getCurrentRequestedMips() { *

It doesn't consider the given Cloudlet because the scheduler * ensures that the Cloudlet will use all required PEs until it * finishes executing.

- * + * * @param rcl {@inheritDoc} * @param mipsShare {@inheritDoc} * @return {@inheritDoc} @@ -181,7 +175,7 @@ public double getCurrentRequestedUtilizationOfBw() { * * @param cloudlet {@inheritDoc} * @return {@inheritDoc} - */ + */ @Override public boolean canAddCloudletToExecutionList(CloudletExecutionInfo cloudlet) { return isThereEnoughFreePesForCloudlet(cloudlet); diff --git a/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/CloudletTest.java b/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/CloudletTest.java index 27c3bf2c7..6a81fdda6 100644 --- a/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/CloudletTest.java +++ b/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/CloudletTest.java @@ -41,7 +41,7 @@ public void testNullObject(){ assertEquals(0, Cloudlet.NULL.getCloudletFinishedSoFar(), 0); assertEquals(0, Cloudlet.NULL.getCloudletFinishedSoFar(), 0); assertEquals("", Cloudlet.NULL.getCloudletHistory()); - assertEquals(0, Cloudlet.NULL.getId(), 0); + assertEquals(-1, Cloudlet.NULL.getId()); assertEquals(0, Cloudlet.NULL.getCloudletLength(), 0); assertEquals(0, Cloudlet.NULL.getCloudletOutputSize(), 0); assertEquals(Cloudlet.Status.FAILED, Cloudlet.NULL.getStatus()); @@ -56,11 +56,11 @@ public void testNullObject(){ assertEquals(0, Cloudlet.NULL.getNumberOfPes(), 0); assertEquals(0, Cloudlet.NULL.getProcessingCost(), 0); assertTrue(Cloudlet.NULL.getRequiredFiles().isEmpty()); - assertEquals(0, Cloudlet.NULL.getReservationId(), 0); - assertEquals(0, Cloudlet.NULL.getDatacenterId(), 0); + assertEquals(-1, Cloudlet.NULL.getReservationId()); + assertEquals(-1, Cloudlet.NULL.getDatacenterId()); assertEquals(0, Cloudlet.NULL.getDatacenterArrivalTime(), 0); assertEquals(0, Cloudlet.NULL.getSubmissionTime(0), 0); - assertEquals(0, Cloudlet.NULL.getUserId(), 0); + assertEquals(-1, Cloudlet.NULL.getUserId()); assertSame(UtilizationModel.NULL, Cloudlet.NULL.getUtilizationModelBw()); assertSame(UtilizationModel.NULL, Cloudlet.NULL.getUtilizationModelCpu()); assertSame(UtilizationModel.NULL, Cloudlet.NULL.getUtilizationModelRam()); @@ -68,7 +68,7 @@ public void testNullObject(){ assertEquals(0, Cloudlet.NULL.getUtilizationOfCpu(0), 0); assertEquals(0, Cloudlet.NULL.getUtilizationOfRam(0), 0); Cloudlet.NULL.setVmId(100); - assertEquals(Cloudlet.NOT_ASSIGNED, Cloudlet.NULL.getVmId(), 0); + assertEquals(-1, Cloudlet.NULL.getVmId()); assertEquals(0, Cloudlet.NULL.getWaitingTime(), 0); assertEquals(0, Cloudlet.NULL.getWallClockTimeInLastExecutedDatacenter(), 0); assertEquals(0, Cloudlet.NULL.getWallClockTime(0), 0); @@ -90,16 +90,16 @@ public void testNullObject(){ assertSame(EventListener.NULL, Cloudlet.NULL.getOnCloudletFinishEventListener()); Cloudlet.NULL.setUserId(10); - assertEquals(0, Cloudlet.NULL.getUserId(), 0); + assertEquals(-1, Cloudlet.NULL.getUserId()); Cloudlet.NULL.setSubmissionDelay(10); assertEquals(0, Cloudlet.NULL.getSubmissionDelay(), 0); - assertEquals(0, Cloudlet.NULL.getDatacenterId(), 0); + assertEquals(-1, Cloudlet.NULL.getDatacenterId()); assertEquals(0, Cloudlet.NULL.getCostPerSec(), 0); Cloudlet.NULL.assignCloudletToDatacenter(1, 1, 1); - assertEquals(0, Cloudlet.NULL.getDatacenterId(), 0); + assertEquals(-1, Cloudlet.NULL.getDatacenterId()); assertEquals(0, Cloudlet.NULL.getCostPerSec(), 0); assertEquals(0, Cloudlet.NULL.getCostPerBw(), 0); diff --git a/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerSpaceSharedTest.java b/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerSpaceSharedTest.java index fca113f6c..c3999cb9f 100644 --- a/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerSpaceSharedTest.java +++ b/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerSpaceSharedTest.java @@ -22,7 +22,7 @@ @PrepareForTest({CloudSim.class}) //to intercept and mock static method calls public class CloudletSchedulerSpaceSharedTest { private static final double SCHEDULER_MIPS = 1000; - + @Test public void testCloudletFinish_CheckCloudletWasSetToFinished() { final double clockMethodReturnValue = 0; @@ -41,7 +41,7 @@ public void testCloudletFinish_CloudletMovedToFinishList() { final double clockMethodReturnValue = 0; final int expectedClockCalls = 3; CloudSimMocker.build(mocker -> mocker.clock(clockMethodReturnValue, expectedClockCalls)); - CloudletExecutionInfo rcl = + CloudletExecutionInfo rcl = new CloudletExecutionInfo(CloudletSimpleTest.createCloudlet(0, 1000, 1)); CloudletSchedulerSpaceShared instance = new CloudletSchedulerSpaceShared(); instance.cloudletFinish(rcl); @@ -49,22 +49,6 @@ public void testCloudletFinish_CloudletMovedToFinishList() { CloudSimMocker.verify(); } - @Test - public void testCloudletFinish_CheckNumberOfUsedPes() { - final int cloudletPes = 1; - final long cloudletLen = 1000; - final double clockMethodReturnValue = 0; - final int expectedClockCalls = 3; - CloudSimMocker.build(mocker -> mocker.clock(clockMethodReturnValue, expectedClockCalls)); - CloudletExecutionInfo rcl = - new CloudletExecutionInfo( - CloudletSimpleTest.createCloudlet0(cloudletLen, cloudletPes)); - CloudletSchedulerSpaceShared instance = new CloudletSchedulerSpaceShared(); - instance.cloudletFinish(rcl); - instance.addUsedPes(cloudletPes); - assertEquals(0, instance.getUsedPes()); - } - @Test public void testRemoveCloudletFromExecList_NotInExecList() { CloudletExecutionInfo cloudlet = new CloudletExecutionInfo(Cloudlet.NULL); @@ -101,11 +85,11 @@ public void testCloudletResume_NotEnoughPesToResume() { new CloudletExecutionInfo( CloudletSimpleTest.createCloudletWithOnePe(i))); } - + instance.getCloudletPausedList().add( new CloudletExecutionInfo( CloudletSimpleTest.createCloudlet(numberOfCloudlets, cloudletPes))); - + double expResult = 0.0; double result = instance.cloudletResume(cloudletId); assertEquals(expResult, result, 0.0); @@ -116,14 +100,14 @@ public void testCloudletSubmit_VerifyIfCloudletWasAddedToExecListByCheckingSubmi final int pes = 1; final long cloudletLen = (long)SCHEDULER_MIPS; final double fileTransferTime = 0.0; - + Cloudlet cloudlet = CloudletSimpleTest.createCloudlet0(cloudletLen, pes); CloudletSchedulerSpaceShared instance = new CloudletSchedulerSpaceShared(); List mipsList = CloudletSchedulerUtil.createMipsList(pes, SCHEDULER_MIPS); instance.setCurrentMipsShare(mipsList); //number of expected seconds to finish the cloudlet - double expResult = 1.0; + double expResult = 1.0; double result = instance.cloudletSubmit(cloudlet, fileTransferTime); assertEquals(expResult, result, 0.0); } @@ -133,7 +117,7 @@ public void testCloudletSubmit_VerifyIfCloudletWasAddedToExecListByCheckingSuchL final int pes = 1; final long cloudletLen = (long)SCHEDULER_MIPS; final double fileTransferTime = 0.0; - + Cloudlet cloudlet = CloudletSimpleTest.createCloudlet0(cloudletLen, pes); CloudletSchedulerSpaceShared instance = new CloudletSchedulerSpaceShared(); List mipsList = CloudletSchedulerUtil.createMipsList(pes, SCHEDULER_MIPS); @@ -148,7 +132,7 @@ public void testCloudletSubmit_WhenThereAreMoreCloudletsThanPes_VerifyThatSubmit final int pes = 1; final long cloudletLen = (long)SCHEDULER_MIPS; final double fileTransferTime = 0.0; - + Cloudlet cloudlet0 = CloudletSimpleTest.createCloudlet(0, cloudletLen, pes); CloudletSchedulerSpaceShared instance = new CloudletSchedulerSpaceShared(); List mipsList = CloudletSchedulerUtil.createMipsList(pes, SCHEDULER_MIPS); @@ -166,7 +150,7 @@ public void testCloudletSubmit_WhenThereAreMoreCloudletsThanPes_VerifyThatSubmit final int pes = 1; final long cloudletLen = (long)SCHEDULER_MIPS; final double fileTransferTime = 0.0; - + Cloudlet cloudlet0 = CloudletSimpleTest.createCloudlet(0, cloudletLen, pes); CloudletSchedulerSpaceShared instance = new CloudletSchedulerSpaceShared(); List mipsList = CloudletSchedulerUtil.createMipsList(pes, SCHEDULER_MIPS); @@ -196,8 +180,8 @@ public void testIsThereEnoughFreePesForCloudlet_WhenThereAreOnePesAndOneAlreadyR instance.setCurrentMipsShare(CloudletSchedulerUtil.createUnitaryMipsList(SCHEDULER_MIPS)); Cloudlet cloudlet0 = CloudletSimpleTest.createCloudlet(0, cloudletPes); instance.cloudletSubmit(cloudlet0, fileTransferTime); - - CloudletExecutionInfo cloudlet1 = + + CloudletExecutionInfo cloudlet1 = new CloudletExecutionInfo(CloudletSimpleTest.createCloudlet(1, cloudletPes)); assertFalse(instance.isThereEnoughFreePesForCloudlet(cloudlet1)); } @@ -211,8 +195,8 @@ public void testIsThereEnoughFreePesForCloudlet_WhenThereAreTwoPesAndOneAlreadyR instance.setCurrentMipsShare(CloudletSchedulerUtil.createMipsList(schedulerPes, SCHEDULER_MIPS)); Cloudlet cloudlet0 = CloudletSimpleTest.createCloudlet(0, cloudletPes); instance.cloudletSubmit(cloudlet0, fileTransferTime); - - CloudletExecutionInfo cloudlet1 = + + CloudletExecutionInfo cloudlet1 = new CloudletExecutionInfo(CloudletSimpleTest.createCloudlet(1, cloudletPes)); assertTrue(instance.isThereEnoughFreePesForCloudlet(cloudlet1)); } @@ -226,8 +210,8 @@ public void testIsThereEnoughFreePesForCloudlet_WhenThereAreFourPesAndOneAlready instance.setCurrentMipsShare(CloudletSchedulerUtil.createMipsList(schedulerPes, SCHEDULER_MIPS)); Cloudlet cloudlet0 = CloudletSimpleTest.createCloudlet(0, cloudletPes); instance.cloudletSubmit(cloudlet0, fileTransferTime); - - CloudletExecutionInfo cloudlet1 = + + CloudletExecutionInfo cloudlet1 = new CloudletExecutionInfo(CloudletSimpleTest.createCloudlet(1, cloudletPes)); assertTrue(instance.isThereEnoughFreePesForCloudlet(cloudlet1)); } @@ -246,10 +230,10 @@ public void testGetCloudletToMigrate_WhenThereAreExecCloudlet_ReturnOne() { final int cloudletPes = 1; CloudletSchedulerSpaceShared instance = new CloudletSchedulerSpaceShared(); instance.setCurrentMipsShare(CloudletSchedulerUtil.createMipsList(schedulerPes, SCHEDULER_MIPS)); - + Cloudlet expResult = CloudletSimpleTest.createCloudlet(0, cloudletPes); instance.cloudletSubmit(expResult); - + Cloudlet result = instance.getCloudletToMigrate(); assertSame(expResult, result); } @@ -260,10 +244,10 @@ public void testGetCloudletToMigrate_CheckExecListBecameEmpty() { final int cloudletPes = 1; CloudletSchedulerSpaceShared instance = new CloudletSchedulerSpaceShared(); instance.setCurrentMipsShare(CloudletSchedulerUtil.createMipsList(schedulerPes, SCHEDULER_MIPS)); - + Cloudlet expResult = CloudletSimpleTest.createCloudlet(0, cloudletPes); instance.cloudletSubmit(expResult); - + instance.getCloudletToMigrate(); assertTrue(instance.getCloudletExecList().isEmpty()); } @@ -274,16 +258,16 @@ public void testGetCloudletToMigrate_WhenTwoCloudletsAreRunning_AfterMigrationUs final int cloudletPes = 1; CloudletSchedulerSpaceShared instance = new CloudletSchedulerSpaceShared(); instance.setCurrentMipsShare(CloudletSchedulerUtil.createMipsList(schedulerPes, SCHEDULER_MIPS)); - + assertEquals(0, instance.getUsedPes()); Cloudlet cloudlet0 = CloudletSimpleTest.createCloudlet(0, cloudletPes); instance.cloudletSubmit(cloudlet0); assertEquals(1, instance.getUsedPes()); - + Cloudlet cloudlet1 = CloudletSimpleTest.createCloudlet(1, cloudletPes); instance.cloudletSubmit(cloudlet1); assertEquals(2, instance.getUsedPes()); - + final int expResult = 1; instance.getCloudletToMigrate(); assertEquals(expResult, instance.getUsedPes()); @@ -323,7 +307,7 @@ public void testGetCloudletExecList_SubmitedCloudletIsInExecList() { Cloudlet cloudlet = CloudletSimpleTest.createCloudletWithOnePe(0); instance.cloudletSubmit(cloudlet); Collection result = instance.getCloudletExecList(); - + assertTrue( instance.getCloudletExecList() .stream() @@ -354,11 +338,11 @@ public void testAddCloudletToExecList_ExecListSizeIsOne() { assertEquals(expResult, result); } - @Test + @Test public void testGetTotalCurrentAvailableMipsForCloudlet() { CloudletExecutionInfo rcl = new CloudletExecutionInfo(Cloudlet.NULL); - final int schedulerPes = 2; - List mipsShare = + final int schedulerPes = 2; + List mipsShare = CloudletSchedulerUtil.createMipsList(schedulerPes, SCHEDULER_MIPS); CloudletSchedulerSpaceShared instance = new CloudletSchedulerSpaceShared(); double expResult = SCHEDULER_MIPS; @@ -401,5 +385,5 @@ public void testGetCurrentRequestedUtilizationOfBw() { double result = instance.getCurrentRequestedUtilizationOfBw(); assertEquals(expResult, result, 0.0); } - + } diff --git a/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerTimeSharedTest.java b/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerTimeSharedTest.java index c75a2e5e7..f680f497f 100644 --- a/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerTimeSharedTest.java +++ b/cloudsim-plus/src/test/java/org/cloudbus/cloudsim/schedulers/CloudletSchedulerTimeSharedTest.java @@ -30,13 +30,13 @@ public class CloudletSchedulerTimeSharedTest { private static final double CPU_UTILIZATION_INCREMENT = 0; private static final double CPU_INITIAL_UTILIZATION = 0.5; private UtilizationModel um; - + @Before public void setUp(){ um = new UtilizationModelArithmeticProgression( CPU_UTILIZATION_INCREMENT, CPU_INITIAL_UTILIZATION); } - + /** * Creates a mock CloudletExecutionInfo. * @param id Cloudlet id @@ -48,7 +48,7 @@ private CloudletExecutionInfo createCloudletExecInfo(int id){ EasyMock.replay(cloudlet); return cloudlet; } - + @Test public void testGetCloudletWaitingList_Empty() { CloudletSchedulerTimeShared instance = new CloudletSchedulerTimeShared(); @@ -92,15 +92,15 @@ public void testCloudletResume_CloudletNotInPausedList() { public void testCloudletResume_CloudletInPausedList() { final int cloudletId = 1; final int schedulerPes = 1; - final double mips = 1000; + final double mips = 1000; final long cloudletLength = 10000; - CloudletSchedulerTimeShared instance = + CloudletSchedulerTimeShared instance = createCloudletSchedulerWithMipsList(schedulerPes, mips); createCloudletAndAddItToPausedList(instance, cloudletId, cloudletLength); double expResult = 10; double result = instance.cloudletResume(cloudletId); - + assertEquals(expResult, result, 0.0); } @@ -153,13 +153,13 @@ public void testGetTotalCurrentAvailableMipsForCloudlet_OneCloudlet() { final long cloudletLen = (long)mips; final int cloudletPes = 2; final int schedulerPes = 4; - CloudletExecutionInfo cloudlet = + CloudletExecutionInfo cloudlet = new CloudletExecutionInfo( CloudletSimpleTest.createCloudlet0(cloudletLen, cloudletPes)); - CloudletSchedulerTimeShared instance = + CloudletSchedulerTimeShared instance = createCloudletSchedulerWithMipsList(schedulerPes, mips); List mipsList = instance.getCurrentMipsShare(); - + double expResult = mips; double result = instance.getTotalCurrentAvailableMipsForCloudlet(cloudlet, mipsList); assertEquals(expResult, result, 0.0); @@ -188,9 +188,9 @@ public void testGetTotalCurrentRequestedMipsForCloudlet() { @Test public void testGetCurrentRequestedUtilizationOfRam() { final int schedulerPes = 2; - CloudletSchedulerTimeShared instance = + CloudletSchedulerTimeShared instance = createCloudletSchedulerWithListOfExecCloudlets(schedulerPes); - + double expResult = 1.0; double result = instance.getCurrentRequestedUtilizationOfRam(); assertEquals(expResult, result, 0.0); @@ -199,9 +199,9 @@ public void testGetCurrentRequestedUtilizationOfRam() { @Test public void testGetCurrentRequestedUtilizationOfBw() { final int schedulerPes = 2; - CloudletSchedulerTimeShared instance = + CloudletSchedulerTimeShared instance = createCloudletSchedulerWithListOfExecCloudlets(schedulerPes); - + double expResult = 1.0; double result = instance.getCurrentRequestedUtilizationOfBw(); assertEquals(expResult, result, 0.0); @@ -210,9 +210,9 @@ public void testGetCurrentRequestedUtilizationOfBw() { /** * Creates a CloudletScheduler and a given number of cloudlets, * adding them to the executing list. - * All created Cloudlets will use the UtilizationModel + * All created Cloudlets will use the UtilizationModel * {@link #um}. - * + * * @param numbeOfCloudlets number of cloudlets to create * @return the created CloudletScheduler with the given number of Cloudlets to execute */ @@ -223,7 +223,7 @@ private CloudletSchedulerTimeShared createCloudletSchedulerWithListOfExecCloudle new CloudletExecutionInfo( CloudletSimpleTest.createCloudlet(i, um))); } - + return instance; } @@ -244,19 +244,19 @@ public void testGetCloudletExecList_Empty() { public void testGetCloudletExecList_EmptyAfterFinishedCloudletsForTwoSchedulerPes() { final long mips = 1000; final int numberOfCloudlets = 2; - - CloudletSchedulerTimeShared instance = + + CloudletSchedulerTimeShared instance = createCloudletSchedulerWithMipsList(numberOfCloudlets, mips); for(int i = 0; i < numberOfCloudlets; i++) { Cloudlet c = CloudletSimpleTest.createCloudletWithOnePe(i, mips); c.assignCloudletToDatacenter(0, 0, 0); instance.addCloudletToExecList(new CloudletExecutionInfo(c)); } - + final double time0 = 0.5; instance.updateVmProcessing(time0, instance.getCurrentMipsShare()); assertEquals(2, instance.getCloudletExecList().size()); - + final double time1 = 1.0; instance.updateVmProcessing(time1, instance.getCurrentMipsShare()); assertTrue(instance.getCloudletExecList().isEmpty()); @@ -274,19 +274,19 @@ public void testGetCloudletExecList_EmptyAfterFinishedCloudletsForTwoSchedulerPe public void testGetCloudletExecList_EmptyAfterFinishedCloudletsForOneSchedulerPe() { final long mips = 1000; final int numberOfCloudlets = 2; - - CloudletSchedulerTimeShared instance = + + CloudletSchedulerTimeShared instance = createCloudletSchedulerWithMipsList(1, mips); for(int i = 0; i < numberOfCloudlets; i++) { Cloudlet c = CloudletSimpleTest.createCloudletWithOnePe(i, mips); c.assignCloudletToDatacenter(0, 0, 0); instance.addCloudletToExecList(new CloudletExecutionInfo(c)); } - + final double time1 = 1; instance.updateVmProcessing(time1, instance.getCurrentMipsShare()); assertEquals(2, instance.getCloudletExecList().size()); - + final double time2 = 2; instance.updateVmProcessing(time2, instance.getCurrentMipsShare()); assertTrue(instance.getCloudletExecList().isEmpty()); @@ -303,8 +303,8 @@ public void testRemoveCloudletFromExecList() { @Test public void testRemoveCloudletFromExecList_CloudletNoFound() { - CloudletExecutionInfo cloudletNotAdded = new CloudletExecutionInfo(Cloudlet.NULL); - CloudletExecutionInfo cloudletAdded = new CloudletExecutionInfo(Cloudlet.NULL); + CloudletExecutionInfo cloudletNotAdded = new CloudletExecutionInfo(CloudletSimpleTest.createCloudletWithOnePe(0)); + CloudletExecutionInfo cloudletAdded = new CloudletExecutionInfo(CloudletSimpleTest.createCloudletWithOnePe(1)); CloudletSchedulerTimeShared instance = new CloudletSchedulerTimeShared(); List list = new ArrayList<>(); list.add(cloudletAdded); @@ -322,5 +322,5 @@ public void testAddCloudletToExecList() { instance.addCloudletToExecList(cloudlet); assertEquals(list.size(), instance.getCloudletExecList().size()); } - + }