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

来源:互联网 发布:docker跑windows程序 编辑:程序博客网 时间:2024/04/28 05:25
[java] view plaincopy
  1. /* 
  2.  * Title:        CloudSim Toolkit 
  3.  * Description:  CloudSim (Cloud Simulation) Toolkit for Modeling and Simulation of Clouds 
  4.  * Licence:      GPL - http://www.gnu.org/copyleft/gpl.html 
  5.  * 
  6.  * Copyright (c) 2009-2010, The University of Melbourne, Australia 
  7.  */  
  8.   
  9. package org.cloudbus.cloudsim.core;  
  10.   
  11. import java.util.ArrayList;  
  12. import java.util.Calendar;  
  13. import java.util.HashMap;  
  14. import java.util.Iterator;  
  15. import java.util.LinkedHashMap;  
  16. import java.util.LinkedList;  
  17. import java.util.List;  
  18. import java.util.Map;  
  19.   
  20. import org.cloudbus.cloudsim.Log;  
  21. import org.cloudbus.cloudsim.core.predicates.Predicate;  
  22. import org.cloudbus.cloudsim.core.predicates.PredicateAny;  
  23. import org.cloudbus.cloudsim.core.predicates.PredicateNone;  
  24.   
  25. /** 
  26.  * 这个类主要作用是把几个核心类组成系统(CIS,QUEUE,CLOUDSIMSHUTDOWN) 
  27.  * 主要包括CIS 
  28.  * cloudsim中所有的字段和方法都是static 
  29.  * This class extends the CloudSimCore to enable network simulation in CloudSim. 
  30.  * Also, it disables all the network models from CloudSim, to provide a simpler 
  31.  * simulation of networking. In the network model used by CloudSim, a topology 
  32.  * file written in BRITE format is used to describe the network. Later, nodes in 
  33.  * such file are mapped to CloudSim entities. Delay calculated from the BRITE 
  34.  * model are added to the messages send through CloudSim. Messages using the old 
  35.  * model are converted to the apropriate methods with the correct parameters. 
  36.  * 
  37.  * @author      Rodrigo N. Calheiros 
  38.  * @author      Anton Beloglazov 
  39.  * @since       CloudSim Toolkit 1.0 
  40.  */  
  41. public class CloudSim {  
  42.   
  43.     /** The Constant CLOUDSIM_VERSION_STRING. */  
  44.     private static final String CLOUDSIM_VERSION_STRING = "2.0";  
  45.   
  46.     /** The id of CIS entity. */  
  47.     private static int cisId = -1;  
  48.   
  49.     /** The id of CloudSimShutdown entity. */  
  50.     @SuppressWarnings("unused")  
  51.     private static int shutdownId = -1;  
  52.   
  53.     /** The CIS object. */  
  54.     private static CloudInformationService cis = null;  
  55.   
  56.     /** The Constant NOT_FOUND. */  
  57.     private static final int NOT_FOUND = -1;  
  58.   
  59.     /** The trace flag. */  
  60.     @SuppressWarnings("unused")  
  61.     private static boolean traceFlag = false;  
  62.   
  63.     /** The calendar. */  
  64.     private static Calendar calendar = null;  
  65.   
  66.     /** 
  67.      * 初始化实体列表,实体hash,future,defered,calendar,traceflag,cloudsimshutdown 
  68.      * Initialises all the common attributes. 
  69.      * 
  70.      * @param _calendar the _calendar 
  71.      * @param _traceFlag the _trace flag 
  72.      * @param numUser number of users 
  73.      * @throws Exception This happens when creating this entity before initialising 
  74.      * CloudSim package or this entity name is <tt>null</tt> or empty 
  75.      * @pre $none 
  76.      * @post $none 
  77.      */  
  78.     private static void initCommonVariable(Calendar _calendar, boolean _traceFlag, int numUser) throws Exception {  
  79.         //初始化实体列表,实体hash,future,defered,等  
  80.         initialize();  
  81.         // NOTE: the order for the below 3 lines are important 
  82.         //注:下面3行的顺序是很重要的
  83.         traceFlag = _traceFlag;  
  84.   
  85.         // Set the current Wall clock time as the starting time of  
  86.         // simulation 
  87.         //设置当前挂钟时间作为模拟的起始时间
  88.         if (_calendar == null) {  
  89.             calendar = Calendar.getInstance();  
  90.         } else {  
  91.             calendar = _calendar;  
  92.         }  
  93.       
  94.         // creates a CloudSimShutdown object 
  95.         //创建一个CloudSimShutdown对象
  96.         CloudSimShutdown shutdown = new CloudSimShutdown("CloudSimShutdown", numUser);  
  97.         shutdownId = shutdown.getId();           //id默认为-1  
  98.     }  
  99.   
  100.     /** 
  101.      * Initialises CloudSim parameters. This method should be called before 
  102.      * creating any entities. 
  103.      * <p> 
  104.      * Inside this method, it will create the following CloudSim entities: 
  105.      * <ul> 
  106.      * <li>CloudInformationService. 
  107.      * <li>CloudSimShutdown 
  108.      * </ul> 
  109.      * <p> 
  110.      * 
  111.      * @param numUser the number of User Entities created. This parameters indicates 
  112.      * that {@link gridsim.CloudSimShutdown} first waits for all user 
  113.      * entities's END_OF_SIMULATION signal before issuing terminate 
  114.      * signal to other entities 
  115.      * @param cal starting time for this simulation. If it is <tt>null</tt>, 
  116.      * then the time will be taken from 
  117.      * <tt>Calendar.getInstance()</tt> 
  118.      * @param traceFlag <tt>true</tt> if CloudSim trace need to be written 
  119.      * 
  120.      * @see gridsim.CloudSimShutdown 
  121.      * @see CloudInformationService.CloudInformationService 
  122.      * @pre numUser >= 0 
  123.      * @post $none 
  124.      */  
  125.     public static void init(int numUser, Calendar cal, boolean traceFlag) {  
  126.         try {  
  127.             initCommonVariable(cal, traceFlag, numUser);  
  128.   
  129.             // create a GIS object  
  130.             cis = new CloudInformationService("CloudInformationService");  
  131.   
  132.             // set all the above entity IDs  
  133.             cisId = cis.getId();  
  134.         } catch (IllegalArgumentException s) {  
  135.             Log.printLine("CloudSim.init(): Unwanted errors happen");  
  136.             Log.printLine(s.getMessage());  
  137.         } catch (Exception e) {  
  138.             Log.printLine("CloudSim.init(): Unwanted errors happen");  
  139.             Log.printLine(e.getMessage());  
  140.         }  
  141.     }  
  142.   
  143.     /** 
  144.      * Starts the execution of CloudSim simulation. It waits for complete 
  145.      * execution of all entities, i.e. until all entities threads reach 
  146.      * non-RUNNABLE state or there are no more events in the future event queue. 
  147.      * <p> 
  148.      * <b>Note</b>: This method should be called after all the entities have 
  149.      * been setup and added. 
  150.      * 
  151.      * @return the double 
  152.      * @throws NullPointerException This happens when creating this entity before initialising 
  153.      * CloudSim package or this entity name is <tt>null</tt> or 
  154.      * empty. 
  155.      * @see gridsim.CloudSim#init(int, Calendar, boolean) 
  156.      * @pre $none 
  157.      * @post $none 
  158.      */  
  159.     public static double startSimulation() throws NullPointerException {  
  160.         Log.printLine("Starting CloudSim version " + CLOUDSIM_VERSION_STRING);  
  161.         try {  
  162.             double clock = run();  
  163.   
  164.             // reset all static variables  
  165.             cisId = -1;  
  166.             shutdownId = -1;  
  167.             cis = null;  
  168.             calendar = null;  
  169.             traceFlag = false;  
  170.   
  171.             return clock;  
  172.         } catch (IllegalArgumentException e) {  
  173.             e.printStackTrace();  
  174.             throw new NullPointerException("CloudSim.startCloudSimulation() :"  
  175.                     + " Error - you haven't initialized CloudSim.");  
  176.         }  
  177.     }  
  178.   
  179.     /** 
  180.      *仿真停止。 
  181.      * Stops Cloud Simulation (based on {@link Simulation#runStop()}). This 
  182.      * should be only called if any of the user defined entities 
  183.      * <b>explicitly</b> want to terminate simulation during execution. 
  184.      * 
  185.      * @throws NullPointerException This happens when creating this entity before initialising 
  186.      * CloudSim package or this entity name is <tt>null</tt> or empty 
  187.      * 
  188.      * @see gridsim.CloudSim#init(int, Calendar, boolean) 
  189.      * @see Simulation#runStop() 
  190.      * @pre $none 
  191.      * @post $none 
  192.      */  
  193.     public static void stopSimulation() throws NullPointerException {  
  194.         try {  
  195.             runStop();  
  196.         } catch (IllegalArgumentException e) {  
  197.             throw new NullPointerException("CloudSim.stopCloudSimulation() : "  
  198.                     + "Error - can't stop Cloud Simulation.");  
  199.         }  
  200.     }  
  201.   
  202.     /** 
  203.      *  复制日历 
  204.      * Gets a new copy of initial simulation Calendar. 
  205.      * 
  206.      * @return a new copy of Calendar object or  if CloudSim hasn't 
  207.      * been initialized 
  208.      * @see gridsim.CloudSim#init(int, Calendar, boolean, String[], String[], 
  209.      * String) 
  210.      * @see gridsim.CloudSim#init(int, Calendar, boolean) 
  211.      * @pre $none 
  212.      * @post $none 
  213.      */  
  214.     public static Calendar getSimulationCalendar() {  
  215.         // make a new copy  
  216.         Calendar clone = calendar;  
  217.         if (calendar != null) {  
  218.             clone = (Calendar) calendar.clone();  
  219.         }  
  220.   
  221.         return clone;  
  222.     }  
  223.   
  224.     /** 
  225.      * 获得CIS的id 
  226.      * Gets the entity ID of <tt>CloudInformationService</tt>. 
  227.      * 
  228.      * @return the Entity ID or  if it is not found 
  229.      * @pre $none 
  230.      * @post $result >= -1 
  231.      */  
  232.     public static int getCloudInfoServiceEntityId() {  
  233.         return cisId;  
  234.     }  
  235.   
  236.     /** 
  237.      * 所得CIS中所有实体列表 
  238.      * Sends a request to Cloud Information Service (GIS) entity to get the list 
  239.      * of all Cloud hostList. 
  240.      * 
  241.      * @return A List containing CloudResource ID (as an Integer object) 
  242.      * or  if a CIS entity hasn't been created before 
  243.      * @pre $none 
  244.      * @post $none 
  245.      */  
  246.     public static List<Integer> getCloudResourceList() {  
  247.         if (cis == null) {  
  248.             return null;  
  249.         }  
  250.   
  251.         return cis.getList();  
  252.     }  
  253.   
  254.     // ======== SIMULATION METHODS ===============//  
  255.   
  256.     // Private data members  
  257.     /** The entities. */  
  258.     private static List<SimEntity> entities;  
  259.   
  260.     /** The future event queue. */  
  261.     private static FutureQueue future;  
  262.   
  263.     /** The deferred event queue. */  
  264.     private static DeferredQueue deferred;  
  265.   
  266.     /** The simulation clock. */  
  267.     private static double clock;  
  268.   
  269.     /** Flag for checking if the simulation is running. */  
  270.     private static boolean running;  
  271.   
  272.     /* 
  273.      * (non-javadoc) 
  274.      */  
  275.     /** The entities by name. */  
  276.     private static Map<String, SimEntity> entitiesByName;  
  277.   
  278.     // The predicates used in entity wait methods  
  279.     /** The wait predicates. */  
  280.     private static Map<Integer, Predicate> waitPredicates;  
  281.   
  282.     /** The paused. */  
  283.     private static boolean paused = false;  
  284.   
  285.     /** The pause at. */  
  286.     private static long pauseAt = -1;  
  287.   
  288.     /** The abrupt terminate. */  
  289.     private static boolean abruptTerminate = false;  
  290.   
  291.     /** 
  292.      * 初始化实体列表,实体hash,future,defered,等 
  293.      * Initialise the simulation for stand alone simulations. This function 
  294.      * should be called at the start of the simulation. 
  295.      */  
  296.     protected static void initialize() {  
  297.         Log.printLine("Initialising...");  
  298.         entities = new ArrayList<SimEntity>();  
  299.         entitiesByName = new LinkedHashMap<String, SimEntity>();  
  300.         future = new FutureQueue();  
  301.         deferred = new DeferredQueue();  
  302.         waitPredicates = new HashMap<Integer, Predicate>();  
  303.         clock = 0;  
  304.         running = false;  
  305.     }  
  306.   
  307.     // The two standard predicates  
  308.   
  309.     /** A standard predicate that matches any event. */  
  310.     public final static PredicateAny SIM_ANY = new PredicateAny();  
  311.   
  312.     /** A standard predicate that does not match any events. */  
  313.     public final static PredicateNone SIM_NONE = new PredicateNone();  
  314.   
  315.     // Public access methods  
  316.   
  317.     /** 
  318.      * 返回时钟 
  319.      * Get the current simulation time. 
  320.      * 
  321.      * @return the simulation time 
  322.      */  
  323.     public static double clock() {  
  324.         return clock;  
  325.     }  
  326.   
  327.     /** 
  328.      * 返回仿真实体数量 
  329.      * Get the current number of entities in the simulation. 
  330.      * 
  331.      * @return The number of entities 
  332.      */  
  333.     public static int getNumEntities() {  
  334.         return entities.size();  
  335.     }  
  336.   
  337.     /** 
  338.      * Get the entity with a given id. 
  339.      *  
  340.      * @param id the entity's unique id number 
  341.      * @return The entity, or  if it could not be found 
  342.      */  
  343.     public static SimEntity getEntity(int id) {  
  344.         return entities.get(id);  
  345.     }  
  346.   
  347.     /** 
  348.      * Get the entity with a given name. 
  349.      * 
  350.      * @param name The entity's name 
  351.      * @return The entity 
  352.      */  
  353.     public static SimEntity getEntity(String name) {  
  354.         return entitiesByName.get(name);  
  355.     }  
  356.   
  357.     /** 
  358.      * Get the id of an entity with a given name. 
  359.      * 
  360.      * @param name The entity's name 
  361.      * @return The entity's unique id number 
  362.      */  
  363.     public static int getEntityId(String name) {  
  364.         SimEntity obj = entitiesByName.get(name);  
  365.         if (obj == null) {  
  366.             return NOT_FOUND;  
  367.         } else {  
  368.             return obj.getId();  
  369.         }  
  370.     }  
  371.   
  372.     /** 
  373.      * Gets name of the entity given its entity ID. 
  374.      * 
  375.      * @param entityID the entity ID 
  376.      * @return the Entity name or  if this object does not have one 
  377.      * @pre entityID > 0 
  378.      * @post $none 
  379.      */  
  380.     public static String getEntityName(int entityID) {  
  381.         try {  
  382.             return getEntity(entityID).getName();  
  383.         } catch (IllegalArgumentException e) {  
  384.             return null;  
  385.         } catch (Exception e) {  
  386.             return null;  
  387.         }  
  388.     }  
  389.   
  390.     /** 
  391.      * Gets name of the entity given its entity ID. 
  392.      * 
  393.      * @param entityID the entity ID 
  394.      * @return the Entity name or  if this object does not have one 
  395.      * @pre entityID > 0 
  396.      * @post $none 
  397.      */  
  398.     public static String getEntityName(Integer entityID) {  
  399.         if (entityID != null) {  
  400.             return getEntityName(entityID.intValue());  
  401.         }  
  402.         return null;  
  403.     }  
  404.   
  405.     /** 
  406.      * Returns a list of entities created for the simulation. 
  407.      * 
  408.      * @return the entity iterator 
  409.      */  
  410.     public static List<SimEntity> getEntityList() {  
  411.         // create a new list to prevent the user from changing  
  412.         // the list of entities used by Simulation  
  413.         List<SimEntity> list = new LinkedList<SimEntity>();  
  414.         list.addAll(entities);  
  415.         return list;  
  416.     }  
  417.   
  418.     // Public update methods  
  419.   
  420.     /** 
  421.      * 实体加入仿真中,创建一个crate的事件(其他还有空事件,发送事件,等待事件)加入到future中 
  422.      * Add a new entity to the simulation. This is present for compatibility 
  423.      * with existing simulations since entities are automatically added to the 
  424.      * simulation upon instantiation. 
  425.      * 
  426.      * @param e The new entity 
  427.      */  
  428.     public static void addEntity(SimEntity e) {  
  429.         SimEvent evt;  
  430.         //??为什么还要发送一个事件??  
  431.         if (running) {  
  432.             // Post an event to make this entity  
  433.             evt = new SimEvent(SimEvent.CREATE, clock, 100, e);  
  434.             future.addEvent(evt);  
  435.         }  
  436.         //实体加入到entities列表中了  
  437.         if (e.getId() == -1) { // Only add once!  
  438.             int id = entities.size();  
  439.             e.setId(id);  
  440.             entities.add(e);  
  441.             entitiesByName.put(e.getName(), e);  
  442.         }  
  443.     }  
  444.   
  445.     /** 
  446.      * 内部用来添加一个实体,当仿真在运行时候 
  447.      * ??没有加入队列??? 
  448.      * Internal method used to add a new entity to the simulation when the 
  449.      * simulation is running. It should <b>not</b> be called from user 
  450.      * simulations. 
  451.      * 
  452.      * @param e The new entity 
  453.      */  
  454.     protected static void addEntityDynamically(SimEntity e) {  
  455.         if (e == null) {  
  456.             throw new IllegalArgumentException("Adding null entity.");  
  457.         } else {  
  458.             printMessage("Adding: " + e.getName());  
  459.         }  
  460.         e.startEntity();  
  461.     }  
  462.   
  463.     /** 
  464.      * 仿真跑一个时刻,处理defered中所有剩下的事件,处理future中所有和第一个事件 
  465.      * 发生时间相同的事件 
  466.      * Internal method used to run one tick of the simulation. This method 
  467.      * should <b>not</b> be called in simulations. 
  468.      * 
  469.      * @return true, if successful 
  470.      * otherwise 
  471.      */  
  472.     public static boolean runClockTick() {  
  473.         SimEntity ent;  
  474.         boolean queue_empty;  
  475.         int entities_size = entities.size();  
  476.           
  477.         //处理所有defered中的事件  
  478.         for (int i = 0; i < entities_size; i++) {  
  479.             ent = entities.get(i);  
  480.             if (ent.getState() == SimEntity.RUNNABLE) {  
  481.                 ent.run();  
  482.             }  
  483.         }  
  484.   
  485.         // If there are more future events then deal with them  
  486.         //处理future中所有和第一个事件发生时间相同的事件  
  487.         if (future.size() > 0) {  
  488.             List<SimEvent> toRemove = new ArrayList<SimEvent>();  
  489.             Iterator<SimEvent> it = future.iterator();  
  490.             queue_empty = false;  
  491.             SimEvent first = it.next();  
  492.             processEvent(first);  
  493.             future.remove(first);  
  494.   
  495.             it = future.iterator();  
  496.   
  497.             // Check if next events are at same time...  
  498.             boolean trymore = it.hasNext();  
  499.             while (trymore) {  
  500.                 SimEvent next = it.next();  
  501.                 if (next.eventTime() == first.eventTime()) {  
  502.                     processEvent(next);  
  503.                     toRemove.add(next);  
  504.                     trymore = it.hasNext();  
  505.                 } else {  
  506.                     trymore = false;  
  507.                 }  
  508.             }  
  509.   
  510.             future.removeAll(toRemove);  
  511.   
  512.         } else {  
  513.             queue_empty = true;  
  514.             running = false;  
  515.             printMessage("Simulation: No more future events");  
  516.         }  
  517.   
  518.         return queue_empty;  
  519.     }  
  520.   
  521.     /** 
  522.      * Internal method used to stop the simulation. This method should 
  523.      * <b>not</b> be used directly. 
  524.      */  
  525.     public static void runStop() {  
  526.         printMessage("Simulation completed.");  
  527.     }  
  528.   
  529.     /** 
  530.      * 同pause相同 
  531.      * Used to hold an entity for some time. 
  532.      * 
  533.      * @param src the src 
  534.      * @param delay the delay 
  535.      */  
  536.     public static void hold(int src, long delay) {  
  537.         SimEvent e = new SimEvent(SimEvent.HOLD_DONE, clock + delay, src);  
  538.         future.addEvent(e);  
  539.         entities.get(src).setState(SimEntity.HOLDING);  
  540.     }  
  541.   
  542.     /** 
  543.      * 用于实体挂起,实体中的pause方法会调用此方法 
  544.      * 该方法建立事件,加入future中,设置实体状体 
  545.      * ???为什么直接设置实体状态,不是应该是该实体收到该事件之后才挂起吗?? 
  546.      * 回答:事件作用是在延迟时间到达后,从新启动该实体 
  547.      * Used to pause an entity for some time. 
  548.      * 
  549.      * @param src the src 
  550.      * @param delay the delay 
  551.      */  
  552.     public static void pause(int src, double delay) {  
  553.         SimEvent e = new SimEvent(SimEvent.HOLD_DONE, clock + delay, src);  
  554.         future.addEvent(e);  
  555.         entities.get(src).setState(SimEntity.HOLDING);  
  556.     }  
  557.   
  558.     /** 
  559.      * send过程:生成event对象,加入future Queue中,event对象中含有源地址,目标地址 
  560.      * 和事件的其他信息。 
  561.      * Used to send an event from one entity to another. 
  562.      * 
  563.      * @param src the src 
  564.      * @param dest the dest 
  565.      * @param delay the delay 
  566.      * @param tag the tag 
  567.      * @param data the data 
  568.      */  
  569.     public static void send(int src, int dest, double delay, int tag, Object data) {  
  570.         if (delay < 0) {  
  571.             throw new IllegalArgumentException("Send delay can't be negative.");  
  572.         }  
  573.   
  574.         SimEvent e = new SimEvent(SimEvent.SEND, clock + delay, src, dest, tag, data);  
  575.         future.addEvent(e);  
  576.     }  
  577.       
  578.     /** 
  579.      * Used to send an event from one entity to another, with priority in the queue. 
  580.      * 
  581.      * @param src the src 
  582.      * @param dest the dest 
  583.      * @param delay the delay 
  584.      * @param tag the tag 
  585.      * @param data the data 
  586.      */  
  587.     public static void sendFirst(int src, int dest, double delay, int tag, Object data) {  
  588.         if (delay < 0) {  
  589.             throw new IllegalArgumentException("Send delay can't be negative.");  
  590.         }  
  591.   
  592.         SimEvent e = new SimEvent(SimEvent.SEND, clock + delay, src, dest, tag, data);  
  593.         future.addEventFirst(e);  
  594.     }  
  595.   
  596.     /** 
  597.      * Sets an entity's state to be waiting. The predicate used to wait for an event 
  598.      * is now passed to Sim_system. Only events that satisfy the predicate will be 
  599.      * passed to the entity. This is done to avoid unnecessary context switches. 
  600.      * 
  601.      * @param src the src 
  602.      * @param p the p 
  603.      */  
  604.     public static void wait(int src, Predicate p) {  
  605.         entities.get(src).setState(SimEntity.WAITING);  
  606.         if (p != SIM_ANY) {  
  607.             // If a predicate has been used store it in order to check it  
  608.             waitPredicates.put(src, p);  
  609.         }  
  610.     }  
  611.   
  612.     /** 
  613.      * 队列中事件满足:目的地=d,谓词满足p的事件个数 
  614.      * Checks if events for a specific entity are present in the deferred event queue. 
  615.      * 
  616.      * @param d the d 
  617.      * @param p the p 
  618.      * 
  619.      * @return the int 
  620.      */  
  621.     public static int waiting(int d, Predicate p) {  
  622.         int count = 0;  
  623.         SimEvent event;  
  624.         Iterator<SimEvent> iterator = deferred.iterator();  
  625.         while (iterator.hasNext()) {  
  626.             event = iterator.next();  
  627.             if ((event.getDestination() == d) && (p.match(event))) {  
  628.                 count++;  
  629.             }  
  630.         }  
  631.         return count;  
  632.     }  
  633.   
  634.     /** 
  635.      * 选择第一个满足src(目的地)和谓词p条件的事件,并把它从队列中移走 
  636.      * Selects an event matching a predicate. 
  637.      * 
  638.      * @param src the src 
  639.      * @param p the p 
  640.      * 
  641.      * @return the sim event 
  642.      */  
  643.     public static SimEvent select(int src, Predicate p) {  
  644.         SimEvent ev = null;  
  645.         Iterator<SimEvent> iterator = deferred.iterator();  
  646.         while (iterator.hasNext()) {  
  647.             ev = iterator.next();  
  648.             if (ev.getDestination() == src && p.match(ev)) {  
  649.                 iterator.remove();  
  650.                 break;  
  651.             }  
  652.         }  
  653.         return ev;  
  654.     }  
  655.   
  656.     /** 
  657.      * Removes an event from the event queue. 
  658.      * 
  659.      * @param src the src 
  660.      * @param p the p 
  661.      * 
  662.      * @return the sim event 
  663.      */  
  664.     public static SimEvent cancel(int src, Predicate p) {  
  665.         SimEvent ev = null;  
  666.         Iterator<SimEvent> iter = future.iterator();  
  667.         while (iter.hasNext()) {  
  668.             ev = iter.next();  
  669.             if (ev.getSource() == src && p.match(ev)) {  
  670.                 iter.remove();  
  671.                 break;  
  672.             }  
  673.         }  
  674.   
  675.         return ev;  
  676.     }  
  677.   
  678.     /** 
  679.      * Removes all events that match a given predicate from the future event queue 
  680.      * returns true if at least one event has been cancelled; false otherwise. 
  681.      * 
  682.      * @param src the src 
  683.      * @param p the p 
  684.      * 
  685.      * @return true, if successful 
  686.      */  
  687.     public static boolean cancelAll(int src, Predicate p) {  
  688.         SimEvent ev = null;  
  689.         int previousSize = future.size();  
  690.         Iterator<SimEvent> iter = future.iterator();  
  691.         while (iter.hasNext()) {  
  692.             ev = iter.next();  
  693.             if (ev.getSource() == src && p.match(ev)) {  
  694.                 iter.remove();  
  695.             }  
  696.         }  
  697.         return previousSize < future.size();  
  698.     }  
  699.   
  700.     //  
  701.     // Private internal methods  
  702.     //  
  703.   
  704.     /** 
  705.      * Processes an event.处理事件 
  706.      * 
  707.      * @param e the e 
  708.      */  
  709.     private static void processEvent(SimEvent e) {  
  710.         int dest, src;  
  711.         SimEntity dest_ent;  
  712.         // Update the system's clock  
  713.         if (e.eventTime() < clock) {  
  714.             //此时仿真系统的时钟回拨,有可能使事件执行顺序变化  
  715.             throw new IllegalArgumentException("Past event detected.");  
  716.         }  
  717.         clock = e.eventTime();  
  718.   
  719.         // Ok now process it  
  720.         switch (e.getType()) {  
  721.             case SimEvent.ENULL:  
  722.                 throw new IllegalArgumentException("Event has a null type.");  
  723.   
  724.             case SimEvent.CREATE:  
  725.                 SimEntity newe = (SimEntity) e.getData();  
  726.                 addEntityDynamically(newe);  
  727.                 break;  
  728.   
  729.             case SimEvent.SEND:  
  730.                 // Check for matching wait  
  731.                 dest = e.getDestination();  
  732.                 if (dest < 0) {  
  733.                     throw new IllegalArgumentException(  
  734.                             "Attempt to send to a null entity detected.");  
  735.                 } else {  
  736.                     int tag = e.getTag();  
  737.                     dest_ent = entities.get(dest);  
  738.                     /** 
  739.                      * 实体处于waiting状态时候,通过event事件可以叫醒 
  740.                      * 处于waiting状态的实体在waitPredicates中可能纯在谓词 
  741.                      * 只有满足此谓词的事件才可以叫醒 
  742.                      * 运行状态的实体没有谓词 
  743.                      */  
  744.                     if (dest_ent.getState() == SimEntity.WAITING) {  
  745.                           
  746.                         Integer destObj = Integer.valueOf(dest);  
  747.                         Predicate p = waitPredicates.get(destObj);  
  748.                         if ((p == null) || (tag == 9999) || (p.match(e))) {  
  749.                             dest_ent.setEventBuffer((SimEvent) e.clone());  
  750.                             dest_ent.setState(SimEntity.RUNNABLE);  
  751.                             waitPredicates.remove(destObj);  
  752.                         } else {  
  753.                             deferred.addEvent(e);  
  754.                         }  
  755.                     } else {  
  756.                         deferred.addEvent(e);  
  757.                     }  
  758.                 }  
  759.                 break;  
  760.   
  761.             case SimEvent.HOLD_DONE:  
  762.                 src = e.getSource();  
  763.                 if (src < 0) {  
  764.                     throw new IllegalArgumentException("Null entity holding.");  
  765.                 } else {  
  766.                     entities.get(src).setState(SimEntity.RUNNABLE);  
  767.                 }  
  768.                 break;  
  769.   
  770.             default:  
  771.                 break;  
  772.         }  
  773.     }  
  774.   
  775.     /** 
  776.      * 启动entities中所有实体 
  777.      * Internal method used to start the simulation. This method should 
  778.      * <b>not</b> be used by user simulations. 
  779.      */  
  780.     public static void runStart() {  
  781.         running = true;  
  782.         // Start all the entities  
  783.         for (SimEntity ent : entities) {  
  784.             ent.startEntity();  
  785.         }  
  786.   
  787.         printMessage("Entities started.");  
  788.     }  
  789.   
  790.     /** 
  791.      * Check if the simulation is still running. This method should be used by 
  792.      * entities to check if they should continue executing. 
  793.      * 
  794.      * @return  if the simulation is still running, 
  795.      *  otherwise 
  796.      */  
  797.     public static boolean running() {  
  798.         return running;  
  799.     }  
  800.   
  801.     /** 
  802.      * This method is called if one wants to pause the simulation. 
  803.      * 
  804.      * @return true, if successful 
  805.      * otherwise. 
  806.      */  
  807.     public static boolean pauseSimulation() {  
  808.         paused = true;  
  809.         return paused;  
  810.     }  
  811.   
  812.     /** 
  813.      * 终止仿真一定时间 
  814.      * This method is called if one wants to pause the simulation at a given 
  815.      * time. 
  816.      * 
  817.      * @param time the time at which the simulation has to be paused 
  818.      * @return true, if successful 
  819.      * otherwise. 
  820.      */  
  821.     public static boolean pauseSimulation(long time) {  
  822.         if (time <= clock) {  
  823.             return false;  
  824.         } else {  
  825.             pauseAt = time;  
  826.         }  
  827.         return true;  
  828.     }  
  829.   
  830.     /** 
  831.      * 恢复实体 
  832.      * This method is called if one wants to resume the simulation that has 
  833.      * previously been paused. 
  834.      * 
  835.      * @return if the simulation has been restarted or or 
  836.      *  otherwise. 
  837.      */  
  838.     public static boolean resumeSimulation() {  
  839.         paused = false;  
  840.   
  841.         if (pauseAt <= clock) {  
  842.             pauseAt = -1;  
  843.         }  
  844.   
  845.         return !paused;  
  846.     }  
  847.   
  848.     /** 
  849.      * 仿真运行 
  850.      * Start the simulation running. This should be called after all the 
  851.      * entities have been setup and added, and their ports linked. 
  852.      * 
  853.      * @return the double last clock value 
  854.      */  
  855.     public static double run() {  
  856.         if (!running) {  
  857.             //启动entities中所有实体  
  858.             runStart();  
  859.         }  
  860.         while (true) {  
  861.             //一个一个时刻运行  
  862.             if (runClockTick() || abruptTerminate) {  
  863.                 break;  
  864.             }  
  865.   
  866.             if (pauseAt != -1 && ((future.size() > 0 && clock <= pauseAt && pauseAt <= future.iterator().next().eventTime()) || future.size() == 0 && pauseAt <= clock)) {  
  867.                 pauseSimulation();  
  868.                 clock = pauseAt;  
  869.             }  
  870.   
  871.             while (paused) {  
  872.                 try {  
  873.                     Thread.sleep(100);  
  874.                 } catch (InterruptedException e) {  
  875.                     e.printStackTrace();  
  876.                 }  
  877.             }  
  878.         }  
  879.   
  880.         double clock = clock();  
  881.   
  882.         finishSimulation();  
  883.         runStop();  
  884.   
  885.         return clock;  
  886.     }  
  887.   
  888.     /** 
  889.      * 仿真结束,置对象为空 
  890.      * Internal method that allows the entities to terminate. This method should 
  891.      * <b>not</b> be used in user simulations. 
  892.      */  
  893.     public static void finishSimulation() {  
  894.         // Allow all entities to exit their body method  
  895.         //非突然中断允许实体处理完剩下的event  
  896.         if (!abruptTerminate) {  
  897.             for (SimEntity ent : entities) {  
  898.                 if (ent.getState() != SimEntity.FINISHED) {  
  899.                     ent.run();  
  900.                 }  
  901.             }  
  902.         }  
  903.   
  904.         for (SimEntity ent : entities) {  
  905.             ent.shutdownEntity();  
  906.         }  
  907.   
  908.         // reset all static variables  
  909.         // Private data members  
  910.         entities = null;  
  911.         entitiesByName = null;  
  912.         future = null;  
  913.         deferred = null;  
  914.         clock = 0L;  
  915.         running = false;  
  916.   
  917.         waitPredicates = null;  
  918.         paused = false;  
  919.         pauseAt = -1;  
  920.         abruptTerminate = false;  
  921.     }  
  922.   
  923.     /** 
  924.      * Abruptally terminate. 
  925.      */  
  926.     public static void abruptallyTerminate() {  
  927.         abruptTerminate = true;  
  928.     }  
  929.   
  930.     /** 
  931.      * Prints a message about the progress of the simulation. 
  932.      * 
  933.      * @param message the message 
  934.      */  
  935.     private static void printMessage(String message) {  
  936.         Log.printLine(message);  
  937.     }  
  938.   
  939.     /** 
  940.      * Checks if is paused. 
  941.      * 
  942.      * @return true, if is paused 
  943.      */  
  944.     public static boolean isPaused() {  
  945.         return paused;  
  946.     }  
  947.   

0 0
原创粉丝点击