Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
peersimgrid release 1.0
[simgrid.git] / contrib / psg / src / peersim / cdsim / CDSimulator.java
diff --git a/contrib/psg/src/peersim/cdsim/CDSimulator.java b/contrib/psg/src/peersim/cdsim/CDSimulator.java
new file mode 100644 (file)
index 0000000..f487594
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2003-2005 The BISON Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+package peersim.cdsim;
+
+import java.util.*;
+import peersim.config.*;
+import peersim.core.*;
+
+/**
+ * This is the cycle driven simulation engine. It is a fully static
+ * singleton class. For a cycle driven simulation the configuration can
+ * describe a set of {@link Protocol}s, and their ordering, a set of
+ * {@link Control}s and their ordering and a set of initializers and their
+ * ordering. See parameters {@value #PAR_INIT}, {@value #PAR_CTRL}. Out
+ * of the set of protocols, this engine only executes the ones that
+ * implement the {@link CDProtocol} interface.
+ * <p>
+ * One experiment run by {@link #nextExperiment} works as follows. First
+ * the initializers are run in the specified order, then the following is
+ * iterated {@value #PAR_CYCLES} times: If {@value #PAR_NOMAIN} is
+ * specified, then simply the controls specified in the configuration are
+ * run in the specified order. If {@value #PAR_NOMAIN} is not specified,
+ * then the controls in the configuration are run in the specified order,
+ * followed by the execution of {@link FullNextCycle}.
+ * <p>
+ * All components (controls and protocols) can have configuration
+ * parameters that control their scheduling (see {@link Scheduler}). This
+ * way they can skip cycles, start from a specified cycle, etc. As a
+ * special case, components can be scheduled to run after the last cycle.
+ * That is, each experiment is finished by running the controls that are
+ * scheduled after the last cycle.
+ * <p>
+ * Finally, any control can interrupt an experiment at any time it is
+ * executed by returning true in method {@link Control#execute}. However,
+ * the controls scheduled to run after the last cycle are still executed
+ * completely, irrespective of their return value and even if the
+ * experiment was interrupted.
+ * @see Configuration
+ */
+public class CDSimulator
+{
+
+// ============== fields ===============================================
+// =====================================================================
+
+/**
+ * Parameter representing the maximum number of cycles to be performed
+ * @config
+ */
+public static final String PAR_CYCLES = "simulation.cycles";
+
+/**
+ * This option is only for experts. It switches off the main cycle that
+ * calls the cycle driven protocols. When you switch this off, you need to
+ * control the execution of the protocols by configuring controls that do
+ * the job (e.g., {@link FullNextCycle}, {@link NextCycle}). It's there for
+ * people who want maximal flexibility for their hacks.
+ * @config
+ */
+private static final String PAR_NOMAIN = "simulation.nodefaultcycle";
+
+/**
+ * This is the prefix for initializers. These have to be of type
+ * {@link Control}. They are run at the beginning of each experiment, in
+ * the order specified by the configuration.
+ * @see Configuration
+ * @config
+ */
+private static final String PAR_INIT = "init";
+
+/**
+ * This is the prefix for controls. These have to be of type
+ * {@link Control}. They are run before each cycle, in the order specified
+ * by the configuration.
+ * @see Configuration
+ * @config
+ */
+private static final String PAR_CTRL = "control";
+
+// --------------------------------------------------------------------
+
+/** The maximum number of cycles to be performed */
+private static int cycles;
+
+/** holds the modifiers of this simulation */
+private static Control[] controls = null;
+
+/** Holds the control schedulers of this simulation */
+private static Scheduler[] ctrlSchedules = null;
+
+// =============== initialization ======================================
+// =====================================================================
+
+/** to prevent construction */
+private CDSimulator()
+{
+}
+
+// =============== private methods =====================================
+// =====================================================================
+
+/**
+ * Load and run initializers.
+ */
+private static void runInitializers()
+{
+
+       Object[] inits = Configuration.getInstanceArray(PAR_INIT);
+       String names[] = Configuration.getNames(PAR_INIT);
+
+       for (int i = 0; i < inits.length; ++i) {
+               System.err.println("- Running initializer " + names[i] + ": "
+                               + inits[i].getClass());
+               ((Control) inits[i]).execute();
+       }
+}
+
+// --------------------------------------------------------------------
+
+private static String[] loadControls()
+{
+
+       boolean nomaincycle = Configuration.contains(PAR_NOMAIN);
+       String[] names = Configuration.getNames(PAR_CTRL);
+       if (nomaincycle) {
+               controls = new Control[names.length];
+               ctrlSchedules = new Scheduler[names.length];
+       } else {
+               // provide for an extra control that handles the main cycle
+               controls = new Control[names.length + 1];
+               ctrlSchedules = new Scheduler[names.length + 1];
+               // calling with a prefix that cannot exist
+               controls[names.length] = new FullNextCycle(" ");
+               ctrlSchedules[names.length] = new Scheduler(" ");
+       }
+       for (int i = 0; i < names.length; ++i) {
+               controls[i] = (Control) Configuration.getInstance(names[i]);
+               ctrlSchedules[i] = new Scheduler(names[i]);
+       }
+       System.err.println("CDSimulator: loaded controls " + Arrays.asList(names));
+       return names;
+}
+
+// ---------------------------------------------------------------------
+
+/**
+ * This method is used to check whether the current configuration can be
+ * used for cycle-driven simulations. It checks for the existence of
+ * configuration parameter {@value #PAR_CYCLES}.
+ */
+public static final boolean isConfigurationCycleDriven()
+{
+       return Configuration.contains(PAR_CYCLES);
+}
+
+// ---------------------------------------------------------------------
+
+/**
+ * Runs an experiment, resetting everything except the random seed. 
+ */
+public static final void nextExperiment()
+{
+
+       // Reading parameter
+       cycles = Configuration.getInt(PAR_CYCLES);
+       if (CommonState.getEndTime() < 0) // not initialized yet
+               CDState.setEndTime(cycles);
+
+       // initialization
+       CDState.setCycle(0);
+       CDState.setPhase(CDState.PHASE_UNKNOWN);
+       System.err.println("CDSimulator: resetting");
+       controls = null;
+       ctrlSchedules = null;
+       Network.reset();
+       System.err.println("CDSimulator: running initializers");
+       runInitializers();
+
+       // main cycle
+       loadControls();
+
+       System.err.println("CDSimulator: starting simulation");
+       for (int i = 0; i < cycles; ++i) {
+               CDState.setCycle(i);
+
+               boolean stop = false;
+               for (int j = 0; j < controls.length; ++j) {
+                       if (ctrlSchedules[j].active(i))
+                               stop = stop || controls[j].execute();
+               }
+               if (stop)
+                       break;
+               //System.err.println("CDSimulator: cycle " + i + " DONE");
+       }
+
+       CDState.setPhase(CDState.POST_SIMULATION);
+
+       // analysis after the simulation
+       for (int j = 0; j < controls.length; ++j) {
+               if (ctrlSchedules[j].fin)
+                       controls[j].execute();
+       }
+}
+
+}