From: <bro...@us...> - 2008-02-19 02:40:47
|
Revision: 112 http://gridsim.svn.sourceforge.net/gridsim/?rev=112&view=rev Author: brobergj Date: 2008-02-18 18:40:39 -0800 (Mon, 18 Feb 2008) Log Message: ----------- *FlowBuffer replaces FlowInput/FlowOutput approach *FlowBuffer acts as both a input and output port for simulation entities and as such it is a central point of control Added Paths: ----------- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java Added: branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java =================================================================== --- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java (rev 0) +++ branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-02-19 02:40:39 UTC (rev 112) @@ -0,0 +1,895 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + * + * Author: James Broberg & Anthony Sulistio (Adapted from original Output.java) + */ + +package gridsim.net.flow; + +import gridsim.*; +import gridsim.net.*; +import gridsim.util.*; + +import eduni.simjava.*; + +import java.util.*; + + +/** + * GridSim Output defines a port through which a simulation entity sends + * data to the simulated network. + * <p> + * It maintains an event queue to serialize + * the data-out-flow and delivers to the destination entity. + * It works along with Input entity to simulate network + * communication delay. Simultaneous outputs can be modeled by using multiple + * instances of this class + * + * @author Manzur Murshed and Rajkumar Buyya + * @since GridSim Toolkit 1.0 + * @invariant $none + */ +public class FlowBuffer extends Sim_entity implements NetIO +{ + private Sim_port outPort_; // output port + private Link link_; // a link to this output entity + private double baudRate_; // baud rate of this entity + private final int SIZE = 8; // 1 byte in bits + private int pktID_; // packet ID counter + private Vector outPacketList_; // store a list of packets + private HashMap<Integer, Packet> activeFlows_; // stores a list of active Flows + private Random random_; // selects to which junk packets go to + private TrafficGenerator gen_; // background traffic generator + private ArrayList list_; // list of resources + user entities + private boolean hasStarted_; // a flag for background traffic has started + private static final int BITS = 8; // 1 byte = 8 bits + + + /** + * Allocates a new Output object + * @param name the name of this object + * @param baudRate the communication speed + * @throws NullPointerException This happens when creating this entity + * before initializing GridSim package or this entity name + * is <tt>null</tt> or empty + * @pre name != null + * @pre baudRate >= 0.0 + * @post $none + */ + public FlowBuffer(String name, double baudRate) throws NullPointerException + { + super(name); + this.baudRate_ = baudRate; + link_ = null; + outPacketList_ = null; + activeFlows_ = null; + pktID_ = 0; + + outPort_ = new Sim_port("output_buffer"); + super.add_port(outPort_); + + // for sending background traffic + gen_ = null; + list_ = null; + random_ = null; + hasStarted_ = false; + } + + /** + * Sets the background traffic generator for this entity. + * <p> + * When simulation starts, this entity will automatically sends junk + * packets to resource entities. + * @param gen a background traffic generator + * @return <tt>true</tt> if successful, <tt>false</tt> otherwise + * @pre gen != null + * @post $none + */ + public boolean setBackgroundTraffic(TrafficGenerator gen) + { + if (gen == null) { + return false; + } + + gen_ = gen; + if (list_ == null) { + list_ = new ArrayList(); + } + + return true; + } + + /** + * Sets the background traffic generator for this entity. + * <p> + * When simulation starts, this entity will automatically sends junk + * packets to resource entities and other entities. <br> + * NOTE: Sending background traffic to itself is not supported. + * + * @param gen a background traffic generator + * @param userName a collection of user entity name (in String object). + * @return <tt>true</tt> if successful, <tt>false</tt> otherwise + * @pre gen != null + * @pre userName != null + * @post $none + */ + public boolean setBackgroundTraffic(TrafficGenerator gen, + Collection userName) + { + if (gen == null || userName == null) { + return false; + } + + boolean flag = true; + try + { + gen_ = gen; + if (list_ == null) { + list_ = new ArrayList(); + } + + // iterates through each list to check whether it is a valid + // entity name or not + Iterator it = userName.iterator(); + int id = -1; + while( it.hasNext() ) + { + String name = (String) it.next(); + + // check whether it is sending to itself + id = GridSim.getEntityId("Output_" + name); + if (id == super.get_id()) + { + System.out.println(super.get_name() + + ".setBackgroundTraffic(): Warning - can not send " + + "junk packets to itself."); + continue; + } + + // get the ID of other entity + id = GridSim.getEntityId(name); + if (id > 0) + { + Integer obj = new Integer(id); + list_.add(obj); + } + // ignore for invalid entity + else + { + System.out.println(super.get_name() + + ".setBackgroundTraffic(): Warning - invalid entity " + + "name for \"" + name + "\"."); + } + } + } + catch(Exception e) { + flag = false; + } + + return flag; + } + + /** + * Sets this entity's link. This should be used only if the network + * extensions are being used. + * + * @param link the link to which this Output entity should send data + * @pre link != null + * @post $none + */ + public void addLink(Link link) + { + this.link_ = link; + baudRate_ = link_.getBaudRate(); + outPacketList_ = new Vector(); + activeFlows_ = new HashMap(); + } + + /** + * Gets the baud rate + * @return the baud rate + * @deprecated As of GridSim 2.1, replaced by {@link #getBaudRate()} + * @pre $none + * @post $result >= 0.0 + */ + public double GetBaudRate() { + return this.getBaudRate(); + } + + /** + * Gets the baud rate + * @return the baud rate + * @pre $none + * @post $result >= 0.0 + */ + public double getBaudRate() { + return baudRate_; + } + + /** + * Gets the I/O real number based on a given value + * @param value the specified value + * @return real number + * @deprecated As of GridSim 2.1, replaced by {@link #realIO(double)} + * @pre $none + * @post $result >= 0.0 + */ + public double real_io(double value) { + return this.realIO(value); + } + + /** + * Gets the I/O real number based on a given value + * @param value the specified value + * @return real number + * @pre $none + * @post $result >= 0.0 + */ + public double realIO(double value) { + return GridSimRandom.realIO(value); + } + + /** + * A method that gets one process event at one time until the end + * of a simulation, then delivers an event to the entity (its parent) + * @pre $none + * @post $none + */ + public void body() + { + + //System.out.println("Hello FlowOutput"); + + // find out ids for entities that are not part of simulation network + // topology, such as GIS, GridSimShutdown and GridStatistics + int gisID = GridSim.getGridInfoServiceEntityId(); + int statID = GridSim.getGridStatisticsEntityId(); + int shutdownID = GridSim.getGridSimShutdownEntityId(); + + // start generating some junk packets or background traffic + startBackgroundTraffic(); + + // Process incoming events + while ( Sim_system.running() ) + { + Sim_event ev = new Sim_event(); + super.sim_get_next(ev); // get the next event in the queue + + // if the simulation finishes then exit the loop + if (ev.get_tag() == GridSimTags.END_OF_SIMULATION) { + break; + } + + System.out.println(super.get_name() + ".body(): ev.get_tag() is " + ev.get_tag()); + + // handle different types of incoming events + switch ( ev.get_tag() ) + { + case GridSimTags.SEND_PACKET: + System.out.println(super.get_name() + ".body(): sendPacket() + at time = " + GridSim.clock()); + sendPacket(); + break; + + // submit ping() request + case GridSimTags.INFOPKT_SUBMIT: + System.out.println(super.get_name() + ".body(): sendInfoPacket() + at time = " + GridSim.clock()); + sendInfoPacket(ev); + break; + + // replying ping() request from another entity + case GridSimTags.INFOPKT_RETURN: + System.out.println(super.get_name() + ".body(): returnInfoPacket() + at time = " + GridSim.clock()); + returnInfoPacket(ev); + break; + + // activate background traffic + case GridSimTags.JUNK_PKT: + generateBackgroundTraffic(); + break; + + case GridSimTags.PKT_FORWARD: + System.out.println(super.get_name() + ".body(): getDataFromLink() + at time = " + GridSim.clock()); + getDataFromLink(ev); + break; + + // Check if initial flow duration estimation was accurate + case GridSimTags.FLOW_HOLD: + System.out.println(super.get_name() + ".body(): checkForecast() + at time = " + GridSim.clock()); + checkForecast(ev); + break; + + default: + defaultSend(ev, gisID, statID, shutdownID); + break; + } + } + + System.out.println(super.get_name() + ":%%%% Exiting body() at time " + + GridSim.clock() ); + } + + private void checkForecast(Sim_event ev) { + int pktID = (Integer) ev.get_data(); + FlowPacket fp = null; + + System.out.println(super.get_name() + ".checkForecast(): checking pkt id # " + pktID); + + // If flow hasn't already finished + if ((fp = (FlowPacket) activeFlows_.get(pktID)) != null) { + Object data = fp.getData(); + IO_data io = new IO_data( data, fp.getSize(), + outPort_.get_src()); + super.sim_schedule(outPort_, GridSimTags.SCHEDULE_NOW, fp.getTag() , io.getData()); + } else { + System.out.println(super.get_name() + ".checkForecast(): pkt id # " + pktID + " already removed"); + + } + + } + + /** + * Generates few junk packets at the given interval + * @pre $none + * @post $none + */ + private synchronized void generateBackgroundTraffic() + { + // get the next inter-arrival time for these junk packets + long time = gen_.getNextPacketTime(); + + // get the sending pattern + int pattern = gen_.getPattern(); + + // for initial start-up, get the list of all resources first + if (hasStarted_ == false) + { + // get list of resource IDs from GIS + LinkedList resList = GridSim.getGridResourceList(); + + // if the list is empty then schedule the next time + if (resList == null && list_.size() == 0) + { + super.sim_schedule(super.get_id(), time, GridSimTags.JUNK_PKT); + return; + } + + hasStarted_ = true; + list_.addAll(resList); // add resource IDs into the current list + + // sets the sending pattern + if (pattern == TrafficGenerator.SEND_ONE_ONLY && random_ == null) { + random_ = new Random(); + } + } + + // get the required info for generating this background traffic + long size = gen_.getNextPacketSize(); // packet size + long freq = gen_.getNextPacketFreq(); // packet freq + int type = gen_.getServiceType(); // packet type + int tag = GridSimTags.JUNK_PKT; // packet tag + + // we need to packetsize the data, all packets are sent with size MTU. + // only the last packet contains the data, the receiver should + // throw away all other packets + int MTU = link_.getMTU(); + int numPackets = (int) Math.ceil( size / (MTU * 1.0) ); + + /********* // DEBUG info + System.out.println(); + System.out.println(super.get_name() + + ": START GENERATE BG traffic... at time "+ GridSim.clock()); + System.out.println(super.get_name() + + ": NEXT background traffic will start at " + time); + System.out.println(super.get_name() + + " num PACKETS = " + numPackets + ", freq = " + freq); + *********/ + + int i = 0; + int destId = -1; + + // send to one of the entity using uniform distribution + if (pattern == TrafficGenerator.SEND_ONE_ONLY) + { + int index = random_.nextInt( list_.size() ); + destId = ((Integer) list_.get(index)).intValue(); + + /********* // DEBUG info + System.out.println(super.get_name() + ": Destination id = " + + destId + " = " + GridSim.getEntityName(destId) ); + *********/ + + // create junk packets or empty FlowPacket. + for (i = 0; i < freq; i++) { + convertIntoPacket(MTU, numPackets+1, tag, destId, type); + } + } + // send to all resources + other entities + else if (pattern == TrafficGenerator.SEND_ALL) + { + // send to all resources and user entities + for (int k = 0; k < list_.size(); k++) + { + destId = ((Integer) list_.get(k)).intValue(); + + /********* // DEBUG info + System.out.println(super.get_name() + ": Destination id = " + + destId + " = " + GridSim.getEntityName(destId) ); + *********/ + + // create junk packets or empty FlowPacket. + for (i = 0; i < freq; i++) { + convertIntoPacket(MTU, numPackets+1, tag, destId, type); + } + } + } + + // sends the next junk packets + super.sim_schedule(super.get_id(), time, GridSimTags.JUNK_PKT); + } + + /** + * Initial start for the background traffic + * @pre $none + * @post $none + */ + private synchronized void startBackgroundTraffic() + { + // if no background traffic generator, then skip the rest + if (gen_ == null) { + return; + } + + // get the next inter-arrival time + long time = gen_.getNextPacketTime(); + System.out.println(super.get_name() + + ": background traffic will start at time " + time); + + // starts background traffic if the inter-arrival time is valid + if (time == -1) { + return; + } + + super.sim_schedule(super.get_id(), time, GridSimTags.JUNK_PKT); + } + + /** + * This method processes outgoing data without a network extension. + * @param ev a Sim_event object + * @param gisID the central/default GIS entity ID + * @param statID the GridStatistic entity ID + * @param shutdownID the GridSimShutdown entity ID + * @pre ev != null + * @post $none + */ + private synchronized void defaultSend(Sim_event ev, int gisID, int statID, + int shutdownID) + { + IO_data io = (IO_data) ev.get_data(); + int destId = io.getDestID(); + + /***** // DEBUG info*/ + System.out.println(super.get_name() + ".defaultSend(): Send to " + + GridSim.getEntityName(destId) + " tag = " + ev.get_tag() + " at time = " + GridSim.clock()); + /*****/ + + // if this entity uses a network extension + if (link_ != null && destId != gisID && destId != statID && + destId != shutdownID) + { + System.out.println(super.get_name() + ".defaultSend(): submitToLink() + at time = " + GridSim.clock()); + submitToLink(ev); + return; + } + + // Identify ID of an entity which acts as Input/Buffer + // entity of destination entity + int id = GridSim.getEntityId( "Input_" + + Sim_system.get_entity(destId).get_name() ); + + // Send first and then hold + super.sim_schedule(id, GridSimTags.SCHEDULE_NOW, ev.get_tag(), io); + + double receiverBaudRate = ( (FlowBuffer) + Sim_system.get_entity(id) ).getBaudRate(); + + // NOTE: io is in byte and baud rate is in bits. 1 byte = 8 bits + // So, convert io into bits + double minBaudRate = Math.min(baudRate_, receiverBaudRate); + double communicationDelay = GridSimRandom.realIO( + (io.getByteSize() * BITS) / minBaudRate); + + // NOTE: Below is a deprecated method for SimJava 2 + //super.sim_hold(communicationDelay); + super.sim_process(communicationDelay); + } + + /** + * This method takes data from an entity. If the size of the data is larger + * than the MTU of the link, then the packet is split into mutiple size + * units. After this it calls outEnque() to queue these packets into its + * buffer. + * + * @param ev A Sim_event data that contains all the data for this method + * to do its task. + * @pre ev != null + * @post $none + */ + private synchronized void submitToLink(Sim_event ev) + { + IO_data data = (IO_data) ev.get_data(); + Object obj = data.getData(); + long size = data.getByteSize(); + int tag = ev.get_tag(); + int destId = data.getDestID(); + int netServiceType = data.getNetServiceLevel(); + + // we need to packetsize the data, all packets are sent with size MTU. + // only the last packet contains the data, the receiver should + // throw away all other packets + //int MTU = link_.getMTU(); + //int numPackets = (int) Math.ceil( size / (MTU * 1.0) ); + + // make dummy packets with null data + //System.out.println("Packetizing data, creating " + numPackets + " dummy packets at time = " + GridSim.clock()); + //convertIntoPacket(MTU, numPackets, tag, destId, netServiceType); + + // last packet contains the actual data + FlowPacket np = null; + np = new FlowPacket(obj,pktID_,size,tag,super.get_id(), + destId, netServiceType, 1, 1); + + System.out.println("Sending flow packet to link at time = " + GridSim.clock() + " id is " + pktID_); + pktID_++; // increments packet ID + outEnque(np, GridSimTags.SCHEDULE_NOW); + } + + /** + * Creates many dummy or null packets + * @param size packet size (in bytes) + * @param numPackets total number of packets to be created + * @param tag packet tag + * @param destId destination ID for sending the packet + * @param netServiceType level type of service for the packet + * @pre $none + * @post $none + */ + private synchronized void convertIntoPacket(long size, int numPackets, + int tag, int destId, int netServiceType) + { + FlowPacket np = null; + for (int i = 0; i < numPackets - 1; i++) + { + // change the tag name for dummy packets, apart from junk packets + if (tag != GridSimTags.JUNK_PKT) { + tag = GridSimTags.EMPTY_PKT; + } + + np = new FlowPacket(null, pktID_, size, tag, super.get_id(), destId, + netServiceType, i+1, numPackets); + + pktID_++; // increments packet ID + outEnque(np, GridSimTags.SCHEDULE_NOW); + } + } + + /** + * Sends an InfoPacket for ping request + * @param ev a Sim_Event object + * @pre ev != null + * @post $none + */ + private synchronized void sendInfoPacket(Sim_event ev) + { + IO_data data = (IO_data) ev.get_data(); + + // gets all the relevant info + long size = data.getByteSize(); + int destId = data.getDestID(); + int netServiceType = data.getNetServiceLevel(); + int tag = ev.get_tag(); + String name = GridSim.getEntityName( outPort_.get_dest() ); + + // we need to packetsize the data, all packets are sent with size MTU + // only the last packet contains the ping data, the receiver should + // throw away all other data + int MTU = link_.getMTU(); + int numPackets = (int) Math.ceil( size / (MTU * 1.0) ); + + // break ping size into smaller pieces + // Also, make sure that it is not for pinging itself + if (size > MTU && outPort_.get_dest() != destId) + { + // make dummy packets with null data + convertIntoPacket(MTU, numPackets, tag, destId, netServiceType); + } + + // get the remaining ping size + size = data.getByteSize() - MTU*(numPackets-1); + + // create the real InfoPacket + InfoPacket pkt = new InfoPacket(name,pktID_,size,outPort_.get_dest(), + destId,netServiceType); + + // set the required info + pkt.setLast( super.get_id() ); + pkt.addHop( outPort_.get_dest() ); + pkt.addEntryTime( GridSim.clock() ); + pkt.setOriginalPingSize( data.getByteSize() ); + + pktID_++; // increments packet ID + outEnque(pkt, GridSimTags.SCHEDULE_NOW); + } + + private synchronized void sendInfoPacket(int dest) + { + // IO_data data = (IO_data) ev.get_data(); + + // gets all the relevant info + long size = 1500; + int destId = dest; +// / int netServiceType = data.getNetServiceLevel(); + // int tag = ev.get_tag(); + String name = GridSim.getEntityName( outPort_.get_dest() ); + + // we need to packetsize the data, all packets are sent with size MTU + // only the last packet contains the ping data, the receiver should + // throw away all other data + // int MTU = link_.getMTU(); + // int numPackets = (int) Math.ceil( size / (MTU * 1.0) ); + + // break ping size into smaller pieces + // Also, make sure that it is not for pinging itself + //if (size > MTU && outPort_.get_dest() != destId) + //{ + // // make dummy packets with null data + // convertIntoPacket(MTU, numPackets, tag, destId, netServiceType); + //} + + // get the remaining ping size + //size = data.getByteSize() - MTU*(numPackets-1); + + // create the real InfoPacket + InfoPacket pkt = new InfoPacket(name,pktID_,size,outPort_.get_dest(), + destId,0); + + // set the required info + pkt.setLast( super.get_id() ); + pkt.addHop( outPort_.get_dest() ); + pkt.addEntryTime( GridSim.clock() ); + pkt.setOriginalPingSize( 1500 ); + pkt.setTag(GridSimTags.INFOPKT_SUBMIT); + + pktID_++; // increments packet ID + outEnque(pkt, GridSimTags.SCHEDULE_NOW); + } + + /** + * Sends back the ping() request to the next hop or destination + * @param ev a Sim_event object + * @pre ev != null + * @post $none + */ + private void returnInfoPacket(Sim_event ev) + { + IO_data data = (IO_data) ev.get_data(); + + // use the original ping size rather than IO_data or InfoPacket size + // since the latter is restricted to MTU + InfoPacket pkt = (InfoPacket) data.getData(); + long size = pkt.getOriginalPingSize(); + + // get other relevant info + int tag = ev.get_tag(); + int destId = pkt.getSrcID(); + int netServiceType = data.getNetServiceLevel(); + + // we need to packetsize the data, all packets are sent with size MTU. + // only the last packet contains the data, the receiver should + // throw away all other packets + int MTU = link_.getMTU(); + int numPackets = (int) Math.ceil( size / (MTU * 1.0) ); + + // make dummy packets with null data + convertIntoPacket(MTU, numPackets, tag, destId, netServiceType); + + // set the original packet of last hop into this entity id + pkt.setLast( super.get_id() ); + outEnque(pkt, GridSimTags.SCHEDULE_NOW); + } + + /** + * Takes a packet, adds it into a buffer and schedules it to be sent out at + * an appropriate time. + * + * @param pkt The packet to be buffered + * @param delay The length of time this packet should be delayed (exclusive + * of the transmission time) + * @pre pkt != null + * @pre delay > 0 + * @post $none + */ + private synchronized void outEnque(Packet pkt, double delay) + { + + //if ((pkt instanceof InfoPacket) != true) { + // sendInfoPacket(pkt.getDestID()); + //} + + outPacketList_.add(pkt); + if (outPacketList_.size() == 1) + { + System.out.println(super.get_name() + ".outEnque() Size is " + pkt.getSize() + " baud " + link_.getBaudRate()); + // Compute expected duration of flow using bottleneck baudRate + // double total = delay + (pkt.getSize()*SIZE / link_.getBaudRate()); + double total = 0.0; + + System.out.println(super.get_name() + ".outEnque() Time now " + GridSim.clock() + " delay is " + total); + super.sim_schedule(super.get_id(), total, GridSimTags.SEND_PACKET); + } + + + + + } + + + /** + * Removes a single packet from the buffer and sends it down the link. + * Then, schedules the next packet in the list. + * @pre $none + * @post $none + */ + private synchronized void sendPacket() + { + if (outPacketList_ == null || outPacketList_.isEmpty() == true) { + return; + } + + // submits the first packet in the list + Packet np = (Packet) outPacketList_.remove(0); + + boolean ping = false; // a flag to determine ping packet or not + int tag = -1; // event tag ID + int dest = -1; // destination ID + + // if a packet belongs to a ping packet + if (np instanceof InfoPacket) + { + ((InfoPacket)np).addExitTime( GridSim.clock() ); + ((InfoPacket)np).addBaudRate( link_.getBaudRate() ); + ping = true; + tag = GridSimTags.INFOPKT_SUBMIT; + } + + if (np instanceof FlowPacket && np.getTag() == GridSimTags.FLOW_SUBMIT ) { + ((FlowPacket)np).addBaudRate( link_.getBaudRate() ); + ((FlowPacket)np).addLatency( link_.getDelay() ); + } + + + // if an entity tries to send a packet to itself + if ( np.getDestID() == outPort_.get_dest() ) + { + // then change the destination name and id + String destName = super.get_name(); + destName = destName.replaceFirst("Output", "Input"); + dest = Sim_system.get_entity_id(destName); + + // for a ping packet, change the tag + if (ping == true) + { + // don't forget to change the packet tag + tag = GridSimTags.INFOPKT_RETURN; + ((InfoPacket) np).setTag(tag); + } + else { + tag = np.getTag(); + } + } + else // if an entity tries to send to other entity + { + // change or keep the event tag + tag = GridSimTags.PKT_FORWARD; + if (np.getTag() == GridSimTags.JUNK_PKT) { + tag = GridSimTags.JUNK_PKT; + } + + // sends the packet into the link + dest = link_.get_id(); + } + + // send the packet + super.sim_schedule(dest, GridSimTags.SCHEDULE_NOW, tag, np); + + /***** // DEBUG info **/ + System.out.println(super.get_name() + " send to " + + GridSim.getEntityName(dest) + " tag = " + tag + " time " + GridSim.clock()); + /****/ + + // if the list is not empty, then schedule the next packet in the list + if (outPacketList_.isEmpty() != true) + { + //double delay = np.getSize() * SIZE / link_.getBaudRate(); + double delay = 0.0; + super.sim_schedule(super.get_id(), delay, GridSimTags.SEND_PACKET); + } + } + + private void getDataFromLink(Sim_event ev) + { + Object obj = ev.get_data(); + double duration = 0.0; + + if (obj instanceof Packet) + { + // decrypt the packet into original format + Packet pkt = (Packet) ev.get_data(); + + if (pkt instanceof InfoPacket) + { + processPingRequest( (InfoPacket) pkt); + return; + } + + // all except last packet in a data session are null packets + if (pkt instanceof FlowPacket) + { + FlowPacket np = (FlowPacket) pkt; + int tag = np.getTag(); + System.out.println("Packet id is " + np.getID()); + + // ignore incoming junk packets + if (tag == GridSimTags.JUNK_PKT) { + return; + } + + // ignore incoming null dummy packets + if (tag == GridSimTags.EMPTY_PKT && np.getData() == null) { + return; + } + + // convert the packets into IO_data + Object data = np.getData(); + IO_data io = new IO_data( data, np.getSize(), + outPort_.get_src()); + System.out.println(super.get_name() + ".getDataFromLink() Time now " + GridSim.clock() + + " bottleneck was " + np.getBandwidth_() + " sum lat is " + np.getLatency() ); + + // if flow terminates at next entity, add to active flows + // & hold for appropriate duration + if (pkt.getTag() == GridSimTags.FLOW_SUBMIT) { + duration = np.getSize()*SIZE / np.getBandwidth_(); + activeFlows_.put(pkt.getID(), pkt); + super.sim_schedule(super.get_id(), duration, GridSimTags.FLOW_HOLD, new Integer(pkt.getID())); + + // if flow is just an ACK of a finished flow do not hold + } else if (pkt.getTag() == GridSimTags.FLOW_RETURN){ + duration = 0.0; + // send the data into entity input port + super.sim_schedule(outPort_, duration, tag, + io.getData() ); + } + + + } + } + } + + private void processPingRequest(InfoPacket pkt) + { + // add more information to ping() packet + pkt.addHop( outPort_.get_dest() ); + pkt.addEntryTime( GridSim.clock() ); + + IO_data io = new IO_data( pkt, pkt.getSize(), outPort_.get_dest() ); + + // send this ping() packet to the entity + super.sim_schedule(outPort_, GridSimTags.SCHEDULE_NOW, + pkt.getTag(), io.getData()); + } + +} // end class + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bro...@us...> - 2008-02-21 05:33:46
|
Revision: 117 http://gridsim.svn.sourceforge.net/gridsim/?rev=117&view=rev Author: brobergj Date: 2008-02-20 21:33:52 -0800 (Wed, 20 Feb 2008) Log Message: ----------- *Added FLOW_UPDATE support, supporting methods Modified Paths: -------------- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java Modified: branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java =================================================================== --- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-02-21 03:43:39 UTC (rev 116) +++ branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-02-21 05:33:52 UTC (rev 117) @@ -11,6 +11,7 @@ import gridsim.*; import gridsim.net.*; +import gridsim.net.flow.*; import gridsim.util.*; import eduni.simjava.*; @@ -76,6 +77,8 @@ list_ = null; random_ = null; hasStarted_ = false; + + System.out.println("Initialising FB id " + super.get_id() + " name " + super.get_name()); } /** @@ -300,6 +303,11 @@ System.out.println(super.get_name() + ".body(): checkForecast() + at time = " + GridSim.clock()); checkForecast(ev); break; + + case GridSimTags.FLOW_UPDATE: + System.out.println(super.get_name() + ".body(): updateForecast() + at time = " + GridSim.clock()); + updateForecast(ev); + break; default: defaultSend(ev, gisID, statID, shutdownID); @@ -311,7 +319,7 @@ GridSim.clock() ); } - private void checkForecast(Sim_event ev) { + private synchronized void checkForecast(Sim_event ev) { int pktID = (Integer) ev.get_data(); FlowPacket fp = null; @@ -323,13 +331,56 @@ IO_data io = new IO_data( data, fp.getSize(), outPort_.get_src()); super.sim_schedule(outPort_, GridSimTags.SCHEDULE_NOW, fp.getTag() , io.getData()); + activeFlows_.remove(pktID); } else { System.out.println(super.get_name() + ".checkForecast(): pkt id # " + pktID + " already removed"); } } + + private synchronized void updateForecast(Sim_event ev) { + int pktID = (Integer) ev.get_data(); // ID of flow to be updated + FlowPacket fp = null; // Reference to flow packet that needs forecast update + double duration = 0.0; // New forecast from current Gridsim.clock() + long remSizeOld = 0; // Previous remaining size + double bandwidthOld = 0.0; // Previous bottleneck BW + int sourceID = ev.get_src(); // ID of source of notification (FlowLink) + int cancelledFlow = 0; // Count of canceled future events that match old forecast + + System.out.println(super.get_name() + ".updateForecast(): updating pkt id # " + pktID); + // If flow hasn't already finished and been cleared... + if ((fp = (FlowPacket) activeFlows_.get(pktID)) != null) { + remSizeOld = fp.getRemSize(); + bandwidthOld = fp.getBandwidth_(); + System.out.println(super.get_name() + " rem size is " + remSizeOld + "BW old is " + bandwidthOld); + Iterator it = (fp.getLinks_()).iterator(); + + while (it.hasNext()) { + FlowLink fl = (FlowLink) it.next(); + if (fl.get_id() == sourceID) { + fp.setBandwidth_(fl.getBaudRate()); + fp.setBottleneckID(sourceID); + } + } + + fp.setRemSize((long)(remSizeOld*BITS - (GridSim.clock()-fp.getUpdateTime())*bandwidthOld)); + duration = fp.getRemSize()/fp.getBandwidth_(); + System.out.println(super.get_name() + " new remaining duration add " + duration); + + FilterFlow filter = new FilterFlow(fp.getID(), GridSimTags.FLOW_HOLD); + cancelledFlow = this.sim_cancel(filter, null); + + if (cancelledFlow != 0) { + System.out.println(super.get_name() + ".updateForecast(): old forecast cancelled"); + } + + + super.sim_schedule(super.get_id(), duration, GridSimTags.FLOW_HOLD , new Integer(fp.getID())); + } + } + /** * Generates few junk packets at the given interval * @pre $none @@ -764,10 +815,10 @@ tag = GridSimTags.INFOPKT_SUBMIT; } - if (np instanceof FlowPacket && np.getTag() == GridSimTags.FLOW_SUBMIT ) { - ((FlowPacket)np).addBaudRate( link_.getBaudRate() ); - ((FlowPacket)np).addLatency( link_.getDelay() ); - } + //if (np instanceof FlowPacket && np.getTag() == GridSimTags.FLOW_SUBMIT ) { + // ((FlowPacket)np).addBaudRate( link_.getBaudRate() ); + // ((FlowPacket)np).addLatency( link_.getDelay() ); + //} // if an entity tries to send a packet to itself @@ -861,9 +912,11 @@ // if flow terminates at next entity, add to active flows // & hold for appropriate duration if (pkt.getTag() == GridSimTags.FLOW_SUBMIT) { - duration = np.getSize()*SIZE / np.getBandwidth_(); - activeFlows_.put(pkt.getID(), pkt); - super.sim_schedule(super.get_id(), duration, GridSimTags.FLOW_HOLD, new Integer(pkt.getID())); + np.setStartTime(GridSim.clock()); + np.setUpdateTime(GridSim.clock()); + duration = np.getSize()*SIZE / np.getBandwidth_(); + activeFlows_.put(pkt.getID(), pkt); + super.sim_schedule(super.get_id(), duration, GridSimTags.FLOW_HOLD, new Integer(pkt.getID())); // if flow is just an ACK of a finished flow do not hold } else if (pkt.getTag() == GridSimTags.FLOW_RETURN){ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bro...@us...> - 2008-02-22 02:10:28
|
Revision: 122 http://gridsim.svn.sourceforge.net/gridsim/?rev=122&view=rev Author: brobergj Date: 2008-02-21 18:10:33 -0800 (Thu, 21 Feb 2008) Log Message: ----------- *Added comments and javadoc Modified Paths: -------------- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java Modified: branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java =================================================================== --- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-02-22 02:10:20 UTC (rev 121) +++ branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-02-22 02:10:33 UTC (rev 122) @@ -4,14 +4,13 @@ * of Parallel and Distributed Systems such as Clusters and Grids * Licence: GPL - http://www.gnu.org/copyleft/gpl.html * - * Author: James Broberg & Anthony Sulistio (Adapted from original Output.java) + * Author: James Broberg & Anthony Sulistio (Adapted from original Input.java & Output.java) */ package gridsim.net.flow; import gridsim.*; import gridsim.net.*; -import gridsim.net.flow.*; import gridsim.util.*; import eduni.simjava.*; @@ -20,17 +19,14 @@ /** - * GridSim Output defines a port through which a simulation entity sends - * data to the simulated network. + * GridSim FlowBuffer defines a port through which a simulation entity sends + * and receives data to the simulated network using flow networking principles. * <p> * It maintains an event queue to serialize - * the data-out-flow and delivers to the destination entity. - * It works along with Input entity to simulate network - * communication delay. Simultaneous outputs can be modeled by using multiple - * instances of this class + * the data-out-flow and data-in-flow and delivers to the destination entity. * - * @author Manzur Murshed and Rajkumar Buyya - * @since GridSim Toolkit 1.0 + * @author James Broberg + * @since GridSim Toolkit 4.0 * @invariant $none */ public class FlowBuffer extends Sim_entity implements NetIO @@ -50,7 +46,7 @@ /** - * Allocates a new Output object + * Allocates a new FlowBuffer object * @param name the name of this object * @param baudRate the communication speed * @throws NullPointerException This happens when creating this entity @@ -91,6 +87,8 @@ * @pre gen != null * @post $none */ + + // TODO: Background traffic not yet implemented, do not use! public boolean setBackgroundTraffic(TrafficGenerator gen) { if (gen == null) { @@ -119,6 +117,8 @@ * @pre userName != null * @post $none */ + + // TODO: Background traffic not yet implemented, do not use! public boolean setBackgroundTraffic(TrafficGenerator gen, Collection userName) { @@ -179,7 +179,7 @@ * Sets this entity's link. This should be used only if the network * extensions are being used. * - * @param link the link to which this Output entity should send data + * @param link the link to which this FlowBuffer entity should send data * @pre link != null * @post $none */ @@ -244,8 +244,6 @@ public void body() { - //System.out.println("Hello FlowOutput"); - // find out ids for entities that are not part of simulation network // topology, such as GIS, GridSimShutdown and GridStatistics int gisID = GridSim.getGridInfoServiceEntityId(); @@ -253,7 +251,7 @@ int shutdownID = GridSim.getGridSimShutdownEntityId(); // start generating some junk packets or background traffic - startBackgroundTraffic(); + // startBackgroundTraffic(); // Process incoming events while ( Sim_system.running() ) @@ -303,7 +301,8 @@ System.out.println(super.get_name() + ".body(): checkForecast() + at time = " + GridSim.clock()); checkForecast(ev); break; - + + // Update flow duration forecase case GridSimTags.FLOW_UPDATE: System.out.println(super.get_name() + ".body(): updateForecast() + at time = " + GridSim.clock()); updateForecast(ev); @@ -319,13 +318,20 @@ GridSim.clock() ); } + /** + * Check the forecast of a flow, and send data to output port if flow still exists + * + * @param ev the flow hold notification event + * @pre ev != null + * @post $none + */ private synchronized void checkForecast(Sim_event ev) { - int pktID = (Integer) ev.get_data(); - FlowPacket fp = null; + int pktID = (Integer) ev.get_data(); // ID of flow to be checked + FlowPacket fp = null; // Reference to flow packet that needs forecast update System.out.println(super.get_name() + ".checkForecast(): checking pkt id # " + pktID); - // If flow hasn't already finished + // If flow hasn't already finished, send it to outPort if ((fp = (FlowPacket) activeFlows_.get(pktID)) != null) { Object data = fp.getData(); IO_data io = new IO_data( data, fp.getSize(), @@ -339,10 +345,18 @@ } + /** + * Update the forecast of a flow, delete the old forecast and schedule a new flow hold + * event in the future with the corrected forecast + * + * @param ev the flow update notification event + * @pre ev != null + * @post $none + */ private synchronized void updateForecast(Sim_event ev) { int pktID = (Integer) ev.get_data(); // ID of flow to be updated FlowPacket fp = null; // Reference to flow packet that needs forecast update - double duration = 0.0; // New forecast from current Gridsim.clock() + double duration = 0.0; // New forecast duration from current Gridsim.clock() long remSizeOld = 0; // Previous remaining size double bandwidthOld = 0.0; // Previous bottleneck BW int sourceID = ev.get_src(); // ID of source of notification (FlowLink) @@ -354,7 +368,7 @@ if ((fp = (FlowPacket) activeFlows_.get(pktID)) != null) { remSizeOld = fp.getRemSize(); bandwidthOld = fp.getBandwidth_(); - System.out.println(super.get_name() + " rem size is " + remSizeOld + "BW old is " + bandwidthOld); + System.out.println(super.get_name() + "updateForecast(): rem size is " + remSizeOld + "BW old is " + bandwidthOld); Iterator it = (fp.getLinks_()).iterator(); while (it.hasNext()) { @@ -486,6 +500,7 @@ * @pre $none * @post $none */ + // TODO: Background traffic not yet implemented, do not use! private synchronized void startBackgroundTraffic() { // if no background traffic generator, then skip the rest @@ -632,6 +647,7 @@ * @pre ev != null * @post $none */ + // TODO: Untested in flow model, and probably not useful private synchronized void sendInfoPacket(Sim_event ev) { IO_data data = (IO_data) ev.get_data(); @@ -673,56 +689,14 @@ pktID_++; // increments packet ID outEnque(pkt, GridSimTags.SCHEDULE_NOW); } - - private synchronized void sendInfoPacket(int dest) - { - // IO_data data = (IO_data) ev.get_data(); - // gets all the relevant info - long size = 1500; - int destId = dest; -// / int netServiceType = data.getNetServiceLevel(); - // int tag = ev.get_tag(); - String name = GridSim.getEntityName( outPort_.get_dest() ); - - // we need to packetsize the data, all packets are sent with size MTU - // only the last packet contains the ping data, the receiver should - // throw away all other data - // int MTU = link_.getMTU(); - // int numPackets = (int) Math.ceil( size / (MTU * 1.0) ); - - // break ping size into smaller pieces - // Also, make sure that it is not for pinging itself - //if (size > MTU && outPort_.get_dest() != destId) - //{ - // // make dummy packets with null data - // convertIntoPacket(MTU, numPackets, tag, destId, netServiceType); - //} - - // get the remaining ping size - //size = data.getByteSize() - MTU*(numPackets-1); - - // create the real InfoPacket - InfoPacket pkt = new InfoPacket(name,pktID_,size,outPort_.get_dest(), - destId,0); - - // set the required info - pkt.setLast( super.get_id() ); - pkt.addHop( outPort_.get_dest() ); - pkt.addEntryTime( GridSim.clock() ); - pkt.setOriginalPingSize( 1500 ); - pkt.setTag(GridSimTags.INFOPKT_SUBMIT); - - pktID_++; // increments packet ID - outEnque(pkt, GridSimTags.SCHEDULE_NOW); - } - /** * Sends back the ping() request to the next hop or destination * @param ev a Sim_event object * @pre ev != null * @post $none */ + // TODO: Untested in flow model, and probably not useful private void returnInfoPacket(Sim_event ev) { IO_data data = (IO_data) ev.get_data(); @@ -765,9 +739,6 @@ private synchronized void outEnque(Packet pkt, double delay) { - //if ((pkt instanceof InfoPacket) != true) { - // sendInfoPacket(pkt.getDestID()); - //} outPacketList_.add(pkt); if (outPacketList_.size() == 1) @@ -779,10 +750,7 @@ System.out.println(super.get_name() + ".outEnque() Time now " + GridSim.clock() + " delay is " + total); super.sim_schedule(super.get_id(), total, GridSimTags.SEND_PACKET); - } - - - + } } @@ -869,6 +837,13 @@ } } + /** + * Process incoming events from senders that are using the network + * extension + * @param ev a Sim_event object + * @pre ev != null + * @post $none + */ private void getDataFromLink(Sim_event ev) { Object obj = ev.get_data(); @@ -921,7 +896,7 @@ // if flow is just an ACK of a finished flow do not hold } else if (pkt.getTag() == GridSimTags.FLOW_RETURN){ duration = 0.0; - // send the data into entity input port + // send the data into entity input/output port super.sim_schedule(outPort_, duration, tag, io.getData() ); } @@ -931,6 +906,13 @@ } } + /** + * Processes a ping request + * @param pkt a packet for pinging + * @pre pkt != null + * @post $none + */ + // TODO: Untested in flow model, and probably not useful private void processPingRequest(InfoPacket pkt) { // add more information to ping() packet This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bro...@us...> - 2008-02-25 01:14:09
|
Revision: 127 http://gridsim.svn.sourceforge.net/gridsim/?rev=127&view=rev Author: brobergj Date: 2008-02-24 17:14:13 -0800 (Sun, 24 Feb 2008) Log Message: ----------- *Changed pktID to static int as it must be unique amongst all flows from all sources! Modified Paths: -------------- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java Modified: branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java =================================================================== --- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-02-22 04:36:44 UTC (rev 126) +++ branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-02-25 01:14:13 UTC (rev 127) @@ -35,7 +35,7 @@ private Link link_; // a link to this output entity private double baudRate_; // baud rate of this entity private final int SIZE = 8; // 1 byte in bits - private int pktID_; // packet ID counter + private static int pktID_; // unique packet ID counter private Vector outPacketList_; // store a list of packets private HashMap<Integer, Packet> activeFlows_; // stores a list of active Flows private Random random_; // selects to which junk packets go to @@ -860,7 +860,6 @@ return; } - // all except last packet in a data session are null packets if (pkt instanceof FlowPacket) { FlowPacket np = (FlowPacket) pkt; @@ -882,7 +881,7 @@ IO_data io = new IO_data( data, np.getSize(), outPort_.get_src()); System.out.println(super.get_name() + ".getDataFromLink() Time now " + GridSim.clock() - + " bottleneck was " + np.getBandwidth_() + " sum lat is " + np.getLatency() ); + + " bottleneck is " + np.getBandwidth_() + " sum lat is " + np.getLatency() ); // if flow terminates at next entity, add to active flows // & hold for appropriate duration @@ -892,7 +891,9 @@ duration = np.getSize()*SIZE / np.getBandwidth_(); activeFlows_.put(pkt.getID(), pkt); super.sim_schedule(super.get_id(), duration, GridSimTags.FLOW_HOLD, new Integer(pkt.getID())); - + System.out.println(super.get_name() + ".getDataFromLink() forecast flow end at " + (GridSim.clock() + + duration)); + // if flow is just an ACK of a finished flow do not hold } else if (pkt.getTag() == GridSimTags.FLOW_RETURN){ duration = 0.0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bro...@us...> - 2008-02-26 04:39:22
|
Revision: 128 http://gridsim.svn.sourceforge.net/gridsim/?rev=128&view=rev Author: brobergj Date: 2008-02-25 20:39:24 -0800 (Mon, 25 Feb 2008) Log Message: ----------- *FlowBuffer now handles the Acks for FlowPackets, after they have been held the appropriate duration Modified Paths: -------------- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java Modified: branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java =================================================================== --- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-02-25 01:14:13 UTC (rev 127) +++ branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-02-26 04:39:24 UTC (rev 128) @@ -35,7 +35,7 @@ private Link link_; // a link to this output entity private double baudRate_; // baud rate of this entity private final int SIZE = 8; // 1 byte in bits - private static int pktID_; // unique packet ID counter + private static int pktID_ = 0; // packet ID counter private Vector outPacketList_; // store a list of packets private HashMap<Integer, Packet> activeFlows_; // stores a list of active Flows private Random random_; // selects to which junk packets go to @@ -63,7 +63,7 @@ link_ = null; outPacketList_ = null; activeFlows_ = null; - pktID_ = 0; + //pktID_ = 0; outPort_ = new Sim_port("output_buffer"); super.add_port(outPort_); @@ -74,7 +74,7 @@ random_ = null; hasStarted_ = false; - System.out.println("Initialising FB id " + super.get_id() + " name " + super.get_name()); + System.out.println("Initialising FlowBuffer id " + super.get_id() + " name " + super.get_name()); } /** @@ -307,6 +307,10 @@ System.out.println(super.get_name() + ".body(): updateForecast() + at time = " + GridSim.clock()); updateForecast(ev); break; + + case GridSimTags.FLOW_RETURN: + submitAckToLink(ev); + break; default: defaultSend(ev, gisID, statID, shutdownID); @@ -328,6 +332,7 @@ private synchronized void checkForecast(Sim_event ev) { int pktID = (Integer) ev.get_data(); // ID of flow to be checked FlowPacket fp = null; // Reference to flow packet that needs forecast update + FlowPacket fpAck = null; System.out.println(super.get_name() + ".checkForecast(): checking pkt id # " + pktID); @@ -337,7 +342,23 @@ IO_data io = new IO_data( data, fp.getSize(), outPort_.get_src()); super.sim_schedule(outPort_, GridSimTags.SCHEDULE_NOW, fp.getTag() , io.getData()); - activeFlows_.remove(pktID); + activeFlows_.remove(pktID); + + // Send ack to source of flow + System.out.println(super.get_name() + ".checkForecast(): flow came from " + GridSim.getEntityName(fp.getSrcID()) + + " heading to " + GridSim.getEntityName(fp.getDestID())); + int oldDestID = fp.getDestID(); + int oldSrcID = fp.getSrcID(); + + IO_data ackData = new IO_data(fp.getData(), fp.getSize(), oldSrcID - 1); + fpAck = new FlowPacket(ackData,fp.getID(),fp.getSize(),GridSimTags.FLOW_RETURN,super.get_id(), + oldSrcID - 1, fp.getNetServiceType(), 1, 1); + fpAck.setRemSize(0); + fpAck.setStartTime(fp.getStartTime()); + fpAck.setLatency(fp.getLatency()); + + super.sim_schedule(super.get_id(), GridSimTags.SCHEDULE_NOW, GridSimTags.FLOW_RETURN, fpAck); + } else { System.out.println(super.get_name() + ".checkForecast(): pkt id # " + pktID + " already removed"); @@ -550,7 +571,7 @@ return; } - // Identify ID of an entity which acts as Input/Buffer +/* // Identify ID of an entity which acts as Input/Buffer // entity of destination entity int id = GridSim.getEntityId( "Input_" + Sim_system.get_entity(destId).get_name() ); @@ -569,7 +590,7 @@ // NOTE: Below is a deprecated method for SimJava 2 //super.sim_hold(communicationDelay); - super.sim_process(communicationDelay); + super.sim_process(communicationDelay);*/ } /** @@ -611,7 +632,15 @@ pktID_++; // increments packet ID outEnque(np, GridSimTags.SCHEDULE_NOW); } + + private synchronized void submitAckToLink(Sim_event ev) + { + FlowPacket fp = (FlowPacket)ev.get_data(); + System.out.println("Sending flow packet ack to link at time = " + GridSim.clock() + " id is " + pktID_); + outEnque(fp, GridSimTags.SCHEDULE_NOW); + } + /** * Creates many dummy or null packets * @param size packet size (in bytes) @@ -782,12 +811,6 @@ ping = true; tag = GridSimTags.INFOPKT_SUBMIT; } - - //if (np instanceof FlowPacket && np.getTag() == GridSimTags.FLOW_SUBMIT ) { - // ((FlowPacket)np).addBaudRate( link_.getBaudRate() ); - // ((FlowPacket)np).addLatency( link_.getDelay() ); - //} - // if an entity tries to send a packet to itself if ( np.getDestID() == outPort_.get_dest() ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sul...@us...> - 2008-03-19 08:30:52
|
Revision: 162 http://gridsim.svn.sourceforge.net/gridsim/?rev=162&view=rev Author: sulistio Date: 2008-03-19 01:30:54 -0700 (Wed, 19 Mar 2008) Log Message: ----------- remove this class since it is not used any more. Instead FlowInput and FlowOutput will take over the functionalities of this class. Removed Paths: ------------- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java Deleted: branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java =================================================================== --- branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-03-18 00:40:38 UTC (rev 161) +++ branches/gridsim4.0-branch2/source/gridsim/net/flow/FlowBuffer.java 2008-03-19 08:30:54 UTC (rev 162) @@ -1,954 +0,0 @@ -/* - * Title: GridSim Toolkit - * Description: GridSim (Grid Simulation) Toolkit for Modeling and Simulation - * of Parallel and Distributed Systems such as Clusters and Grids - * Licence: GPL - http://www.gnu.org/copyleft/gpl.html - * - * Author: James Broberg & Anthony Sulistio (Adapted from original Input.java & Output.java) - */ - -package gridsim.net.flow; - -import gridsim.*; -import gridsim.net.*; -import gridsim.util.*; - -import eduni.simjava.*; - -import java.util.*; - - -/** - * GridSim FlowBuffer defines a port through which a simulation entity sends - * and receives data to the simulated network using flow networking principles. - * <p> - * It maintains an event queue to serialize - * the data-out-flow and data-in-flow and delivers to the destination entity. - * - * @author James Broberg - * @since GridSim Toolkit 4.0 - * @invariant $none - */ -public class FlowBuffer extends Sim_entity implements NetIO -{ - private Sim_port outPort_; // output port - private Link link_; // a link to this output entity - private double baudRate_; // baud rate of this entity - private final int SIZE = 8; // 1 byte in bits - private static int pktID_ = 0; // packet ID counter - private Vector outPacketList_; // store a list of packets - private HashMap<Integer, Packet> activeFlows_; // stores a list of active Flows - private Random random_; // selects to which junk packets go to - private TrafficGenerator gen_; // background traffic generator - private ArrayList list_; // list of resources + user entities - private boolean hasStarted_; // a flag for background traffic has started - private static final int BITS = 8; // 1 byte = 8 bits - - - /** - * Allocates a new FlowBuffer object - * @param name the name of this object - * @param baudRate the communication speed - * @throws NullPointerException This happens when creating this entity - * before initializing GridSim package or this entity name - * is <tt>null</tt> or empty - * @pre name != null - * @pre baudRate >= 0.0 - * @post $none - */ - public FlowBuffer(String name, double baudRate) throws NullPointerException - { - super(name); - this.baudRate_ = baudRate; - link_ = null; - outPacketList_ = null; - activeFlows_ = null; - //pktID_ = 0; - - outPort_ = new Sim_port("output_buffer"); - super.add_port(outPort_); - - // for sending background traffic - gen_ = null; - list_ = null; - random_ = null; - hasStarted_ = false; - - System.out.println("Initialising FlowBuffer id " + super.get_id() + " name " + super.get_name()); - } - - /** - * Sets the background traffic generator for this entity. - * <p> - * When simulation starts, this entity will automatically sends junk - * packets to resource entities. - * @param gen a background traffic generator - * @return <tt>true</tt> if successful, <tt>false</tt> otherwise - * @pre gen != null - * @post $none - */ - - // TODO: Background traffic not yet implemented, do not use! - public boolean setBackgroundTraffic(TrafficGenerator gen) - { - if (gen == null) { - return false; - } - - gen_ = gen; - if (list_ == null) { - list_ = new ArrayList(); - } - - return true; - } - - /** - * Sets the background traffic generator for this entity. - * <p> - * When simulation starts, this entity will automatically sends junk - * packets to resource entities and other entities. <br> - * NOTE: Sending background traffic to itself is not supported. - * - * @param gen a background traffic generator - * @param userName a collection of user entity name (in String object). - * @return <tt>true</tt> if successful, <tt>false</tt> otherwise - * @pre gen != null - * @pre userName != null - * @post $none - */ - - // TODO: Background traffic not yet implemented, do not use! - public boolean setBackgroundTraffic(TrafficGenerator gen, - Collection userName) - { - if (gen == null || userName == null) { - return false; - } - - boolean flag = true; - try - { - gen_ = gen; - if (list_ == null) { - list_ = new ArrayList(); - } - - // iterates through each list to check whether it is a valid - // entity name or not - Iterator it = userName.iterator(); - int id = -1; - while( it.hasNext() ) - { - String name = (String) it.next(); - - // check whether it is sending to itself - id = GridSim.getEntityId("Output_" + name); - if (id == super.get_id()) - { - System.out.println(super.get_name() + - ".setBackgroundTraffic(): Warning - can not send " + - "junk packets to itself."); - continue; - } - - // get the ID of other entity - id = GridSim.getEntityId(name); - if (id > 0) - { - Integer obj = new Integer(id); - list_.add(obj); - } - // ignore for invalid entity - else - { - System.out.println(super.get_name() + - ".setBackgroundTraffic(): Warning - invalid entity " + - "name for \"" + name + "\"."); - } - } - } - catch(Exception e) { - flag = false; - } - - return flag; - } - - /** - * Sets this entity's link. This should be used only if the network - * extensions are being used. - * - * @param link the link to which this FlowBuffer entity should send data - * @pre link != null - * @post $none - */ - public void addLink(Link link) - { - this.link_ = link; - baudRate_ = link_.getBaudRate(); - outPacketList_ = new Vector(); - activeFlows_ = new HashMap(); - } - - /** - * Gets the baud rate - * @return the baud rate - * @deprecated As of GridSim 2.1, replaced by {@link #getBaudRate()} - * @pre $none - * @post $result >= 0.0 - */ - public double GetBaudRate() { - return this.getBaudRate(); - } - - /** - * Gets the baud rate - * @return the baud rate - * @pre $none - * @post $result >= 0.0 - */ - public double getBaudRate() { - return baudRate_; - } - - /** - * Gets the I/O real number based on a given value - * @param value the specified value - * @return real number - * @deprecated As of GridSim 2.1, replaced by {@link #realIO(double)} - * @pre $none - * @post $result >= 0.0 - */ - public double real_io(double value) { - return this.realIO(value); - } - - /** - * Gets the I/O real number based on a given value - * @param value the specified value - * @return real number - * @pre $none - * @post $result >= 0.0 - */ - public double realIO(double value) { - return GridSimRandom.realIO(value); - } - - /** - * A method that gets one process event at one time until the end - * of a simulation, then delivers an event to the entity (its parent) - * @pre $none - * @post $none - */ - public void body() - { - - // find out ids for entities that are not part of simulation network - // topology, such as GIS, GridSimShutdown and GridStatistics - int gisID = GridSim.getGridInfoServiceEntityId(); - int statID = GridSim.getGridStatisticsEntityId(); - int shutdownID = GridSim.getGridSimShutdownEntityId(); - - // start generating some junk packets or background traffic - // startBackgroundTraffic(); - - // Process incoming events - while ( Sim_system.running() ) - { - Sim_event ev = new Sim_event(); - super.sim_get_next(ev); // get the next event in the queue - - // if the simulation finishes then exit the loop - if (ev.get_tag() == GridSimTags.END_OF_SIMULATION) { - break; - } - - System.out.println(super.get_name() + ".body(): ev.get_tag() is " + ev.get_tag()); - - // handle different types of incoming events - switch ( ev.get_tag() ) - { - case GridSimTags.SEND_PACKET: - System.out.println(super.get_name() + ".body(): sendPacket() + at time = " + GridSim.clock()); - sendPacket(); - break; - - // submit ping() request - case GridSimTags.INFOPKT_SUBMIT: - System.out.println(super.get_name() + ".body(): sendInfoPacket() + at time = " + GridSim.clock()); - sendInfoPacket(ev); - break; - - // replying ping() request from another entity - case GridSimTags.INFOPKT_RETURN: - System.out.println(super.get_name() + ".body(): returnInfoPacket() + at time = " + GridSim.clock()); - returnInfoPacket(ev); - break; - - // activate background traffic - case GridSimTags.JUNK_PKT: - generateBackgroundTraffic(); - break; - - case GridSimTags.PKT_FORWARD: - System.out.println(super.get_name() + ".body(): getDataFromLink() + at time = " + GridSim.clock()); - getDataFromLink(ev); - break; - - // Check if initial flow duration estimation was accurate - case GridSimTags.FLOW_HOLD: - System.out.println(super.get_name() + ".body(): checkForecast() + at time = " + GridSim.clock()); - checkForecast(ev); - break; - - // Update flow duration forecase - case GridSimTags.FLOW_UPDATE: - System.out.println(super.get_name() + ".body(): updateForecast() + at time = " + GridSim.clock()); - updateForecast(ev); - break; - - case GridSimTags.FLOW_RETURN: - submitAckToLink(ev); - break; - - default: - defaultSend(ev, gisID, statID, shutdownID); - break; - } - } - - System.out.println(super.get_name() + ":%%%% Exiting body() at time " + - GridSim.clock() ); - } - - /** - * Check the forecast of a flow, and send data to output port if flow still exists - * - * @param ev the flow hold notification event - * @pre ev != null - * @post $none - */ - private synchronized void checkForecast(Sim_event ev) { - int pktID = (Integer) ev.get_data(); // ID of flow to be checked - FlowPacket fp = null; // Reference to flow packet that needs forecast update - FlowPacket fpAck = null; - - System.out.println(super.get_name() + ".checkForecast(): checking pkt id # " + pktID); - - // If flow hasn't already finished, send it to outPort - if ((fp = (FlowPacket) activeFlows_.get(pktID)) != null) { - Object data = fp.getData(); - IO_data io = new IO_data( data, fp.getSize(), - outPort_.get_src()); - super.sim_schedule(outPort_, GridSimTags.SCHEDULE_NOW, fp.getTag() , io.getData()); - activeFlows_.remove(pktID); - - // Send ack to source of flow - System.out.println(super.get_name() + ".checkForecast(): flow came from " + GridSim.getEntityName(fp.getSrcID()) - + " heading to " + GridSim.getEntityName(fp.getDestID())); - int oldDestID = fp.getDestID(); - int oldSrcID = fp.getSrcID(); - - IO_data ackData = new IO_data(fp.getData(), fp.getSize(), oldSrcID - 1); - fpAck = new FlowPacket(ackData,fp.getID(),fp.getSize(),GridSimTags.FLOW_RETURN,super.get_id(), - oldSrcID - 1, fp.getNetServiceType(), 1, 1); - fpAck.setRemSize(0); - fpAck.setStartTime(fp.getStartTime()); - fpAck.setLatency(fp.getLatency()); - - super.sim_schedule(super.get_id(), GridSimTags.SCHEDULE_NOW, GridSimTags.FLOW_RETURN, fpAck); - - } else { - System.out.println(super.get_name() + ".checkForecast(): pkt id # " + pktID + " already removed"); - - } - - } - - /** - * Update the forecast of a flow, delete the old forecast and schedule a new flow hold - * event in the future with the corrected forecast - * - * @param ev the flow update notification event - * @pre ev != null - * @post $none - */ - private synchronized void updateForecast(Sim_event ev) { - int pktID = (Integer) ev.get_data(); // ID of flow to be updated - FlowPacket fp = null; // Reference to flow packet that needs forecast update - double duration = 0.0; // New forecast duration from current Gridsim.clock() - long remSizeOld = 0; // Previous remaining size - double bandwidthOld = 0.0; // Previous bottleneck BW - int sourceID = ev.get_src(); // ID of source of notification (FlowLink) - int cancelledFlow = 0; // Count of canceled future events that match old forecast - - System.out.println(super.get_name() + ".updateForecast(): updating pkt id # " + pktID); - - // If flow hasn't already finished and been cleared... - if ((fp = (FlowPacket) activeFlows_.get(pktID)) != null) { - remSizeOld = fp.getRemSize(); - bandwidthOld = fp.getBandwidth_(); - System.out.println(super.get_name() + "updateForecast(): rem size is " + remSizeOld + "BW old is " + bandwidthOld); - Iterator it = (fp.getLinks_()).iterator(); - - while (it.hasNext()) { - FlowLink fl = (FlowLink) it.next(); - if (fl.get_id() == sourceID) { - fp.setBandwidth_(fl.getBaudRate()); - fp.setBottleneckID(sourceID); - } - } - - fp.setRemSize((long)(remSizeOld*BITS - (GridSim.clock()-fp.getUpdateTime())*bandwidthOld)); - duration = fp.getRemSize()/fp.getBandwidth_(); - System.out.println(super.get_name() + " new remaining duration add " + duration); - - FilterFlow filter = new FilterFlow(fp.getID(), GridSimTags.FLOW_HOLD); - cancelledFlow = this.sim_cancel(filter, null); - - if (cancelledFlow != 0) { - System.out.println(super.get_name() + ".updateForecast(): old forecast cancelled"); - } - - - super.sim_schedule(super.get_id(), duration, GridSimTags.FLOW_HOLD , new Integer(fp.getID())); - } - } - - /** - * Generates few junk packets at the given interval - * @pre $none - * @post $none - */ - private synchronized void generateBackgroundTraffic() - { - // get the next inter-arrival time for these junk packets - long time = gen_.getNextPacketTime(); - - // get the sending pattern - int pattern = gen_.getPattern(); - - // for initial start-up, get the list of all resources first - if (hasStarted_ == false) - { - // get list of resource IDs from GIS - LinkedList resList = GridSim.getGridResourceList(); - - // if the list is empty then schedule the next time - if (resList == null && list_.size() == 0) - { - super.sim_schedule(super.get_id(), time, GridSimTags.JUNK_PKT); - return; - } - - hasStarted_ = true; - list_.addAll(resList); // add resource IDs into the current list - - // sets the sending pattern - if (pattern == TrafficGenerator.SEND_ONE_ONLY && random_ == null) { - random_ = new Random(); - } - } - - // get the required info for generating this background traffic - long size = gen_.getNextPacketSize(); // packet size - long freq = gen_.getNextPacketFreq(); // packet freq - int type = gen_.getServiceType(); // packet type - int tag = GridSimTags.JUNK_PKT; // packet tag - - // we need to packetsize the data, all packets are sent with size MTU. - // only the last packet contains the data, the receiver should - // throw away all other packets - int MTU = link_.getMTU(); - int numPackets = (int) Math.ceil( size / (MTU * 1.0) ); - - /********* // DEBUG info - System.out.println(); - System.out.println(super.get_name() + - ": START GENERATE BG traffic... at time "+ GridSim.clock()); - System.out.println(super.get_name() + - ": NEXT background traffic will start at " + time); - System.out.println(super.get_name() + - " num PACKETS = " + numPackets + ", freq = " + freq); - *********/ - - int i = 0; - int destId = -1; - - // send to one of the entity using uniform distribution - if (pattern == TrafficGenerator.SEND_ONE_ONLY) - { - int index = random_.nextInt( list_.size() ); - destId = ((Integer) list_.get(index)).intValue(); - - /********* // DEBUG info - System.out.println(super.get_name() + ": Destination id = " + - destId + " = " + GridSim.getEntityName(destId) ); - *********/ - - // create junk packets or empty FlowPacket. - for (i = 0; i < freq; i++) { - convertIntoPacket(MTU, numPackets+1, tag, destId, type); - } - } - // send to all resources + other entities - else if (pattern == TrafficGenerator.SEND_ALL) - { - // send to all resources and user entities - for (int k = 0; k < list_.size(); k++) - { - destId = ((Integer) list_.get(k)).intValue(); - - /********* // DEBUG info - System.out.println(super.get_name() + ": Destination id = " + - destId + " = " + GridSim.getEntityName(destId) ); - *********/ - - // create junk packets or empty FlowPacket. - for (i = 0; i < freq; i++) { - convertIntoPacket(MTU, numPackets+1, tag, destId, type); - } - } - } - - // sends the next junk packets - super.sim_schedule(super.get_id(), time, GridSimTags.JUNK_PKT); - } - - /** - * Initial start for the background traffic - * @pre $none - * @post $none - */ - // TODO: Background traffic not yet implemented, do not use! - private synchronized void startBackgroundTraffic() - { - // if no background traffic generator, then skip the rest - if (gen_ == null) { - return; - } - - // get the next inter-arrival time - long time = gen_.getNextPacketTime(); - System.out.println(super.get_name() + - ": background traffic will start at time " + time); - - // starts background traffic if the inter-arrival time is valid - if (time == -1) { - return; - } - - super.sim_schedule(super.get_id(), time, GridSimTags.JUNK_PKT); - } - - /** - * This method processes outgoing data without a network extension. - * @param ev a Sim_event object - * @param gisID the central/default GIS entity ID - * @param statID the GridStatistic entity ID - * @param shutdownID the GridSimShutdown entity ID - * @pre ev != null - * @post $none - */ - private synchronized void defaultSend(Sim_event ev, int gisID, int statID, - int shutdownID) - { - IO_data io = (IO_data) ev.get_data(); - int destId = io.getDestID(); - - /***** // DEBUG info*/ - System.out.println(super.get_name() + ".defaultSend(): Send to " + - GridSim.getEntityName(destId) + " tag = " + ev.get_tag() + " at time = " + GridSim.clock()); - /*****/ - - // if this entity uses a network extension - if (link_ != null && destId != gisID && destId != statID && - destId != shutdownID) - { - System.out.println(super.get_name() + ".defaultSend(): submitToLink() + at time = " + GridSim.clock()); - submitToLink(ev); - return; - } - -/* // Identify ID of an entity which acts as Input/Buffer - // entity of destination entity - int id = GridSim.getEntityId( "Input_" + - Sim_system.get_entity(destId).get_name() ); - - // Send first and then hold - super.sim_schedule(id, GridSimTags.SCHEDULE_NOW, ev.get_tag(), io); - - double receiverBaudRate = ( (FlowBuffer) - Sim_system.get_entity(id) ).getBaudRate(); - - // NOTE: io is in byte and baud rate is in bits. 1 byte = 8 bits - // So, convert io into bits - double minBaudRate = Math.min(baudRate_, receiverBaudRate); - double communicationDelay = GridSimRandom.realIO( - (io.getByteSize() * BITS) / minBaudRate); - - // NOTE: Below is a deprecated method for SimJava 2 - //super.sim_hold(communicationDelay); - super.sim_process(communicationDelay);*/ - } - - /** - * This method takes data from an entity. If the size of the data is larger - * than the MTU of the link, then the packet is split into mutiple size - * units. After this it calls outEnque() to queue these packets into its - * buffer. - * - * @param ev A Sim_event data that contains all the data for this method - * to do its task. - * @pre ev != null - * @post $none - */ - private synchronized void submitToLink(Sim_event ev) - { - IO_data data = (IO_data) ev.get_data(); - Object obj = data.getData(); - long size = data.getByteSize(); - int tag = ev.get_tag(); - int destId = data.getDestID(); - int netServiceType = data.getNetServiceLevel(); - - // we need to packetsize the data, all packets are sent with size MTU. - // only the last packet contains the data, the receiver should - // throw away all other packets - //int MTU = link_.getMTU(); - //int numPackets = (int) Math.ceil( size / (MTU * 1.0) ); - - // make dummy packets with null data - //System.out.println("Packetizing data, creating " + numPackets + " dummy packets at time = " + GridSim.clock()); - //convertIntoPacket(MTU, numPackets, tag, destId, netServiceType); - - // last packet contains the actual data - FlowPacket np = null; - np = new FlowPacket(obj,pktID_,size,tag,super.get_id(), - destId, netServiceType, 1, 1); - - System.out.println("Sending flow packet to link at time = " + GridSim.clock() + " id is " + pktID_); - pktID_++; // increments packet ID - outEnque(np, GridSimTags.SCHEDULE_NOW); - } - - private synchronized void submitAckToLink(Sim_event ev) - { - - FlowPacket fp = (FlowPacket)ev.get_data(); - System.out.println("Sending flow packet ack to link at time = " + GridSim.clock() + " id is " + pktID_); - outEnque(fp, GridSimTags.SCHEDULE_NOW); - } - - /** - * Creates many dummy or null packets - * @param size packet size (in bytes) - * @param numPackets total number of packets to be created - * @param tag packet tag - * @param destId destination ID for sending the packet - * @param netServiceType level type of service for the packet - * @pre $none - * @post $none - */ - private synchronized void convertIntoPacket(long size, int numPackets, - int tag, int destId, int netServiceType) - { - FlowPacket np = null; - for (int i = 0; i < numPackets - 1; i++) - { - // change the tag name for dummy packets, apart from junk packets - if (tag != GridSimTags.JUNK_PKT) { - tag = GridSimTags.EMPTY_PKT; - } - - np = new FlowPacket(null, pktID_, size, tag, super.get_id(), destId, - netServiceType, i+1, numPackets); - - pktID_++; // increments packet ID - outEnque(np, GridSimTags.SCHEDULE_NOW); - } - } - - /** - * Sends an InfoPacket for ping request - * @param ev a Sim_Event object - * @pre ev != null - * @post $none - */ - // TODO: Untested in flow model, and probably not useful - private synchronized void sendInfoPacket(Sim_event ev) - { - IO_data data = (IO_data) ev.get_data(); - - // gets all the relevant info - long size = data.getByteSize(); - int destId = data.getDestID(); - int netServiceType = data.getNetServiceLevel(); - int tag = ev.get_tag(); - String name = GridSim.getEntityName( outPort_.get_dest() ); - - // we need to packetsize the data, all packets are sent with size MTU - // only the last packet contains the ping data, the receiver should - // throw away all other data - int MTU = link_.getMTU(); - int numPackets = (int) Math.ceil( size / (MTU * 1.0) ); - - // break ping size into smaller pieces - // Also, make sure that it is not for pinging itself - if (size > MTU && outPort_.get_dest() != destId) - { - // make dummy packets with null data - convertIntoPacket(MTU, numPackets, tag, destId, netServiceType); - } - - // get the remaining ping size - size = data.getByteSize() - MTU*(numPackets-1); - - // create the real InfoPacket - InfoPacket pkt = new InfoPacket(name,pktID_,size,outPort_.get_dest(), - destId,netServiceType); - - // set the required info - pkt.setLast( super.get_id() ); - pkt.addHop( outPort_.get_dest() ); - pkt.addEntryTime( GridSim.clock() ); - pkt.setOriginalPingSize( data.getByteSize() ); - - pktID_++; // increments packet ID - outEnque(pkt, GridSimTags.SCHEDULE_NOW); - } - - /** - * Sends back the ping() request to the next hop or destination - * @param ev a Sim_event object - * @pre ev != null - * @post $none - */ - // TODO: Untested in flow model, and probably not useful - private void returnInfoPacket(Sim_event ev) - { - IO_data data = (IO_data) ev.get_data(); - - // use the original ping size rather than IO_data or InfoPacket size - // since the latter is restricted to MTU - InfoPacket pkt = (InfoPacket) data.getData(); - long size = pkt.getOriginalPingSize(); - - // get other relevant info - int tag = ev.get_tag(); - int destId = pkt.getSrcID(); - int netServiceType = data.getNetServiceLevel(); - - // we need to packetsize the data, all packets are sent with size MTU. - // only the last packet contains the data, the receiver should - // throw away all other packets - int MTU = link_.getMTU(); - int numPackets = (int) Math.ceil( size / (MTU * 1.0) ); - - // make dummy packets with null data - convertIntoPacket(MTU, numPackets, tag, destId, netServiceType); - - // set the original packet of last hop into this entity id - pkt.setLast( super.get_id() ); - outEnque(pkt, GridSimTags.SCHEDULE_NOW); - } - - /** - * Takes a packet, adds it into a buffer and schedules it to be sent out at - * an appropriate time. - * - * @param pkt The packet to be buffered - * @param delay The length of time this packet should be delayed (exclusive - * of the transmission time) - * @pre pkt != null - * @pre delay > 0 - * @post $none - */ - private synchronized void outEnque(Packet pkt, double delay) - { - - - outPacketList_.add(pkt); - if (outPacketList_.size() == 1) - { - System.out.println(super.get_name() + ".outEnque() Size is " + pkt.getSize() + " baud " + link_.getBaudRate()); - // Compute expected duration of flow using bottleneck baudRate - // double total = delay + (pkt.getSize()*SIZE / link_.getBaudRate()); - double total = 0.0; - - System.out.println(super.get_name() + ".outEnque() Time now " + GridSim.clock() + " delay is " + total); - super.sim_schedule(super.get_id(), total, GridSimTags.SEND_PACKET); - } - - } - - - /** - * Removes a single packet from the buffer and sends it down the link. - * Then, schedules the next packet in the list. - * @pre $none - * @post $none - */ - private synchronized void sendPacket() - { - if (outPacketList_ == null || outPacketList_.isEmpty() == true) { - return; - } - - // submits the first packet in the list - Packet np = (Packet) outPacketList_.remove(0); - - boolean ping = false; // a flag to determine ping packet or not - int tag = -1; // event tag ID - int dest = -1; // destination ID - - // if a packet belongs to a ping packet - if (np instanceof InfoPacket) - { - ((InfoPacket)np).addExitTime( GridSim.clock() ); - ((InfoPacket)np).addBaudRate( link_.getBaudRate() ); - ping = true; - tag = GridSimTags.INFOPKT_SUBMIT; - } - - // if an entity tries to send a packet to itself - if ( np.getDestID() == outPort_.get_dest() ) - { - // then change the destination name and id - String destName = super.get_name(); - destName = destName.replaceFirst("Output", "Input"); - dest = Sim_system.get_entity_id(destName); - - // for a ping packet, change the tag - if (ping == true) - { - // don't forget to change the packet tag - tag = GridSimTags.INFOPKT_RETURN; - ((InfoPacket) np).setTag(tag); - } - else { - tag = np.getTag(); - } - } - else // if an entity tries to send to other entity - { - // change or keep the event tag - tag = GridSimTags.PKT_FORWARD; - if (np.getTag() == GridSimTags.JUNK_PKT) { - tag = GridSimTags.JUNK_PKT; - } - - // sends the packet into the link - dest = link_.get_id(); - } - - // send the packet - super.sim_schedule(dest, GridSimTags.SCHEDULE_NOW, tag, np); - - /***** // DEBUG info **/ - System.out.println(super.get_name() + " send to " + - GridSim.getEntityName(dest) + " tag = " + tag + " time " + GridSim.clock()); - /****/ - - // if the list is not empty, then schedule the next packet in the list - if (outPacketList_.isEmpty() != true) - { - //double delay = np.getSize() * SIZE / link_.getBaudRate(); - double delay = 0.0; - super.sim_schedule(super.get_id(), delay, GridSimTags.SEND_PACKET); - } - } - - /** - * Process incoming events from senders that are using the network - * extension - * @param ev a Sim_event object - * @pre ev != null - * @post $none - */ - private void getDataFromLink(Sim_event ev) - { - Object obj = ev.get_data(); - double duration = 0.0; - - if (obj instanceof Packet) - { - // decrypt the packet into original format - Packet pkt = (Packet) ev.get_data(); - - if (pkt instanceof InfoPacket) - { - processPingRequest( (InfoPacket) pkt); - return; - } - - if (pkt instanceof FlowPacket) - { - FlowPacket np = (FlowPacket) pkt; - int tag = np.getTag(); - System.out.println("Packet id is " + np.getID()); - - // ignore incoming junk packets - if (tag == GridSimTags.JUNK_PKT) { - return; - } - - // ignore incoming null dummy packets - if (tag == GridSimTags.EMPTY_PKT && np.getData() == null) { - return; - } - - // convert the packets into IO_data - Object data = np.getData(); - IO_data io = new IO_data( data, np.getSize(), - outPort_.get_src()); - System.out.println(super.get_name() + ".getDataFromLink() Time now " + GridSim.clock() - + " bottleneck is " + np.getBandwidth_() + " sum lat is " + np.getLatency() ); - - // if flow terminates at next entity, add to active flows - // & hold for appropriate duration - if (pkt.getTag() == GridSimTags.FLOW_SUBMIT) { - np.setStartTime(GridSim.clock()); - np.setUpdateTime(GridSim.clock()); - duration = np.getSize()*SIZE / np.getBandwidth_(); - activeFlows_.put(pkt.getID(), pkt); - super.sim_schedule(super.get_id(), duration, GridSimTags.FLOW_HOLD, new Integer(pkt.getID())); - System.out.println(super.get_name() + ".getDataFromLink() forecast flow end at " + (GridSim.clock() - + duration)); - - // if flow is just an ACK of a finished flow do not hold - } else if (pkt.getTag() == GridSimTags.FLOW_RETURN){ - duration = 0.0; - // send the data into entity input/output port - super.sim_schedule(outPort_, duration, tag, - io.getData() ); - } - - - } - } - } - - /** - * Processes a ping request - * @param pkt a packet for pinging - * @pre pkt != null - * @post $none - */ - // TODO: Untested in flow model, and probably not useful - private void processPingRequest(InfoPacket pkt) - { - // add more information to ping() packet - pkt.addHop( outPort_.get_dest() ); - pkt.addEntryTime( GridSim.clock() ); - - IO_data io = new IO_data( pkt, pkt.getSize(), outPort_.get_dest() ); - - // send this ping() packet to the entity - super.sim_schedule(outPort_, GridSimTags.SCHEDULE_NOW, - pkt.getTag(), io.getData()); - } - -} // end class - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |