/*
* 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-2010, 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.
* Cloudlets execute time-shared in VM.
*
* @author Rodrigo N. Calheiros
* @author Anton Beloglazov
* @since CloudSim Toolkit 1.0
*/
//实现Time shared调度
public class CloudletSchedulerTimeShared extends CloudletScheduler {
//执行列表
/** The cloudlet exec list. */
private List<? extends ResCloudlet> cloudletExecList;
//暂停列表
/** The cloudlet paused list. */
private List<? extends ResCloudlet> cloudletPausedList;
//完成列表
/** The cloudlet finished list. */
private List<? extends ResCloudlet> cloudletFinishedList;
//当前cpu数
/** The current cp us. */
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();
this.cloudletExecList = new ArrayList<ResCloudlet>();
this.cloudletPausedList = new ArrayList<ResCloudlet>();
this.cloudletFinishedList = new ArrayList<ResCloudlet>();
this.currentCPUs = 0;
}
/**
* Updates the processing of cloudlets running under management of this scheduler.
*
* @param currentTime current simulation time
* @param mipsShare array with MIPS share of each processor available to the scheduler
*
* @return time predicted completion time of the earliest finishing cloudlet, or 0
* if there is no next events
*
* @pre currentTime >= 0
* @post $none
*/
@Override
//更新处理过程
public double updateVmProcessing(double currentTime, List<Double> mipsShare) {
setCurrentMipsShare(mipsShare);
double timeSpam = currentTime - getPreviousTime();
for (ResCloudlet rcl : getCloudletExecList()) { //更新各个cloudlet的完成长度
rcl.updateCloudletFinishedSoFar((long) (getCapacity(mipsShare) * timeSpam * rcl.getPesNumber()));
}
if (getCloudletExecList().size() == 0) { //列表为空
setPreviousTime(currentTime);
return 0.0;
}
// check finished cloudlets //检查完成的cloudlet
double nextEvent = Double.MAX_VALUE;
int i = 0;
List<ResCloudlet> toRemove = new ArrayList<ResCloudlet>();
for (ResCloudlet rcl : getCloudletExecList()) {
double remainingLength = rcl.getRemainingCloudletLength();
if (remainingLength == 0.00) {// finished: remove from the list
toRemove.add(rcl);
cloudletFinish(rcl);
continue;
}
i++;
}
getCloudletExecList().removeAll(toRemove);
//estimate finish time of cloudlets 估算最短完成时间
i=0;
for (ResCloudlet rcl : getCloudletExecList()) {
double estimatedFinishTime = currentTime + (rcl.getRemainingCloudletLength() / (getCapacity(mipsShare) * rcl.getPesNumber()));
if (estimatedFinishTime - currentTime < 0.1) {
estimatedFinishTime = currentTime + 0.1;
}
if (estimatedFinishTime < nextEvent) {
nextEvent = estimatedFinishTime;
}
i++;
}
setPreviousTime(currentTime);
return nextEvent;
}
/**
* Gets the capacity.
*
* @param mipsShare the mips share
*
* @return the capacity
*/
//获取每cpu计算能力
private 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.getPesNumber();
}
if (pesInUse > currentCPUs) {
capacity /= pesInUse;
} else {
capacity /= currentCPUs;
}
return capacity;
}
/**
* Cancels execution of a cloudlet.
*
* @param cloudletId ID of the cloudlet being cancealed
*
* @return the canceled cloudlet, $null if not found
*
* @pre $none
* @post $none
*/
//取消cloudlet
@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 检查执行队列
for (ResCloudlet rcl : getCloudletExecList()) {
if (rcl.getCloudletId() == cloudletId) {
found = true;
break;
}
position++;
}
if (found) {
ResCloudlet rcl = getCloudletExecList().remove(position);
if (rcl.getRemainingCloudletLength() == 0.0) {
cloudletFinish(rcl);
} else {
rcl.setCloudletStatus(Cloudlet.CANCELED);
}
return rcl.getCloudlet();
}
// Now, looks in the paused queue 检查暂停队列
found = false;
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;
}
/**
* Pauses execution of a cloudlet.
*
* @param cloudletId ID of the cloudlet being paused
*
* @return $true if cloudlet paused, $false otherwise
*
* @pre $none
* @post $none
*/
//暂停cloudlet
@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.0) {
cloudletFinish(rcl);
} else {
rcl.setCloudletStatus(Cloudlet.PAUSED);
getCloudletPausedList().add(rcl);
}
return true;
}
return false;
}
/**
* Processes a finished cloudlet.
*
* @param rcl finished cloudlet
*
* @pre rgl != $null
* @post $none
*/
//处理完成的cloudlet
@Override
public void cloudletFinish(ResCloudlet rcl) {
rcl.setCloudletStatus(Cloudlet.SUCCESS);
rcl.finalizeCloudlet();
getCloudletFinishedList().add(rcl);
}
/**
* Resumes execution of a paused cloudlet.
*
* @param cloudletId ID of the cloudlet being resumed
*
* @return expected finish time of the cloudlet, 0.0 if queued
*
* @pre $none
* @post $none
*/
//恢复暂停的cloudlet
@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.getPesNumber()));
return estimatedFinishTime;
}
return 0.0;
}
/**
* Receives an cloudlet to be executed in the VM managed by this scheduler.
*
* @param cloudlet the submited cloudlet
* @param fileTransferTime time required to move the required files from the SAN to the VM
*
* @return expected finish time of this cloudlet
*
* @pre gl != null
* @post $none
*/
//提交cloudlet
@Override
public double cloudletSubmit(Cloudlet cloudlet, double fileTransferTime) {
ResCloudlet rcl = new ResCloudlet(cloudlet);
rcl.setCloudletStatus(Cloudlet.INEXEC);
for (int i = 0; i < cloudlet.getPesNumber(); 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());
}
/* (non-Javadoc)
* @see cloudsim.CloudletScheduler#cloudletSubmit(cloudsim.Cloudlet)
*/
@Override
public double cloudletSubmit(Cloudlet cloudlet) {
cloudletSubmit(cloudlet, 0);
return 0;
}
/**
* Gets the status of a cloudlet.
*
* @param cloudletId ID of the cloudlet
*
* @return status of the cloudlet, -1 if cloudlet not found
*
* @pre $none
* @post $none
*/
//获取状态
@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;
}
/**
* Get utilization created by all cloudlets.
*
* @param time the time
*
* @return total utilization
*/
//获取利用率
@Override
public double getTotalUtilizationOfCpu(double time) {
double totalUtilization = 0;
for (ResCloudlet gl : getCloudletExecList()) {
totalUtilization += gl.getCloudlet().getUtilizationOfCpu(time);
}
return totalUtilization;
}
/**
* Informs about completion of some cloudlet in the VM managed
* by this scheduler.
*
* @return $true if there is at least one finished cloudlet; $false otherwise
*
* @pre $none
* @post $none
*/
@Override
//检查完成队列是否为空
public boolean isFinishedCloudlets() {
return getCloudletFinishedList().size() > 0;
}
/**
* Returns the next cloudlet in the finished list, $null if this list is empty.
*
* @return a finished cloudlet
*
* @pre $none
* @post $none
*/
//移除列表首元素并返回
@Override
public Cloudlet getNextFinishedCloudlet() {
if (getCloudletFinishedList().size() > 0) {
return getCloudletFinishedList().remove(0).getCloudlet();
}
return null;
}
/**
* Returns the number of cloudlets runnning in the virtual machine.
*
* @return number of cloudlets runnning
*
* @pre $none
* @post $none
*/
//获取运行VM数
@Override
public int runningCloudlets() {
return getCloudletExecList().size();
}
/**
* Returns one cloudlet to migrate to another vm.
*
* @return one running cloudlet
*
* @pre $none
* @post $none
*/
@Override
//迁移
public Cloudlet migrateCloudlet() {
ResCloudlet rgl = getCloudletExecList().remove(0);
rgl.finalizeCloudlet();
return rgl.getCloudlet();
}
/**
* Gets the cloudlet exec list.
*
* @param <T> the generic type
* @return the cloudlet exec list
*/
//获取执行队列
@SuppressWarnings("unchecked")
protected <T extends ResCloudlet> List<T> getCloudletExecList() {
return (List<T>) cloudletExecList;
}
/**
* Sets the cloudlet exec list.
*
* @param <T> the generic type
* @param cloudletExecList the new cloudlet exec list
*/
//设置执行对立
protected <T extends ResCloudlet> void setCloudletExecList(List<T> cloudletExecList) {
this.cloudletExecList = cloudletExecList;
}
/**
* Gets the cloudlet paused list.
*
* @param <T> the generic type
* @return the cloudlet paused list
*/
//获取暂停队列
@SuppressWarnings("unchecked")
protected <T extends ResCloudlet> List<T> getCloudletPausedList() {
return (List<T>) cloudletPausedList;
}
/**
* Sets the cloudlet paused list.
*
* @param <T> the generic type
* @param cloudletPausedList the new cloudlet paused list
*/
//设置暂停对立
protected <T extends ResCloudlet> void setCloudletPausedList(List<T> cloudletPausedList) {
this.cloudletPausedList = cloudletPausedList;
}
/**
* Gets the cloudlet finished list.
*
* @param <T> the generic type
* @return the cloudlet finished list
*/
//获取完成列表
@SuppressWarnings("unchecked")
protected <T extends ResCloudlet> List<T> getCloudletFinishedList() {
return (List<T>) cloudletFinishedList;
}
/**
* Sets the cloudlet finished list.
*
* @param <T> the generic type
* @param cloudletFinishedList the new cloudlet finished list
*/
//设置完成列表
protected <T extends ResCloudlet> void setCloudletFinishedList(List<T> cloudletFinishedList) {
this.cloudletFinishedList = cloudletFinishedList;
}
/* (non-Javadoc)
* @see cloudsim.CloudletScheduler#getCurrentRequestedMips()
*/
@Override
public List<Double> getCurrentRequestedMips() {
List<Double> mipsShare = new ArrayList<Double>();
// if (getCurrentMipsShare() != null) {
// for (Double mips : getCurrentMipsShare()) {
// mipsShare.add(mips);
// }
// }
//TODO: implement
return mipsShare;
}
/* (non-Javadoc)
* @see cloudsim.CloudletScheduler#getTotalCurrentAvailableMipsForCloudlet(cloudsim.ResCloudlet, java.util.List)
*/
@Override
public double getTotalCurrentAvailableMipsForCloudlet(ResCloudlet rcl, List<Double> mipsShare) {
return getCapacity(getCurrentMipsShare());
}
/* (non-Javadoc)
* @see cloudsim.CloudletScheduler#getTotalCurrentAllocatedMipsForCloudlet(cloudsim.ResCloudlet, double)
*/
@Override
public double getTotalCurrentAllocatedMipsForCloudlet(ResCloudlet rcl,
double time) {
return 0.0;
}
/* (non-Javadoc)
* @see cloudsim.CloudletScheduler#getTotalCurrentRequestedMipsForCloudlet(cloudsim.ResCloudlet, double)
*/
@Override
public double getTotalCurrentRequestedMipsForCloudlet(ResCloudlet rcl,
double time) {
// TODO Auto-generated method stub
return 0.0;
}
}
cloudsim源代码学习:CloudletSchedulerTimeShared.java
最新推荐文章于 2014-12-11 20:17:07 发布