From: <mar...@us...> - 2007-10-04 06:05:10
|
Revision: 66 http://gridsim.svn.sourceforge.net/gridsim/?rev=66&view=rev Author: marcos_dias Date: 2007-10-03 23:05:13 -0700 (Wed, 03 Oct 2007) Log Message: ----------- This version contains many changes and bug fixes: + Some classes have been moved to gridsim.turbo package. + The ParallelSpaceShared policy has been changed substantially and some bugs have been fixed. For example, the policy was not compressing the schedule properly when cancelling a gridlet. This could also lead to finding the wrong anchor for a job when the completion of a job matched the completion of another job and there was a big job starting at this completion time. + Some advance reservation features have been provided, but they are still being tested. + Improvements in the graphical user interface have been made. + Some changes in SimJava classes have been made to remove the animation and log capabilities that are not used by GridSim. Removed Paths: ------------- branches/gridsim4.0-branch3/source/eduni/simjava/Evqueue.java branches/gridsim4.0-branch3/source/eduni/simjava/Sim_system.java Deleted: branches/gridsim4.0-branch3/source/eduni/simjava/Evqueue.java =================================================================== --- branches/gridsim4.0-branch3/source/eduni/simjava/Evqueue.java 2007-10-04 06:04:43 UTC (rev 65) +++ branches/gridsim4.0-branch3/source/eduni/simjava/Evqueue.java 2007-10-04 06:05:13 UTC (rev 66) @@ -1,88 +0,0 @@ -/* Evqueue.java */ - -package eduni.simjava; - -import java.util.Iterator; -import java.util.SortedSet; -import java.util.TreeSet; - -/** - * This class implements the event queue used by <code>Sim_system</code>. - * <p> - * The event queue is separated into two subqueues, the future queue and - * the deferred queue. Newly arrived events are added to the future queue - * while events that the receiving entity is unable to process are placed - * in the deferred queue. The current implementation uses a Vector to store - * the events received. - * <p> - * This class is used internally by <code>Sim_system</code> and should not be - * directly accessed. - * @see eduni.simjava.Sim_system - * @version 0.1, 25 June 1995 - * @author Ross McNab - * @author Marcos Dias de Assuncao (changed this class to use SortedSet) - */ -public class Evqueue { - private SortedSet sortedSet; - private long serial = 0; - - /** - * Allocates a new Evqueue object. - */ - public Evqueue() { - sortedSet = new TreeSet(); - } - - /** - * Remove and return the event at the top of the queue. - * @return The next event. - */ - public Sim_event pop() { - Sim_event event = (Sim_event)sortedSet.first(); - sortedSet.remove(event); - return event; - } - - /** - * Return the event at the top of the queue, without removing it. - * @return The next event. - */ - public Sim_event top() { - return (Sim_event)sortedSet.first(); - } - - /** - * Add a new event to the queue. Adding a new event to the queue preserves the - * temporal order of the events in the queue. - * @param new_event The event to be put on the queue. - */ - public void add_event(Sim_event new_event) { - // The event has to be inserted as the last of all events - // with the same event_time(). Yes, this matters. - new_event.setSerial(serial++); - sortedSet.add(new_event); - } - - /** - * Returns an interator to the sorted set - * @return the iterator - */ - public Iterator iterator() { - return sortedSet.iterator(); - } - - /** - * Returns the size of this event queue - * @return the size - */ - public int size() { - return sortedSet.size(); - } - - /** - * Clears the sorted set - */ - public void clear(){ - sortedSet.clear(); - } -} \ No newline at end of file Deleted: branches/gridsim4.0-branch3/source/eduni/simjava/Sim_system.java =================================================================== --- branches/gridsim4.0-branch3/source/eduni/simjava/Sim_system.java 2007-10-04 06:04:43 UTC (rev 65) +++ branches/gridsim4.0-branch3/source/eduni/simjava/Sim_system.java 2007-10-04 06:05:13 UTC (rev 66) @@ -1,3219 +0,0 @@ -/* Sim_system.java */ - -package eduni.simjava; - -import java.io.BufferedReader; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.ObjectOutputStream; -import java.text.DateFormat; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.zip.GZIPOutputStream; - -import eduni.simjava.distributions.Generator; -import eduni.simjava.distributions.Sim_random_obj; - -/** - * The <code>SimJava</code> simulation kernel. - * <p> - * This class is responsible for managing all aspects of the simulation. Instantiated entities - * are added to <code>Sim_system</code> which is responsible for synchronising their behaviour. - * Time progresses on the basis of event scheduling times. These events are held in two queues, - * instances of <code>Evqueue</code>, the future queue and the deferred queue. All the runtime - * functionality available to entities is managed by <code>Sim_system</code>. - * <p> - * In the previous versions of <code>SimJava</code>, users would use <code>Sim_system</code> - * only to initialise the simulation, add the entities, link their ports, and finally run the - * simulation. In version 2.0 <code>Sim_system</code> makes a lot more functionality available - * to the modeller. - * <p> - * Three new aspects of <code>Sim_system</code> are the definition of a transient condition, a - * termination condition, and the selection of an output analysis method to apply. All these are - * managed internally by <code>Sim_system</code> so the user is not required to include relevant - * code in the simulation's entities. To set the <b>transient condition</b> for the simulation - * the user uses a <code>set_transient_condition</code> method. The simulation's <b>termination - * condition</b> is set by using a <code>set_termination_condition</code> method. Finally, an - * <b>output analysis method</b> is selected with one of the <code>set_output_analysis</code> - * methods. - * <p> - * Available transient conditions are: - * <ul> - * <li> - * A number of event completions. In this case the simulation is considered to have entered steady state - * after a certain number of event service completions at a given entity. Event completions - * are signalled to <code>Sim_system</code> with the entities' - * <code><a href="Sim_entity.html#sim_completed(eduni.simjava.Sim_event)">sim_completed</a></code> method. - * <li> - * A specific period of simulated time. After this time period elapses the simulation is considered to - * have entered steady state. - * <li> - * The minimum-maximum method. This method allows <code>Sim_system</code> to try and identify the - * transient period based on the minimum-maximum method for a given measure. This method considers - * steady state to have been entered once a measure observation has been located which is neither - * the minimum nor the maximum of the remaining observations. - * <li> - * None. This is the default if no condition is specified. - * </ul> - * <p> - * Available termination conditions are: - * <ul> - * <li> - * A number of event completions. The simulation is terminated once a given number of events complete - * service at a given entity. This condition is similar to the relevant transient condition. - * <li> - * A specific period of simulated time. After this time period elapses the simulation is terminated. - * <li> - * A measure's confidence interval accuracy. This method allows <code>Sim_system</code> to run the - * simulation until a confidence interval for a given measure has reached a certain accuracy level. - * To use this method, the user needs to provide the measure of interest, an output analysis method - * which will be used as a variance reduction technique, the confidence level, and the desired accuracy. - * The accuracy is the ratio of the confidence interval's halfwidth over the measure's total mean. - * <li> - * None. As before this is the default if no condition is specified. Non terminating simulations have - * meaning only for animation purposes in which case a simulation is used as an elaborate demo of a - * system. - * </ul> - * <p> - * Entities may use the <code>running</code> method to check whether the simulation has completed. - * <p> - * Finally, the available output analysis methods are: - * <ul> - * <li> - * Independent replications. In this case, the simulation run is repeated a number of times - * to produce total measurements. - * <li> - * Batch means. With this method, a single, long run is performed and then the obtained observations - * are batched into batches and their means are then used to produce the total measurements. The - * number of batches used is the one that gives the least serial correlation between the batch means. - * for the majority of measures. - * <li> - * None. Again this is the default method. In this case no output analysis is performed and only - * available sample measurements are produced. - * </ul> - * <p> - * Since version 2.0 of <code>SimJava</code>, <code>Sim_system</code> also allows the modeller greater - * control over the <b>seeding</b> of the random number generators. The simulation's generators can be created - * in such a way to allow <code>Sim_system</code> to automatically seed them, ensuring well spaced - * sample sequences for the generators. The original seed to be used as well as the seed spacing desired - * can be set with the <code>set_seed_sequence</code> method. If this method is not used, the default - * seed of 4851 is used to produce seeds spaced by 100000 samples. If independent replications are used - * as an output analysis method and reseeding of the generators is desired in each subsequent replication, - * the generators need to be added to their entities. This is accomplished with the entities' - * <code><a href="Sim_entity.html#add_generator(eduni.simjava.distributions.Generator)">add_generator</a></code> method. - * Otherwise the previous replication's last seed is used as the next one's initial seed. - * <p> - * <code>Sim_system</code> also provides control over the simulation's output. The <b>trace file</b> - * (<code>sim_trace</code>) can be managed with more detail. The <code>set_trace_detail</code> method - * can be used to specify whether or not to add the default trace , trace generated by the - * entities, or trace for specific event types. In this last case, the event tags of interest can be - * supplied to <code>Sim_system</code> with a <code>track_event</code> method. The level of entity - * trace included in the trace file can be managed with the <code>set_trace_level</code> method. Finally, - * tracing can be switched off altogether with the <code>set_auto_trace</code> method. The default is - * not to produce a trace file. - * <p> - * Another major aspect of the simulation's output is the <b>simulation's report</b>. The report is - * automatically produced by <code>Sim_system</code> and includes information on the simulation - * depending on the specified conditions and parameters. The detail level of the report file - * (<code>sim_report</code>) can be modified with the <code>set_report_detail</code> method. The - * default information included are the total obtained measurements obtained as well as general - * information about the simulation run. In the case of no output analysis method having been used, - * the steady state sample measurements are presented in place of the total measurements. If an - * output analysis method has been used, <code>set_report_detail</code> can be used to include - * the sample measurements for each replication (for independent replications), or the sample - * measurements for each batch (for batch means). Finally, the original seeds used in the random - * number generators of the simulation can also be included in the report. Since version 2.0, - * the simulation's report is also available to animated simulations. - * <p> - * A <code>generate_graphs</code> method may also be used to generate <b>graphs</b> for the simulation. - * Graphs are generated for all detailed measures and present the progress of each measure's sample - * average over the progress of the simulation. Several additional information may also be displayed - * for each graph such as the mean confidence interval, the transient period, the batches etc. The - * simulation will produce a <i>".sjg"</i> file containing the simulation data. This file may then - * be opened with the <code>SimJava Graph Viewer</code>, a graph viewing utility for <code>SimJava</code> - * simulations. - * <p> - * More information on the definition of simulations and the use of <code>Sim_system</code> can be found - * at the <a href="http://www.dcs.ed.ac.uk/home/simjava/tutorial/index.html#2">SimJava Tutorial</a>. - * @see Sim_entity - * @version 2.0, 12 July 2002 - * @author Costas Simatos - * @author Marcos Dias de Assuncao (removed the animation features) - */ -public class Sim_system { - - // The types of termination and transient conditions, and output analysis methods - /** A constant representing no condition. */ - public static final int NONE = 0; - /** A constant representing a condition based on event completions. */ - public static final int EVENTS_COMPLETED = 1; - /** A constant representing a condition based on a time period. */ - public static final int TIME_ELAPSED = 2; - /** A constant representing the minimum-maximum method for transient period identification. */ - public static final int MIN_MAX = 3; - /** A constant representing the output analysis method of independent replications. */ - public static final int IND_REPLICATIONS = 4; - /** A constant representing the output analysis method of batch means. */ - public static final int BATCH_MEANS = 5; - /** A constant representing a termination condition based on a confidence interval's accuray. */ - public static final int INTERVAL_ACCURACY = 6; - - // Private fields used to store the termination condition parameters - private static int term_condition = NONE; // The termination condition to be used - private static int term_entity_id; // The id of the entity containing the measure on which the termination condition is based - private static int term_event_type; // The event tag of the events to be considered for the termination condition - private static double term_time = 0.0; // The termination time - private static double initial_term_time = 0.0; // The termination time speficied by the user - private static long initial_term_count = 0; // The count of event completions specified by the user for the termination condition - private static long term_count = 0; // The count of event completions for the termination condition - private static int[] term_count_bm; // The count of event completions for a termination condition using batch means - private static List term_times; // Stores the termination times in the case of the minimum-maximum method being used - private static long term_event_counter = 0; // The counter for termination condtion event completions - private static long transient_term_event_count = 0; // The count of termination events completed during the transient period - private static String term_measure; // The measure used in the termination condition - private static double term_accuracy; // The accuracy for the confidence interval used in the termination condition - - // Private fields used to store the termination comdition parameters - private static int trans_condition = NONE; // The transient condition being used - private static int trans_entity_id; // The id of the entity containing the measure on which the transient condition is based - private static int trans_event_type; // The event tag of events to be considered for the transient condition - private static double trans_time = -1.0; // The transient time - private static String trans_measure; // The measure on which the transient conditnion is based - private static double initial_trans_time = 0.0; // The transient time specified by the user - private static long trans_count = 0; // The count of events for the transient period estimation - private static long initial_trans_count = 0; // The count of transient events for the transient period condition specified by the user - private static long trans_event_counter = 0; // The counter for events that count towards the transient condition - - private static boolean include_transient; // Flag for specifying whether the transient condition should be considered a part of the termination condition or not - private static boolean in_steady_state = false; // Flag for checking whether the simulation is in steady state - - // Fields concerning output analysis methods - private static int output_analysis_type = NONE; // The output analysis method being used - private static boolean incomplete = true; // Flag for telling whether a simulation is complete or not - private static int replication_count = 10; // The default number of replications to be made - private static double confidence_level = 0.90; // The default confidence level - private static List replications; // Stores the data from each replication - private static double total_time_elapsed = 0.0; // The total simulated time elapsed in all replications - private static double total_transient_time = 0.0; // The total transient time elapsed in all replications - private static int min_batches = 10; // The default minimum number of batches - private static int max_batches = 20; // The default maximum number of batches - - private static Object[] run_data; // Contains all the data obtained from the run - - // Fields for the management of the trace file - private static int[] trace_tags; // The tags for which trace will be generated - private static boolean default_trace = true, // Flag for including or not the default trace - entity_trace = true, // Flag for including or not the entity trace - event_trace = true; // Flag for including or not the event specific trace - - // Private data members - private static List entities; // The current entity list - private static List backup; // A backup containing the entities in their initial state - private static Evqueue future; // The future event queue - private static Evqueue deferred; // The deferred event queue - private static double clock; // Holds the current global sim time - private static boolean running; // Flag for checking if the simulation is running - private static Semaphore onestopped; // Semaphore for synchronising entities - private static Semaphore onecompleted; // Semaphore for registering entities having completed - private static Sim_output trcout; // The output object for trace messages - private static int trace_level; // The trace level for which event trace will be generated - private static boolean auto_trace; // Should we print trace messages? - private static NumberFormat nf; // The animation number format used - private static HashMap wait_predicates; // The predicates used in entity wait methods - - // Fields concerning the simulation's report - private static long start_date; // The actual time at which the simulation started - private static boolean detailed_report = false; // The default is to produce a report that isn't detailed - private static boolean include_seeds = false; // The default is to produce a report that does not include seed information - private static List initial_seeds; // The set of initial seeds - - // Private fields used for seed generation - private static long root_seed = 4851L; // The default seed - private static int seed_spacing = 100000; // The default seed spacing - private static Sim_random_obj seed_source = new Sim_random_obj("Seed generator", root_seed); // The seed generator - private static boolean not_sampled = true; // Flag that is checked to see whether the seed generator has been sampled - - private static boolean anim_stopped = false; // Flag used to check whether (in animated versions) the user has clicked on the stop button - - // Fields concerning graph generation - private static final String suffix = ".sjg"; // The suffix for SimJava graphs - private static boolean generate_graphs = false; // Flag used to check whether or not to generate graphs - private static String graph_file = "sim_graphs" + suffix; // The default graph file to be used - - private static boolean efficient_measure_defined = false; // Flag used to check whether the simulation contains an efficient measure - - // ADDED BY MARCOS - 2007-09-07 - private static boolean paused = false; - private static Object syncObj = new Object(); - - /** - * Do not a constructor for <code>Sim_system</code>. Use an <code>initialise</code> method instead. - */ - public Sim_system() { - throw new Sim_exception("Attempt to instantiate Sim_system."); - } - - /** - * Initialise the simulation for standalone simulations. This function should be called - * at the start of the simulation. - */ - public static void initialise() { - initialise(new Sim_outfile()); - } - - /** - * Initialise the system to draw <code>simdiag</code> diagrams. This method - * should be used directly only by expert users. - * @param out The <code>Sim_output</code> instance that will receive the simulation trace - */ - public static void initialise(Sim_output out) { - System.out.println("Initialising..."); - entities = new ArrayList(); - future = new Evqueue(); - deferred = new Evqueue(); - wait_predicates = new HashMap(); - clock = 0.0; - running = false; - onestopped = new Semaphore(0); - onecompleted = new Semaphore(0); - trcout = out; - trcout.initialise(); - trace_level = 0xff; - auto_trace = false; - // Set the default number format - nf = NumberFormat.getInstance(); - nf.setMaximumFractionDigits(4); - nf.setMinimumFractionDigits(2); - } - - /** - * Get the number format used for generating times in trace lines. - * @return The number format - */ - public static NumberFormat getNumberFormat() { return nf; } - - // The two standard predicates - - /** A standard predicate that matches any event. */ - public static Sim_any_p SIM_ANY = new Sim_any_p(); - /** A standard predicate that does not match any events. */ - public static Sim_none_p SIM_NONE = new Sim_none_p(); - - // Public access methods - - /** - * Get the current simulation time. This method is identical to <code>sim_clock()</code> and - * is present for compatibility with existing simulations. - * @return The simulation time - */ - public static double clock() { return clock; } - - /** - * Get the current simulation time, as a runtime method for entities. - * @return The simulation time - */ - public static double sim_clock() { return clock; } - - /** - * Get the current number of entities in the simulation. - * @return The number of entities - */ - public static int get_num_entities() { return entities.size(); } - - /** - * Get the current trace level (initially <code>0xff</code>), which - * controls trace output. This method is identical to <code>get_trace_level()</code> and - * is present for compatibility with existing simulations. - * @return The trace level - */ - public static int get_trc_level() { return trace_level; } // For compatibility with previous versions - - /** - * Get the current trace level (initially <code>0xff</code>), which - * controls trace output. - * @return The trace level - */ - public static int get_trace_level() { return trace_level; } - - /** - * Get the entity with a given id. - * @param id The entity's unique id number - * @return The entity, or <code>null</code> if it could not be found - * @throws Sim_exception If the entity was not found. This error can be left unchecked. - */ - public static Sim_entity get_entity(int id) { - if ((id < 0) || (id >= entities.size())) { - throw new Sim_exception("Entity " + id + " does not exist."); - } - return (Sim_entity)entities.get(id); - } - - /** - * Get the entity with a given name. - * @param name The entity's name - * @return The entity - * @throws Sim_exception If the entity was not found. This error can be left unchecked. - */ - public static Sim_entity get_entity(String name) { - Sim_entity ent; - int entities_size = entities.size(); - for (int i=0; i < entities_size; i++) { - ent = (Sim_entity)entities.get(i); - if (name.compareTo(ent.get_name()) == 0) { - return ent; - } - } - throw new Sim_exception("Entity " + name + " does not exist."); - } - - /** - * Get the id of an entity with a given name. - * @param name The entity's name - * @return The entity's unique id number - * @throws Sim_exception If the entity was not found. This error can be left unchecked. - */ - public static int get_entity_id(String name) { - int id = entities.indexOf(get_entity(name)); - if (id == -1) { - throw new Sim_exception("Entity " + name + " does not exist."); - } - return id; - } - - // ADDED BY MARCOS TO GET THE LIST OF ENTITIES IN THE SIMULATION - - /** - * Returns a list of entities created for the simulation - * @return the entity iterator - */ - public static LinkedList<Sim_entity> getEntityList(){ - // create a new list to prevent the user from changing - // the list of entities used by Sim_system - LinkedList<Sim_entity> list = new LinkedList<Sim_entity>(); - list.addAll(entities); - return list; - } - - // END OF METHODS ADDED BY MARCOS - - /** - * Get the currently running entity. - * @return The entity, or <code>null</code> if none are running - */ - public static Sim_entity current_ent() { - return (Sim_entity)Sim_entity.currentThread(); - } - - // Public update methods - - /** - * Set the trace level which controls entity trace output. This method is identical to - * <code>set_trace_level()</code> and is present for compatibility with existing simulations. - * @param level The new level - */ - public static void set_trc_level(int level) { auto_trace = true; trace_level = level; } - - /** - * Set the trace level which controls entity trace output. - * @param level The new level - */ - public static void set_trace_level(int level) { auto_trace = true; trace_level = level; } - - /** - * Switch the trace messages on and off. - * @param on If <code>true</code> then the messages are switched on, if <code>false</code> - they are switched off. - */ - public static void set_auto_trace(boolean on) { auto_trace = on; } - - /** - * Add a new entity to the simulation. This is present for compatibility with existing - * simulations since entities are automatically added to the simulation upon instantiation. - * @param e The new entity - */ - public static void add(Sim_entity e) { - Sim_event evt; - if (running) { - // Post an event to make this entity - evt = new Sim_event(Sim_event.CREATE,clock,current_ent().get_id(),0,0, e); - future.add_event(evt); - } else { - if (e.get_id()==-1) { // Only add once! - e.set_id(entities.size()); - entities.add(e); - } - } - } - - /** - * Internal method used to add a new entity to the simulation when the simulation is running. - * It should <b>not</b> be called from - * user simulations. - * @param e The new entity - */ - static synchronized void add_entity_dynamically(Sim_entity e) { - e.set_id(entities.size()); - if (e == null) { - throw new Sim_exception("Adding null entity."); - } else { - print_message("Adding: " + e.get_name()); - } - entities.add(e); - e.start(); - onestopped.p(); - } - - /** - * Link the ports of two entities so that events can be scheduled. - * @param ent1 The name of the first entity - * @param port1 The name of the port on the first entity - * @param ent2 The name of the second entity - * @param port2 The name of the port on the second entity - */ - public static void link_ports(String ent1, String port1, String ent2, String port2) { - Sim_port p1,p2; - Sim_entity e1, e2; - e1 = get_entity(ent1); - e2 = get_entity(ent2); - if (e1 == null) { - throw new Sim_exception("Sim_system: " + ent1 + " not found."); - } else if (e2==null) { - throw new Sim_exception("Sim_system: " + ent2 + " not found."); - } else { - p1 = e1.get_port(port1); - p2 = e2.get_port(port2); - if (p1 == null) { - throw new Sim_exception("Sim_system: " + port1 + " not found."); - } else if (p2==null) { - throw new Sim_exception("Sim_system: " + port2 + " not found."); - } else { - p1.connect(e2); - p2.connect(e1); - } - } - } - - /** - * Internal method used to run one tick of the simulation. This method should <b>not</b> be - * called in simulations. - * @return <code>true</code> if the event queue is empty, <code>false</code> otherwise - */ - public static boolean run_tick() { - Sim_entity ent; - int num_started; - boolean queue_empty; - num_started = 0; - int entities_size = entities.size(); - for (int i=0; i < entities_size; i++) { - ent = (Sim_entity)entities.get(i); - if (ent.get_state() == Sim_entity.RUNNABLE) { - ent.restart(); - num_started++; - } - } - // Wait for them all to halt - for (int i=0; i<num_started; i++) { - onestopped.p(); - } - - // If there are more future events then deal with them - if (future.size() > 0) { - queue_empty = false; - Sim_event first = future.pop(); - process_event(first); - // Check if next events are at same time... - boolean trymore = (future.size()>0); - while (trymore) { - Sim_event next = future.top(); - if (next.event_time() == first.event_time()) { - process_event(future.pop()); - trymore = (future.size()>0); - } else trymore = false; - } - } else { - queue_empty = true; - running = false; - print_message("Sim_system: No more future events"); - } - return queue_empty; - } - - - /** - * Internal method used to stop the simulation. This method should <b>not</b> be used directly. - */ - public static void run_stop() { - print_message("Simulation completed."); - trcout.close(); - } - - // - // Package level methods - // - - /** - * Get the object to which the simulation trace is sent. - * @return The trace handler - */ - public static Sim_output get_trcout() { return trcout; } - - // Entity service methods - - // Called by an entity just before it become non-RUNNABLE - static void paused() { onestopped.v(); } - - // Used to hold an entity for some time - static synchronized void hold(int src, double delay) { - Sim_event e = new Sim_event(Sim_event.HOLD_DONE,clock+delay,src); - future.add_event(e); - ((Sim_entity)entities.get(src)).set_state(Sim_entity.HOLDING); - if (auto_trace && default_trace) { - trace(src, "start processing"); - } - } - - // Used to pause an entity for some time - static synchronized void pause(int src, double delay) { - Sim_event e = new Sim_event(Sim_event.HOLD_DONE,clock+delay,src); - future.add_event(e); - ((Sim_entity)entities.get(src)).set_state(Sim_entity.HOLDING); - if (auto_trace && default_trace) { - trace(src, "start pausing"); - } - } - - // Used to send an event from one entity to another - static synchronized void send(int src, int dest, double delay, int tag, Object data) { - if (delay < 0.0) { - throw new Sim_exception("Sim_system: Send delay can't be negative."); - } - Sim_event e = new Sim_event(Sim_event.SEND, clock+delay, src, dest, tag, data); - if (auto_trace && (default_trace || (event_trace && is_trace_tag(tag)))) { - trace(src, "scheduling event type "+tag+" for "+ - ((Sim_entity)entities.get(dest)).get_name()+ - " with delay "+delay); - } - future.add_event(e); - } - - // Sets an entity's state to be waiting. The predicate used to wait for an event is now - // passed to Sim_system. Only events that satisfy the predicate will be passed to the - // entity. This is done to avoid unnecessary context switches. - static synchronized void wait(int src, Sim_predicate p) { - ((Sim_entity)entities.get(src)).set_state(Sim_entity.WAITING); - if (p != SIM_ANY) { - // If a predicate has been used store it in order to check it - wait_predicates.put(new Integer(src), p); - } - if (auto_trace && default_trace) { - trace(src,"waiting for an event"); - } - } - - // Checks if events for a specific entity are present in the deferred event queue - static synchronized int waiting(int d, Sim_predicate p) { - int count = 0; - Sim_event event; - Iterator iterator = deferred.iterator(); - while (iterator.hasNext()) { - event = (Sim_event)iterator.next(); - if ((event.get_dest() == d) && (p.match(event))) { - count++; - } - } - return count; - } - - // Selects an event matching a predicate - static synchronized void select(int src, Sim_predicate p) { - Sim_event ev = null; - boolean found = false; - Iterator iterator = deferred.iterator(); - while (iterator.hasNext()) { - ev = (Sim_event)iterator.next(); - if (ev.get_dest() == src) { - if (p.match(ev)) { - iterator.remove(); - found = true; - break; - } - } - } - if (found) { - ((Sim_entity)entities.get(src)).set_evbuf((Sim_event)ev.clone()); - if (auto_trace && (default_trace || (event_trace &&is_trace_tag(ev.get_tag())))) { - trace(src,"selected event type " + ev.get_tag() + " (event time was "+ev.event_time()+")"); - } - } else { - ((Sim_entity)entities.get(src)).set_evbuf(null); - if (auto_trace && (default_trace)) { - trace(src,"no event selected"); - } - } - } - - // Removes an event from the event queue - static synchronized void cancel(int src, Sim_predicate p) { - Sim_event ev = null; - boolean found = false; - int future_size = future.size(); - Iterator iter = future.iterator(); - while(iter.hasNext()){ - ev = (Sim_event)iter.next(); - if (ev.get_src() == src) { - if (p.match(ev)) { - iter.remove(); - found = true; - break; - } - } - } - -// for (int i=0; i < future_size; i++) { -// ev = (Sim_event)future.get(i); -// if (ev.get_src() == src) { -// if (p.match(ev)) { -// future.remove(i); -// found = true; -// break; -// } -// } -// } - - if (found) { - ((Sim_entity)entities.get(src)).set_evbuf((Sim_event)ev.clone()); - if (auto_trace && (default_trace || (event_trace && is_trace_tag(ev.get_tag())))) { - trace(src,"cancelled event type " + ev.get_tag() + " (event time was "+ev.event_time()+")"); - } - } else { - ((Sim_entity)entities.get(src)).set_evbuf(null); - if (auto_trace && default_trace) { - trace(src,"no event cancelled"); - } - } - } - - // Puts an event into the deferred queue - static synchronized void putback(Sim_event ev) { deferred.add_event(ev); } - - // - // Private internal methods - // - - // Processes an event - private static void process_event(Sim_event e) { - - // ADDED BY MARCOS TO ALLOW THE - // SIMULATION TO BE PAUSED - while(paused){ - synchronized(syncObj){ - try { - syncObj.wait(); - } catch (InterruptedException e1) { - e1.printStackTrace(); - } - } - } - - int dest, src; - Sim_entity dest_ent; - // Update the system's clock - if (e.event_time() < clock) { - throw new Sim_exception("Sim_system: Past event detected."); - } - clock = e.event_time(); - // Ok now process it - switch(e.get_type()) { - case(Sim_event.ENULL): - throw new Sim_exception("Sim_system: Event has a null type."); - case(Sim_event.CREATE): - Sim_entity newe = (Sim_entity)e.get_data(); - add_entity_dynamically(newe); - break; - case(Sim_event.SEND): - // Check for matching wait - dest = e.get_dest(); - if (dest < 0) { - throw new Sim_exception("Sim_system: Attempt to send to a null entity detected."); - } else { - int tag = e.get_tag(); - if (((dest != e.get_src()) || (tag != 9999)) && ((Sim_entity)entities.get(dest)).has_stat()) { - ((Sim_entity)entities.get(dest)).update(Sim_stat.ARRIVAL, tag, clock); - } - dest_ent = (Sim_entity)entities.get(dest); - if (dest_ent.get_state() == Sim_entity.WAITING) { - Integer destObj = new Integer(dest); - Sim_predicate p = (Sim_predicate)wait_predicates.get(destObj); - if ((p == null) || (tag == 9999) || (p.match(e))) { - dest_ent.set_evbuf((Sim_event)e.clone()); - dest_ent.set_state(Sim_entity.RUNNABLE); - wait_predicates.remove(destObj); - } else { - deferred.add_event(e); - } - } else { - deferred.add_event(e); - } - } - break; - case(Sim_event.HOLD_DONE): - src = e.get_src(); - if (src<0) { - throw new Sim_exception("Sim_system: Null entity holding."); - } else { - ((Sim_entity)entities.get(src)).set_state(Sim_entity.RUNNABLE); - } - break; - } - } - - /** - * Set the sample generators' seed sequence. If this method is not called the defaults - * are 4851 as the root seed and 100000 as the desired sample spacing. - * @param seed_specing The seed spacing - * @param root_seed The seed used to generate all the simulation's seeds - */ - public static void set_seed_sequence(int seed_spacing, long root_seed) { - Sim_system.seed_spacing = seed_spacing; - Sim_system.root_seed = root_seed; - seed_source.set_seed(root_seed); - not_sampled = true; - } - - /** - * Set the sample generators' seed spacing. - * @param new_spacing The new seed spacing - */ - public static void set_spacing(int new_spacing) { - seed_spacing = new_spacing; - } - - /** - * Get the sample generators' seed spacing. - * @return The seed spacing - */ - public static int get_spacing() { - return seed_spacing; - } - - /** - * Set the sample generators' root seed. This is the seed used to generate the initial seeds - * for the simulation's sample generators. - * @param new_seed The new root seed - */ - public static void set_seed(long new_seed) { - root_seed = new_seed; - seed_source.set_seed(new_seed); - not_sampled = true; - } - - /** - * Get the sample generator's root seed. - * @return The root seed - */ - public static long get_root_seed() { - return root_seed; - } - - /** - * Generate the next seed based on the root seed and the seed spacing. This method - * is automatically called and doesn't need to be included on user simulations. - * @return The next well spaced seed - */ - public static long next_seed() { - long new_seed = seed_source.get_seed(); - if ((new_seed == root_seed) && not_sampled) { - not_sampled = false; - } else { - for (int i=0; i<seed_spacing; i++) { - seed_source.sample(); - } - new_seed = seed_source.get_seed(); - } - return new_seed; - } - - // Called when an event is considered to have completed service. If the event that completed is the one - // that determines the run length condition. - static synchronized void job_completed(int entity, int event_tag) { - if (term_condition == EVENTS_COMPLETED) { - if ((entity == term_entity_id) && (event_tag == term_event_type)) { - term_event_counter++; - if (trans_condition == MIN_MAX) { - term_times.add(new Double(clock)); - } - } - } - if (trans_condition == EVENTS_COMPLETED) { - if ((entity == trans_entity_id) && (event_tag == trans_event_type)) { - trans_event_counter++; - } - } - if (auto_trace && (default_trace || (event_trace && is_trace_tag(event_tag)))) { - trace(entity, "event type " + event_tag + " completed service"); - } - } - - // Called to update the count of collected observations of interest. This is done in the case of - // a termination condition based on collected observations and interval accuracy. - static synchronized void observation_collected(int entity, String measure) { - if ((term_condition == INTERVAL_ACCURACY) && - (entity == term_entity_id) && - (measure.equals(term_measure)) && - in_steady_state) { - term_event_counter++; - } - } - - /** - * Internal method used to initialise the simulation. This should <b>not</b> be called from user simulations. - */ - public static void run_initialise() { - start_date = System.currentTimeMillis(); - if (term_condition == INTERVAL_ACCURACY) { - switch (output_analysis_type) { - case IND_REPLICATIONS: - initial_term_count = 2500; - break; - case BATCH_MEANS: - term_count_bm = new int[2]; - term_count_bm[0] = 600; - term_count_bm[1] = 800; - term_count = 800; - break; - } - } else if (term_condition == EVENTS_COMPLETED) { - term_count = initial_term_count; - } else { - term_time = initial_term_time; - } - trans_count = initial_trans_count; - if (output_analysis_type == IND_REPLICATIONS) { - // Make a backup of the entities. This is done in order to perform independent replications - backup = new ArrayList(); - Sim_entity ent; - int entities_size = entities.size(); - for (int i=0; i < entities_size; i++) { - ent = (Sim_entity)entities.get(i); - try { - backup.add((Sim_entity)ent.clone()); - } catch (CloneNotSupportedException ex) { - throw new Sim_exception("Could not make backup of entity " + ent.get_name() + "."); - } - } - } - // Get the initial seeds used in the entities. - initial_seeds = new ArrayList(); - int entities_size = entities.size(); - for (int i=0; i < entities_size; i++) { - Sim_entity ent = (Sim_entity)entities.get(i); - String ent_name = ent.get_name(); - List generators = ent.get_generators(); - if (generators.size() == 0) { - continue; - } - List gens = new ArrayList(); - int generators_size = generators.size(); - for (int j=0; j < generators_size; j++) { - Generator gen = (Generator)generators.get(j); - gens.add(new Object[] {gen.get_name(), new Long(gen.get_seed())}); - } - initial_seeds.add(new Object[] {ent_name, gens}); - } - } - - /** - * Internal method used to start the simulation. This method should <b>not</b> be used by user simulations. - */ - public static void run_start() { - if (output_analysis_type == IND_REPLICATIONS) { - int count = 1; - if (replications != null) { - count = replications.size() + 1; - } - print_message("Performing replication #" + count + "."); - } - running = true; - // Start all the entities' threads - int entities_size = entities.size(); - for (int i=0; i < entities_size; i++) { - ((Sim_entity)entities.get(i)).start(); - } - // Wait until they're all up and ready - for (int i=0; i < entities_size; i++) { - onestopped.p(); - } - print_message("Entities started."); - } - - /** - * Specify a termination condition based on event completions at a specific entity. - * @param type The termination condition type. This must be set to <code>EVENTS_COMPLETED</code>. - * @param entity The name of the entity whose events will be used for the termination condition - * @param event_type The event tag of the events to be counted towards the termination condition - * @param count The event completion count that when reached, will satisfy the termination condition - * @param include_transient <code>true</code> if the number of completions provided should only apply to - * completions in steady state. <code>false</code> if they should apply to the entire - * run length. - */ - public static void set_termination_condition(int type, String entity, int event_type, long count, boolean include_transient) { - if (type != EVENTS_COMPLETED) { - throw new Sim_exception("The method used must be passed a condition based on completed events."); - } else if (count <= 0) { - throw new Sim_exception("The count for events completed must be positive."); - } else if (term_condition != NONE) { - throw new Sim_exception("You can't specify two termination conditions."); - } - term_condition = type; - term_entity_id = get_entity_id(entity); - term_event_type = event_type; - initial_term_count = count; - Sim_system.include_transient = include_transient; - } - - /** - * Specify a termination condition based on the simulation time elapsed. - * @param type The termination condition type. This must be set to <code>TIME_ELAPSED</code>. - * @param time The simulated time after which the termination condition will be satisfied - * @param include_transient <code>true</code> if the condition's time period should be considered - * only after steady state has been reached, <code>false</code> if it should - * be considered from the beginning of the simulation. - */ - public static void set_termination_condition(int type, double time, boolean include_transient) { - if (type != TIME_ELAPSED) { - throw new Sim_exception("The method used must be passed a condition based on the elapsed simulation time."); - } else if (time <= 0.0) { - throw new Sim_exception("The simulation termination time completed must be positive."); - } else if (term_condition != NONE) { - throw new Sim_exception("You can't specify two termination conditions."); - } - term_condition = type; - initial_term_time = time; - Sim_system.include_transient = include_transient; - } - - /** - * Specify a termination condition based on the confidence interval accuracy obtained for a custom measure. This - * condition is considered only once the transient period has elapsed. The accuracy is the ratio of the confidence - * interval's halfwidth over the measure's total mean. - * @param type The termination condition type. This must be set to <code>INTERVAL_ACCURACY</code>. - * @param output_analysis_type The output analysis method to be used as a variance reduction technique - * @param level The confidence level for which the confidence interval will be calculated - * @param accuracy The accuracy that is required to satisfy the termination condition - * @param entity The name of the entity that contains the measure upon which the termination condition is based - * @param measure The name of the custom measure upon which the termination condition is based - */ - public static void set_termination_condition(int type, int output_analysis_type, double level, double accuracy, String entity, String measure) { - if (type != INTERVAL_ACCURACY) { - throw new Sim_exception("The method used must be passed a condition based on the accuracy of a confidence interval."); - } else if ((output_analysis_type != IND_REPLICATIONS) && (output_analysis_type != BATCH_MEANS)) { - throw new Sim_exception("The output analysis method to be used must be either IND_REPLICATIONS or BATCH_MEANS."); - } else if ((level <= 0.0) || (level >= 1.0)) { - throw new Sim_exception("The confidence level must be between 0.0 and 1.0."); - } else if (accuracy <= 0.0) { - throw new Sim_exception("The interval accuracy tolerance must be greater than 0.0."); - } else if (Sim_system.output_analysis_type != NONE) { - throw new Sim_exception("When using this termination condition no other output analysis method can be specified."); - } else if (trans_condition == MIN_MAX) { - throw new Sim_exception("This termination condition can't be used when the minimum-maximum method is used."); - } else if (term_condition != NONE) { - throw new Sim_exception("You can't specify two termination conditions."); - } else if ((output_analysis_type == BATCH_MEANS) && (efficient_measure_defined)) { - throw new Sim_exception("Batch means may not be used when efficient measures are defined."); - } - term_entity_id = get_entity_id(entity); - Sim_stat stat = ((Sim_entity)entities.get(term_entity_id)).get_stat(); - if (stat == null) { - throw new Sim_exception("No measures have been defined for " + entity + "."); - } - int measure_type = stat.get_type(measure); - if (measure_type == -1) { - throw new Sim_exception(measure + " has not been defined for " + entity + "."); - } - term_condition = type; - term_measure = measure; - Sim_system.output_analysis_type = output_analysis_type; - confidence_level = level; - term_accuracy = accuracy; - replication_count = 5; - } - - /** - * Specify a termination condition based on the confidence interval accuracy obtained for a default measure. This - * condition is considered only once the transient period has elapsed. The accuracy is the ratio of the confidence - * interval's halfwidth over the measure's total mean. - * @param type The termination condition type. This must be set to <code>INTERVAL_ACCURACY</code>. - * @param output_analysis_type The output analysis method to be used as a variance reduction technique - * @param level The confidence level for which the confidence interval will be calculated - * @param accuracy The accuracy that is required to satisfy the termination condition - * @param entity The name of the entity that contains the measure upon which the termination condition is based - * @param measure The <code>int</code> constant that represents the default measure upon which the termination - * condition is based - */ - public static void set_termination_condition(int type, int output_analysis_type, double level, double accuracy, String entity, int measure) { - if (type != INTERVAL_ACCURACY) { - throw new Sim_exception("The method used must be passed a condition based on the accuracy of a confidence interval."); - } else if ((output_analysis_type != IND_REPLICATIONS) && (output_analysis_type != BATCH_MEANS)) { - throw new Sim_exception("The output analysis method to be used must be either IND_REPLICATIONS or BATCH_MEANS."); - } else if ((level <= 0.0) || (level >= 1.0)) { - throw new Sim_exception("The confidence level must be between 0.0 and 1.0."); - } else if (accuracy <= 0.0) { - throw new Sim_exception("The interval accuracy tolerance must be greater than 0.0."); - } else if (Sim_system.output_analysis_type != NONE) { - throw new Sim_exception("When using this termination condition no other output analysis method can be specified."); - } else if (trans_condition == MIN_MAX) { - throw new Sim_exception("This termination condition can't be used when the minimum-maximum method is used."); - } else if (term_condition != NONE) { - throw new Sim_exception("You can't specify two termination conditions."); - } else if ((output_analysis_type == BATCH_MEANS) && (efficient_measure_defined)) { - throw new Sim_exception("Batch means may not be used when efficient measures are defined."); - } - term_entity_id = get_entity_id(entity); - Sim_stat stat = ((Sim_entity)entities.get(term_entity_id)).get_stat(); - if (stat == null) { - throw new Sim_exception("No measures have been defined for " + entity + "."); - } - String measure_name = stat.get_name_default(measure); - int measure_type = stat.get_type(measure_name); - if (measure_type == -1) { - throw new Sim_exception(measure_name + " has not been defined for " + entity + "."); - } - term_condition = type; - term_measure = measure_name; - Sim_system.output_analysis_type = output_analysis_type; - confidence_level = level; - term_accuracy = accuracy; - replication_count = 5; - } - - /** - * Specify a transient condition using the minimum-maximum method for a custom measure. - * The minimum-maximum method considers the simulation to have entered steady state after the first - * observation of the given measure is found that is neither the minimum nor the maximum of the remaining - * observations. - * @param type The transient condition type. This must be set to <code>MIN_MAX</code>. - * @param entity The name of the entity that contains the measure upon which the minimum-maximum method will be - * applied - * @param measure The name of the custom measure upon which the minimum-maximum method will be applied - */ - public static void set_transient_condition(int type, String entity, String measure) { - if (type != MIN_MAX) { - throw new Sim_exception("The method used must be passed a condition based on minimum-maximum values of observations of a specific entity's measure."); - } else if (trans_condition != NONE) { - throw new Sim_exception("You can't specify two transient conditions."); - } else if ((term_condition == INTERVAL_ACCURACY) || (term_condition == NONE)) { - throw new Sim_exception("The minimum-maximum method can only be used with a termination of event completions or elapsed time."); - } else if (efficient_measure_defined) { - throw new Sim_exception("The minimum-maximum method can't be used with efficient measures."); - } - trans_condition = type; - trans_entity_id = get_entity_id(entity); - Sim_stat stat = ((Sim_entity)entities.get(trans_entity_id)).get_stat(); - if (stat == null) { - throw new Sim_exception("No measures have been defined for " + entity + "."); - } - int measure_type = stat.get_type(measure); - if (measure_type == -1) { - throw new Sim_exception(measure + " has not been defined for " + entity + "."); - } else if (((measure_type != Sim_stat.STATE_BASED) && (measure_type != Sim_stat.INTERVAL_BASED)) || (measure.equals("Utilisation"))) { - throw new Sim_exception(measure + " of " + entity + " has invalid type for a transient period estimator."); - } - trans_measure = measure; - term_times = new ArrayList(); - } - - /** - * Specify a transient condition using the minimum-maximum method for a default measure. - * The minimum-maximum method considers the simulation to have entered steady state after the first - * observation of the given measure is found that is neither the minimum nor the maximum of the remaining - * observations. - * @param type The transient condition type. This must be set to <code>MIN_MAX</code>. - * @param entity The name of the entity that contains the measure upon which the minimum-maximum method will be - * applied - * @param measure The <code>int</code> constant that represents the default measure upon which the minimum-maximum - * method will be applied - */ - public static void set_transient_condition(int type, String entity, int measure) { - if (type != MIN_MAX) { - throw new Sim_exception("The method used must be passed a condition based on minimum-maximum values of observations of a specific entity's measure."); - } else if (trans_condition != NONE) { - throw new Sim_exception("You can't specify two transient conditions."); - } else if ((term_condition == INTERVAL_ACCURACY) || (term_condition == NONE)) { - throw new Sim_exception("The minimum-maximum method can only be used with a termination of event completions or elapsed time."); - } else if (efficient_measure_defined) { - throw new Sim_exception("The minimum-maximum method can't be used with efficient measures."); - } - trans_condition = type; - trans_entity_id = get_entity_id(entity); - Sim_stat stat = ((Sim_entity)entities.get(trans_entity_id)).get_stat(); - if (stat == null) { - throw new Sim_exception("No measures have been defined for " + entity + "."); - } - String measure_name = stat.get_name_default(measure); - int measure_type = stat.get_type(measure_name); - if (measure_type == -1) { - throw new Sim_exception(measure_name + " has not been defined for " + entity + "."); - } else if (((measure_type != Sim_stat.STATE_BASED) && (measure_type != Sim_stat.INTERVAL_BASED)) || (measure_name.equals("Utilisation"))) { - throw new Sim_exception(measure_name + " of " + entity + " has invalid type for a transient period estimator."); - } - trans_measure = measure_name; - term_times = new ArrayList(); - } - - /** - * Specify a transient condition based on event completions at a specific entity. - * @param type The transient condition type. This must be set to <code>EVENTS_COMPLETED</code>. - * @param entity The name of the entity whise event completions will be counted towards this condition - * @param event_type The event tag of the events whose completions will be counted towards this condition - * @param count The number of event completions after which the condition will be satisfied - */ - public static void set_transient_condition(int type, String entity, int event_type, long count) { - if (type != EVENTS_COMPLETED) { - throw new Sim_exception("The method used must be passed a condition based on completed events."); - } else if (count <= 0) { - throw new Sim_exception("The count for events completed must be positive."); - } else if (trans_condition != NONE) { - throw new Sim_exception("You can't specify two transient conditions."); - } - trans_condition = type; - trans_entity_id = get_entity_id(entity); - trans_event_type = event_type; - initial_trans_count = count; - } - - /** - * Specify a transient condition based on the elapsed simulation time. - * @param type The transient condition type. This must be set to <code>TIME_ELAPSED</code>. - * @param time The time period after which the condition will be satisfied - */ - public static void set_transient_condition(int type, double time) { - if (type != TIME_ELAPSED) { - throw new Sim_exception("The method used must be passed a condition based on the elapsed simulation time."); - } else if (time <= 0.0) { - throw new Sim_exception("The transient time must be positive."); - } else if (trans_condition != NONE) { - throw new Sim_exception("You can't specify two transient conditions."); - } - trans_condition = type; - initial_trans_time = time; - } - - /** - * Specify an output analysis method for the simulation. The default, if this method is not used is <code>NONE</code>. - * If independent replications is selected, 10 replications will be performed. If batch means is selected, the - * observations will be batched into 10 to 20 batches. The actual number of batches used will be the one that - * gives the least serial correlation among the batch means. - * <p> - * The confidence level that will be used for calculating the simulation's measures' confidence intervals is - * <code>0.90</code> (<code>90%</code>). - * @param type The output analysis method - */ - public static void set_output_analysis(int type) { - if ((type != NONE) && (type != IND_REPLICATIONS) && (type != BATCH_MEANS)) { - throw new Sim_exception("The output analysis method must be either NONE, IND_REPLICATIONS or BATCH_MEANS."); - } else if (term_condition == INTERVAL_ACCURAC... [truncated message content] |