📄 ratecontrolledscheduler.java
字号:
/*
* ** Network and Service Differentiation Extensions to GridSim 3.0 **
*
* Gokul Poduval & Chen-Khong Tham
* Computer Communication Networks (CCN) Lab
* Dept of Electrical & Computer Engineering
* National University of Singapore
* August 2004
*
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
*
* RateControlledScheduler.java - Implements a Rate controlled scheduler
*
*/
package gridsim.net;
import gridsim.net.*;
import eduni.simjava.*;
import gridsim.*;
import java.util.*;
/**
* RateControlledScheduler is an implementation of a rate-jitter controlling
* regulator. For more details refer to <b>H. Zhang and D.Ferrari's</b>
* INFOCOM '93 paper <i>Rate-Controlled Static-Priority Queueing</i>.
* <p>
* RateControlledScheduler can be used to control the bandwidth that
* is assigned to each class of user at a Router. This is a non-work conserving
* algorithm, which means that the router can remain idle even if there are
* packets in its queue.
* <p>
* At a RateControlledScheduler each class of users is assigned a certain
* percentage of bandwidth, and the scheduler makes sure that each class remains
* constrained within its bandwidth limits at all times.
*
* @author Gokul Poduval & Chen-Khong Tham, National University of Singapore
* @since GridSim Toolkit 4.0
* @invariant $none
*/
public class RateControlledScheduler extends Sim_entity
implements PacketScheduler
{
private double baudRate_; // baud rate of a link
private int routerID_ ; // router ID that hosts this scheduler
private double[] rates_; // rates of each class
private int numClasses_; // num of classes or ToS
private ArrayList[] packets_; // intermediate queue
private ArrayList pktList_; // final queue
private ArrayList classType_; // an integer storing the class types
private static final int BITS = 8; // 1 byte in bits
private static final int DEQUEUE_PACKET = 1000;
private static final int INTERNAL_DEQUEUE = 1001;
/**
* Creates a new RateControlled packet scheduler with the specified name
* and baud rate (in bits/s).
* The name can be useful for debugging purposes, but serves
* no functional purposes.
* Don't forget to set the rate for each packet class by using the
* {@link #setRates(double[])} method.
*
* @param name Name of this scheduler
* @param baudRate baud rate in bits/s of the port that is using
* this scheduler.
* @param numClasses number of classes for prioritizing a packet
* @throws ParameterException This happens when the name is null or
* the baud rate <= 0 or num of classes <= 0
* @pre name != null
* @pre baudRate > 0
* @pre numClasses > 0
* @post $none
*/
public RateControlledScheduler(String name, double baudRate, int numClasses)
throws ParameterException
{
super(name);
if (baudRate <= 0) {
throw new ParameterException("Baudrate must be greater than 0");
}
if (numClasses <= 0) {
throw new ParameterException("Num of class must be greater than 0");
}
routerID_ = -1;
baudRate_ = baudRate;
numClasses_ = numClasses;
init(numClasses);
}
/**
* Creates a new RateControlled packet scheduler with the specified name.
* The baud rate is left at 0, and should be set with
* {@link gridsim.net.PacketScheduler#setBaudRate(double)}
* before the simulation starts.
* The name can be useful for debugging purposes, but serves
* no functional purposes.
* Don't forget to set the rate for each packet class by using the
* {@link #setRates(double[])} method.
*
* @param name Name of this scheduler
* @param numClasses number of classes for prioritizing a packet
* @throws ParameterException This happens when the name is null or
* the baud rate <= 0 or num of classes <= 0
* @pre name != null
* @pre numClasses > 0
* @post $none
*/
public RateControlledScheduler(String name, int numClasses)
throws ParameterException
{
super(name);
if (numClasses <= 0) {
throw new ParameterException("Num of class must be greater than 0");
}
routerID_ = -1;
baudRate_ = 0;
numClasses_ = numClasses;
init(numClasses);
}
/**
* Creates a new RateControlled packet scheduler with the specified name
* and baud rate (in bits/s).
* The name can be useful for debugging purposes, but serves
* no functional purposes.
* Don't forget to set the rate for each packet class by using the
* {@link #setRates(double[])} method.
*
* @param name Name of this scheduler
* @param baudRate baud rate in bits/s of the port that is using
* this scheduler.
* @param routerID the router ID that hosts this packet scheduler
* @param numClasses number of classes for prioritizing a packet
* @throws ParameterException This happens when the name is null or
* router ID <= 0 or the baud rate <= 0 or
* num of classes <= 0
* @pre name != null
* @pre baudRate > 0
* @pre routerID > 0
* @pre numClasses > 0
* @post $none
*/
public RateControlledScheduler(String name, double baudRate, int routerID,
int numClasses) throws ParameterException
{
super(name);
if (baudRate <= 0) {
throw new ParameterException("Baud rate must be greater than 0");
}
if (routerID <= 0) {
throw new ParameterException("Router ID must be greater than 0");
}
if (numClasses <= 0) {
throw new ParameterException("Num of class must be greater than 0");
}
baudRate_ = baudRate;
routerID_ = routerID;
numClasses_ = numClasses;
init(numClasses);
}
/**
* Initializes all private attributes
* @param numClasses number of classes for prioritizing a packet
* @pre $none
* @post $none
*/
private void init(int numClasses)
{
rates_ = null;
classType_ = new ArrayList(numClasses);
packets_ = new ArrayList[numClasses];
pktList_ = new ArrayList();
for (int i = 0; i < numClasses; i++)
{
packets_[i] = new ArrayList();
classType_.add( new Integer(i) );
}
}
/**
* Gets the number of classes for prioritizing incoming packets
* @return number of classes
* @pre $none
* @post $none
*/
public int getNumClass() {
return numClasses_;
}
/**
* Gets the list of rates for each packet class
* @return the list of rates or <tt>null</tt> if empty
* @pre $none
* @post $none
*/
public double[] getRate() {
return rates_;
}
/**
* Handles an incoming events coming from a specified Router
* @pre $none
* @post $none
*/
public void body()
{
Sim_event ev = new Sim_event();
while ( Sim_system.running() )
{
super.sim_get_next(ev); // get the incoming event
// if the simulation finishes then exit the loop
if (ev.get_tag() == GridSimTags.END_OF_SIMULATION) {
break;
}
// process the received event
processEvent(ev);
}
}
/**
* Processes an incoming event based on its tag name
* @param ev a Sim_event object
* @pre ev != null
* @post $none
*/
private void processEvent(Sim_event ev)
{
if (ev == null) {
return;
}
switch (ev.get_tag())
{
case GridSimTags.SCHEDULER_ENQUE:
this.enque(ev);
break;
case INTERNAL_DEQUEUE:
this.internalDequeue(ev);
break;
case DEQUEUE_PACKET:
this.dequeue(ev);
break;
default:
System.out.println(super.get_name() +
".processEvent: Warning - unknown tag name.");
break;
}
}
/**
* In this scheduler, the packet is put into the tail of the queue.
* There is no buffer management, so packets are never dropped, and the
* queue can grow as long as system memory is available.
*
* @param ev a Sim_event object
* @pre ev != null
* @post $none
*/
private void enque(Sim_event ev)
{
if (ev == null) {
return;
}
try
{
Packet pkt = (Packet) ev.get_data();
int type = pkt.getNetServiceType();
// check whether the class type is correct or not
if (type >= packets_.length)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -