您的位置:首页 > 大数据 > 云计算

云计算仿真工具中文注释CloudletSchedulerSpaceShared.java

2011-11-08 15:53 465 查看
/*
* 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;

/**
* cloudletschedulerspaceshared实现了vm对于cloudlet的一个调度策略
*
* CloudletSchedulerSpaceShared implements a policy of
* scheduling performed by a virtual machine. It consider
* that there will be only one cloudlet per VM. Other cloudlets will be in a
* waiting list. We consider that file transfer from cloudlets waiting happens
* before cloudlet execution. I.e., even though cloudlets must wait for CPU,
* data transfer happens as soon as cloudlets are submitted.
*
* @author		Rodrigo N. Calheiros
* @author		Anton Beloglazov
* @since		CloudSim Toolkit 1.0
*/
public class CloudletSchedulerSpaceShared extends CloudletScheduler {

/** The cloudlet waiting list. */
private List<? extends ResCloudlet> cloudletWaitingList;

/** 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;

/** The current CPUs. */
protected int currentCpus;

/** The used PEs. */
protected int usedPes;

/**
* Creates a new CloudletSchedulerSpaceShared object. This method must be invoked
* before starting the actual simulation.
*
* @pre $none
* @post $none
*/
public CloudletSchedulerSpaceShared() {
//父类字段:previoustime和currentmipshare
super();
this.cloudletWaitingList = new ArrayList<ResCloudlet>();
this.cloudletExecList = new ArrayList<ResCloudlet>();
this.cloudletPausedList = new ArrayList<ResCloudlet>();
this.cloudletFinishedList = new ArrayList<ResCloudlet>();
this.usedPes = 0;
this.currentCpus = 0;
}

/**
* 当前时间,更新cloudlet状态,当有任务完成时,加入新的任务,返回下一个任务完成的时刻
* 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
*        每个cpu提供的计算能力
* @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(); // time since last update
double capacity = 0.0;
int cpus = 0;

for (Double mips : mipsShare) { // count the CPUs available to the VMM
capacity += mips;
if (mips > 0) {
cpus++;
}
}
currentCpus = cpus;
capacity /= cpus; // average capacity of each cpu

for (ResCloudlet rcl : getCloudletExecList()) { // cpu个数等于任务在exec队列中乘以pe个数each machine in the exec list has the same amount of cpu
rcl.updateCloudletFinishedSoFar((long) (capacity * timeSpam * rcl.getPesNumber()));
}

if (getCloudletExecList().size() == 0 && getCloudletWaitingList().size() == 0) { // no more cloudlets in this scheduler
setPreviousTime(currentTime);             //所有任务执行完毕,设置此时刻
return 0.0;
}

//update each cloudlet
int finished = 0;
int cont = 0;
List<ResCloudlet> toRemove = new ArrayList<ResCloudlet>();
for (ResCloudlet rcl : getCloudletExecList()) {
if (rcl.getRemainingCloudletLength() == 0.0) {// finished anyway, rounding issue...
toRemove.add(rcl);
cloudletFinish(rcl);              //设置状态,释放pes
finished++;
}
cont++;
}
getCloudletExecList().removeAll(toRemove);

//for each finished cloudlet, add a new one from the waiting list
//从等候队列中选择cloudlet加入到执行队列中,需要检查currentcpus>usedpes+rcl.pes
if (!getCloudletWaitingList().isEmpty()) {
//??为什么要加这个循环,资源不是已经释放完了吗,??
//回答:为了加id号
for (int i = 0; i < finished; i++) {
toRemove.clear();
for (ResCloudlet rcl : getCloudletWaitingList()) {
if ((currentCpus - usedPes) >= rcl.getPesNumber()) {
rcl.setCloudletStatus(Cloudlet.INEXEC);
for (int k = 0; k < rcl.getPesNumber(); k++) {
//??加一样的有什么意义??,是不是应该是rcl.setMachineAndPeId(i,k);;
rcl.setMachineAndPeId(0, i);
}
getCloudletExecList().add(rcl);
usedPes += rcl.getPesNumber();
toRemove.add(rcl);
break;
}
}
getCloudletWaitingList().removeAll(toRemove);
}// for(cont)
}

//estimate finish time of cloudlets in the execution queue
double nextEvent = Double.MAX_VALUE;
for (ResCloudlet rcl : getCloudletExecList()) {
double remainingLength = rcl.getRemainingCloudletLength();
double estimatedFinishTime = currentTime + (remainingLength / (capacity * rcl.getPesNumber()));
if (estimatedFinishTime - currentTime < 0.1) {
estimatedFinishTime = currentTime + 0.1;
}
if (estimatedFinishTime < nextEvent) {
nextEvent = estimatedFinishTime;
}
}
setPreviousTime(currentTime);  //每当有任务完成(可能有任务加入),就设置当前时间
return nextEvent;              //nextevent为下一个任务完成的时刻
}

/**
* 取消一个cloudlet
* 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
*/
@Override
public Cloudlet cloudletCancel(int cloudletId) {
//First, looks in the finished queue
for (ResCloudlet rcl : getCloudletFinishedList()) {
if (rcl.getCloudletId() == cloudletId) {
getCloudletFinishedList().remove(rcl);
return rcl.getCloudlet();
}
}

//Then searches in the exec list
for (ResCloudlet rcl : getCloudletExecList()) {
if (rcl.getCloudletId() == cloudletId) {
getCloudletExecList().remove(rcl);
if (rcl.getRemainingCloudletLength() == 0.0) {
cloudletFinish(rcl);
} else {
rcl.setCloudletStatus(Cloudlet.CANCELED);
}
return rcl.getCloudlet();
}
}

//Now, looks in the paused queue
for (ResCloudlet rcl : getCloudletPausedList()) {
if (rcl.getCloudletId() == cloudletId) {
getCloudletPausedList().remove(rcl);
return rcl.getCloudlet();
}
}

//Finally, looks in the waiting list
for (ResCloudlet rcl : getCloudletWaitingList()) {
if (rcl.getCloudletId() == cloudletId) {
rcl.setCloudletStatus(Cloudlet.CANCELED);
getCloudletWaitingList().remove(rcl);
return rcl.getCloudlet();
}
}

return null;

}

/**
* 暂停一个cloudlet
* Pauses execution of a cloudlet.
*
* @param cloudletId ID of the cloudlet being paused
*
* @return $true if cloudlet paused, $false otherwise
*
* @pre $none
* @post $none
*/
@Override
public boolean cloudletPause(int cloudletId) {
boolean found = false;
int position = 0;

//first, looks for the cloudlet in the exec list
for (ResCloudlet rcl : getCloudletExecList()) {
if (rcl.getCloudletId() == cloudletId) {
found = true;
break;
}
position++;
}

if (found){
//moves to the paused list
ResCloudlet rgl = getCloudletExecList().remove(position);
if (rgl.getRemainingCloudletLength() == 0.0) {
cloudletFinish(rgl);
} else {
rgl.setCloudletStatus(Cloudlet.PAUSED);
getCloudletPausedList().add(rgl);
}
return true;

}

//now, look for the cloudlet in the waiting list
position = 0;
found = false;
for (ResCloudlet rcl : getCloudletWaitingList()) {
if (rcl.getCloudletId() == cloudletId) {
found = true;
break;
}
position++;
}

if (found) {
// moves to the paused list
ResCloudlet rgl = getCloudletWaitingList().remove(position);
if (rgl.getRemainingCloudletLength() == 0.0) {
cloudletFinish(rgl);
} else {
rgl.setCloudletStatus(Cloudlet.PAUSED);
getCloudletPausedList().add(rgl);
}
return true;

}

return false;
}

/**
* cloudlet执行完毕,设置状态,移入完成队列中,释放pe单元
* 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);
usedPes -= rcl.getPesNumber();
}

/**
* 恢复cloudlet,返回估计完成时间或0
* Resumes execution of a paused cloudlet.
*
* @param cloudletId ID of the cloudlet being resumed
*
* @return $true if the cloudlet was resumed, $false otherwise
*
* @pre $none
* @post $none
*/
@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 rcl = getCloudletPausedList().remove(position);

if ((currentCpus - usedPes) >= rcl.getPesNumber()) {// it can go to the exec list
rcl.setCloudletStatus(Cloudlet.INEXEC);
for (int i = 0; i < rcl.getPesNumber(); i++) {
rcl.setMachineAndPeId(0, i);
}

long size = rcl.getRemainingCloudletLength();
size *= rcl.getPesNumber();
rcl.getCloudlet().setCloudletLength(size);

getCloudletExecList().add(rcl);
usedPes += rcl.getPesNumber();

// calculate the expected time for cloudlet completion
double capacity = 0.0;
int cpus = 0;
for (Double mips : getCurrentMipsShare()) {
capacity += mips;
if (mips > 0) {
cpus++;
}
}
currentCpus = cpus;
capacity /= cpus;

long remainingLength = rcl.getRemainingCloudletLength();
double estimatedFinishTime = CloudSim.clock() + (remainingLength / (capacity * rcl.getPesNumber()));

return estimatedFinishTime;
} else {// no enough free PEs: go to the waiting queue
rcl.setCloudletStatus(Cloudlet.QUEUED);

long size = rcl.getRemainingCloudletLength();
size *= rcl.getPesNumber();
rcl.getCloudlet().setCloudletLength(size);

getCloudletWaitingList().add(rcl);
return 0.0;
}

}

//not found in the paused list: either it is in in the queue, executing or not exist
return 0.0;

}

/**
* 任务提交,收到一个cloudlet,加入到执行队列,或者等待队列中
* 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, or 0 if it is in the waiting queue
*
* @pre gl != null
* @post $none
*/
@Override
public double cloudletSubmit(Cloudlet cloudlet, double fileTransferTime) {
if ((currentCpus - usedPes) >= cloudlet.getPesNumber()) {// it can go to the exec list
ResCloudlet rcl = new ResCloudlet(cloudlet);
rcl.setCloudletStatus(Cloudlet.INEXEC);
for (int i = 0; i < cloudlet.getPesNumber(); i++) {
rcl.setMachineAndPeId(0, i);
}

getCloudletExecList().add(rcl);
usedPes += cloudlet.getPesNumber();
} else {// no enough free PEs: go to the waiting queue
ResCloudlet rcl = new ResCloudlet(cloudlet);
rcl.setCloudletStatus(Cloudlet.QUEUED);
getCloudletWaitingList().add(rcl);
return 0.0;
}

// calculate the expected time for cloudlet completion
double capacity = 0.0;
int cpus = 0;
for (Double mips : getCurrentMipsShare()) {
capacity += mips;
if (mips > 0) {
cpus++;
}
}

currentCpus = cpus;
capacity /= cpus;

// use the current capacity to estimate the extra amount of
// time to file transferring. It must be added to the cloudlet length
double extraSize = capacity * fileTransferTime;
long length = cloudlet.getCloudletLength();
length += extraSize;
cloudlet.setCloudletLength(length);
return cloudlet.getCloudletLength() / capacity;
}

/* (non-Javadoc)
* 提交任务,没有文件
* @see cloudsim.CloudletScheduler#cloudletSubmit(cloudsim.Cloudlet)
*/
@Override
public double cloudletSubmit(Cloudlet cloudlet) {
cloudletSubmit(cloudlet, 0);
return 0;
}

/**
* 获得一个cloudlet状态,需要检查三个列表
* 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();
}
}

for (ResCloudlet rcl : getCloudletWaitingList()) {
if (rcl.getCloudletId() == cloudletId) {
return rcl.getCloudletStatus();
}
}

return -1;
}

/**
* 获得所有cpu的利用率
* 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
*/
@Override
public int runningCloudlets() {
return getCloudletExecList().size();
}

/**
* 在此vm上结算后返回
* Returns one cloudlet to migrate to another vm.
*
* @return one running cloudlet
*
* @pre $none
* @post $none
*/
@Override
public Cloudlet migrateCloudlet() {
ResCloudlet rcl = getCloudletExecList().remove(0);
rcl.finalizeCloudlet();
Cloudlet cl = rcl.getCloudlet();
usedPes -= cl.getPesNumber();
return cl;
}

/**
* Gets the cloudlet waiting list.
*
* @param <T> the generic type
* @return the cloudlet waiting list
*/
@SuppressWarnings("unchecked")
protected <T extends ResCloudlet> List<T> getCloudletWaitingList() {
return (List<T>) cloudletWaitingList;
}

/**
* Cloudlet waiting list.
*
* @param <T> the generic type
* @param cloudletWaitingList the cloudlet waiting list
*/
protected <T extends ResCloudlet> void cloudletWaitingList(List<T> cloudletWaitingList) {
this.cloudletWaitingList = cloudletWaitingList;
}

/**
* 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 org.cloudbus.cloudsim.CloudletScheduler#getCurrentRequestedMips()
*/
@Override
public List<Double> getCurrentRequestedMips() {
List<Double> mipsShare = new ArrayList<Double>();
if (getCurrentMipsShare() != null) {
for (Double mips : getCurrentMipsShare()) {
mipsShare.add(mips);
}
}
return mipsShare;
}

/* (non-Javadoc)
* @see org.cloudbus.cloudsim.CloudletScheduler#getTotalCurrentAvailableMipsForCloudlet(org.cloudbus.cloudsim.ResCloudlet, java.util.List)
*/
@Override
public double getTotalCurrentAvailableMipsForCloudlet(ResCloudlet rcl, List<Double> mipsShare) {
double capacity = 0.0;
int cpus = 0;
for (Double mips : mipsShare) { // count the cpus available to the vmm
capacity += mips;
if (mips > 0) {
cpus++;
}
}
currentCpus = cpus;
capacity /= cpus; // average capacity of each cpu
return capacity;
}

/* (non-Javadoc)
* @see org.cloudbus.cloudsim.CloudletScheduler#getTotalCurrentAllocatedMipsForCloudlet(org.cloudbus.cloudsim.ResCloudlet, double)
*/
@Override
public double getTotalCurrentAllocatedMipsForCloudlet(ResCloudlet rcl, double time) {
// TODO Auto-generated method stub
return 0.0;
}

/* (non-Javadoc)
* @see org.cloudbus.cloudsim.CloudletScheduler#getTotalCurrentRequestedMipsForCloudlet(org.cloudbus.cloudsim.ResCloudlet, double)
*/
@Override
public double getTotalCurrentRequestedMipsForCloudlet(ResCloudlet rcl, double time) {
// TODO Auto-generated method stub
return 0.0;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: