All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cloudbus.cloudsim.cloudlets.CloudletExecution Maven / Gradle / Ivy

Go to download

CloudSim Plus: A modern, highly extensible and easier-to-use Java 8 Framework for Modeling and Simulation of Cloud Computing Infrastructures and Services

There is a newer version: 8.0.0
Show newest version
/*
 * 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.cloudlets;

import org.cloudbus.cloudsim.datacenters.Datacenter;
import org.cloudbus.cloudsim.core.CloudSim;
import org.cloudbus.cloudsim.schedulers.cloudlet.CloudletScheduler;
import org.cloudbus.cloudsim.util.Conversion;

import java.util.Objects;

/**
 * Stores execution information about a {@link Cloudlet} submitted to a specific {@link Datacenter} for
 * processing. This class keeps track of the time for all activities in the
 * Datacenter for a specific Cloudlet. Before a Cloudlet exits the Datacenter,
 * it is RECOMMENDED to call this method {@link #finalizeCloudlet()}.
 * 

* It acts as a * 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.

* * @author Manzur Murshed * @author Rajkumar Buyya * @since CloudSim Toolkit 1.0 */ public class CloudletExecution { /** * A property that implements the Null Object Design Pattern for {@link CloudletExecution} * objects. */ public static final CloudletExecution NULL = new CloudletExecution(Cloudlet.NULL); /** * @see #getCloudlet() */ private final Cloudlet cloudlet; /** * @see #getFileTransferTime() */ private double fileTransferTime; /** * @see #getCloudletArrivalTime() */ private final double arrivalTime; /** * @see #getFinishTime() */ private double finishedTime; /** * The length of Cloudlet finished so far in number of Instructions (I). * The attribute stores the execution length of the cloudlet * in previous datacenters. Thus, it represents the actual executed * length of the cloudlet (not just the executed length in the current Datacenter). */ private long instructionsFinishedSoFar; /** * Latest cloudlet execution start time in the current Datacenter. * This attribute will only hold the latest * time since a Cloudlet can be canceled, paused or resumed. */ private double startExecTime; /** * @see #getLastProcessingTime() */ private double lastProcessingTime; /** * The total time the Cloudlet spent in the last state * at the current Datacenter. * For instance, if the last state was paused and now * the cloudlet was resumed (it is running), * this time represents the time the cloudlet * stayed paused. */ private double totalCompletionTime; /** * @see #getVirtualRuntime() */ private double virtualRuntime; /** * @see #getTimeSlice() */ private double timeSlice; /** * Instantiates a CloudletExecutionInfo object upon the arrival of a Cloudlet inside a Datacenter. * The arriving time is determined by {@link CloudSim#clock()}. * * @param cloudlet the Cloudlet to store execution information from */ public CloudletExecution(final Cloudlet cloudlet) { this.cloudlet = cloudlet; this.arrivalTime = cloudlet.registerArrivalInDatacenter(); this.finishedTime = Cloudlet.NOT_ASSIGNED; this.lastProcessingTime = Cloudlet.NOT_ASSIGNED; this.totalCompletionTime = 0.0; this.startExecTime = 0.0; this.virtualRuntime = 0; //In case a Cloudlet has been executed partially by some other Host this.instructionsFinishedSoFar = cloudlet.getFinishedLengthSoFar() * Conversion.MILLION; } /** * Gets the Cloudlet's length. * * @return Cloudlet's length * @pre $none * @post $none */ public long getCloudletLength() { return cloudlet.getLength(); } public long getNumberOfPes(){ return cloudlet.getNumberOfPes(); } /** * Sets the Cloudlet status. * * @param newStatus the Cloudlet status * @return true if the new status has been set, false * otherwise * @pre status >= 0 * @post $none */ public boolean setCloudletStatus(final Cloudlet.Status newStatus) { // gets Cloudlet's previous status final Cloudlet.Status prevStatus = cloudlet.getStatus(); // if the status of a Cloudlet is the same as last time, then ignore if (prevStatus.equals(newStatus)) { return false; } final double clock = cloudlet.getSimulation().clock(); cloudlet.setStatus(newStatus); if (prevStatus == Cloudlet.Status.INEXEC && isNotRunning(newStatus)) { totalCompletionTime += (clock - startExecTime); return true; } if (prevStatus == Cloudlet.Status.RESUMED && newStatus == Cloudlet.Status.SUCCESS) { totalCompletionTime += (clock - startExecTime); return true; } startOrResumeCloudlet(newStatus, prevStatus); return true; } /** * Starts or resumes the Cloudlet if the new status is requesting that. * * @param newStatus the new status that will be checked to start or resume the Cloudlet * @param oldStatus the old Cloudlet status */ private void startOrResumeCloudlet(final Cloudlet.Status newStatus, final Cloudlet.Status oldStatus) { final double clock = cloudlet.getSimulation().clock(); if (newStatus == Cloudlet.Status.INEXEC || isTryingToResumePausedCloudlet(newStatus, oldStatus)) { startExecTime = clock; if(cloudlet.getExecStartTime() == 0) { cloudlet.setExecStartTime(startExecTime); } } } private boolean isTryingToResumePausedCloudlet(final Cloudlet.Status newStatus, final Cloudlet.Status oldStatus) { return newStatus == Cloudlet.Status.RESUMED && oldStatus == Cloudlet.Status.PAUSED; } /** * Checks if the cloudlet is NOT in a running state. * * @param status The current cloudlet status * @return true if the cloudlet is NOT running, false if it is. */ private static boolean isNotRunning(final Cloudlet.Status status) { return status == Cloudlet.Status.CANCELED || status == Cloudlet.Status.PAUSED || status == Cloudlet.Status.SUCCESS; } /** * Gets the remaining cloudlet length (in MI) that has to be execute yet, * considering the {@link Cloudlet#getLength()}. * * @return cloudlet length in MI * @pre $none * @post $result >= 0 */ public long getRemainingCloudletLength() { final double remainingMI = cloudlet.getLength() - (instructionsFinishedSoFar / (double)Conversion.MILLION); return (remainingMI < 0 ? 0 : (long)remainingMI); } /** * Finalizes all relevant information before exiting the Datacenter * entity. This method sets the final data of: *
    *
  • wall clock time, i.e. the time of this Cloudlet resides in a * Datacenter (from arrival time until departure time). *
  • actual CPU time, i.e. the total execution time of this Cloudlet in a * Datacenter. *
  • Cloudlet's finished time so far *
*/ public void finalizeCloudlet() { // Sets the wall clock time and actual CPU time final double wallClockTime = cloudlet.getSimulation().clock() - arrivalTime; cloudlet.setWallClockTime(wallClockTime, totalCompletionTime); final long finishedLengthMI = cloudlet.getStatus() == Cloudlet.Status.SUCCESS ? cloudlet.getLength() : instructionsFinishedSoFar / Conversion.MILLION; cloudlet.addFinishedLengthSoFar(finishedLengthMI); } /** * Updates the length of cloudlet that has already been completed. * * @param partialFinishedInstructions the partial amount of instructions just executed, to be * added to the {@link #instructionsFinishedSoFar}, in Number of Instructions (instead of Million Instructions) */ public void updateProcessing(final long partialFinishedInstructions) { setLastProcessingTime(cloudlet.getSimulation().clock()); if(partialFinishedInstructions <= 0){ return; } this.instructionsFinishedSoFar += partialFinishedInstructions; final double partialFinishedMI = partialFinishedInstructions / Conversion.MILLION; cloudlet.addFinishedLengthSoFar((long)partialFinishedMI); } /** * Gets the time the cloudlet arrived for execution inside the Datacenter. * * @return arrival time */ public double getCloudletArrivalTime() { return arrivalTime; } /** * Gets 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 Cloudlet#NOT_ASSIGNED}. * * @return finish time of a cloudlet or -1.0 if it cannot finish in * this hourly slot * @pre $none * @post $result >= -1.0 */ public double getFinishTime() { return finishedTime; } /** * Sets the finish time for this Cloudlet. If time is negative, then it will be ignored. * * @param time finish time * @pre time >= 0.0 * @post $none */ public void setFinishTime(final double time) { if (time < 0) { return; } finishedTime = time; } /** * Gets the Cloudlet for which the execution information is related to. * * @return cloudlet for this execution information object * @pre $none * @post $result != null */ public Cloudlet getCloudlet() { return cloudlet; } /** * Gets the ID of the Cloudlet this execution info is related to. * @return */ public int getCloudletId(){ return cloudlet.getId(); } /** * 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 */ public double getFileTransferTime() { return fileTransferTime; } /** * Sets 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. * * @param fileTransferTime the file transfer time to set */ public void setFileTransferTime(final double fileTransferTime) { this.fileTransferTime = fileTransferTime; } /** * Gets the last time the Cloudlet was processed at the Datacenter * where this execution information is related to. * * @return the last time the Cloudlet was processed or zero when it has never been processed yet */ public double getLastProcessingTime() { return lastProcessingTime; } /** * Sets the last time this Cloudlet was processed at a Datacenter. * @param lastProcessingTime the last processing time to set */ public void setLastProcessingTime(final double lastProcessingTime) { this.lastProcessingTime = lastProcessingTime; cloudlet.notifyOnUpdateProcessingListeners(lastProcessingTime); } /** * 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. Each scheduler * implementation might set a value to such attribute * to use it for context switch, * preempting running Cloudlets to enable other ones to start executing. * This way, the attribute is just used internally by specific CloudletSchedulers. * * @return */ public double 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(final double timeToAdd) { if(timeToAdd >= 0) { setVirtualRuntime(virtualRuntime + timeToAdd); } return virtualRuntime; } /** * 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(final double virtualRuntime){ this.virtualRuntime = virtualRuntime; } /** * Gets the timeslice assigned by a {@link CloudletScheduler} for a Cloudlet, which 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; } /** * Sets the timeslice assigned by a {@link CloudletScheduler} for a Cloudlet, which 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. * * @param timeSlice the Cloudlet timeslice to set (in seconds) * */ public void setTimeSlice(final double timeSlice) { this.timeSlice = timeSlice; } @Override public String toString() { return String.format("Cloudlet %d", cloudlet.getId()); } @Override public boolean equals(Object obj) { return obj instanceof CloudletExecution && ((CloudletExecution)obj).cloudlet.getId() == this.cloudlet.getId(); } @Override public int hashCode() { return Objects.hash(cloudlet.getId()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy