2 * Copyright (c) 2003-2005 The BISON Project
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 package peersim.cdsim;
22 import peersim.config.*;
23 import peersim.core.*;
26 * This is the cycle driven simulation engine. It is a fully static
27 * singleton class. For a cycle driven simulation the configuration can
28 * describe a set of {@link Protocol}s, and their ordering, a set of
29 * {@link Control}s and their ordering and a set of initializers and their
30 * ordering. See parameters {@value #PAR_INIT}, {@value #PAR_CTRL}. Out
31 * of the set of protocols, this engine only executes the ones that
32 * implement the {@link CDProtocol} interface.
34 * One experiment run by {@link #nextExperiment} works as follows. First
35 * the initializers are run in the specified order, then the following is
36 * iterated {@value #PAR_CYCLES} times: If {@value #PAR_NOMAIN} is
37 * specified, then simply the controls specified in the configuration are
38 * run in the specified order. If {@value #PAR_NOMAIN} is not specified,
39 * then the controls in the configuration are run in the specified order,
40 * followed by the execution of {@link FullNextCycle}.
42 * All components (controls and protocols) can have configuration
43 * parameters that control their scheduling (see {@link Scheduler}). This
44 * way they can skip cycles, start from a specified cycle, etc. As a
45 * special case, components can be scheduled to run after the last cycle.
46 * That is, each experiment is finished by running the controls that are
47 * scheduled after the last cycle.
49 * Finally, any control can interrupt an experiment at any time it is
50 * executed by returning true in method {@link Control#execute}. However,
51 * the controls scheduled to run after the last cycle are still executed
52 * completely, irrespective of their return value and even if the
53 * experiment was interrupted.
56 public class CDSimulator
59 // ============== fields ===============================================
60 // =====================================================================
63 * Parameter representing the maximum number of cycles to be performed
66 public static final String PAR_CYCLES = "simulation.cycles";
69 * This option is only for experts. It switches off the main cycle that
70 * calls the cycle driven protocols. When you switch this off, you need to
71 * control the execution of the protocols by configuring controls that do
72 * the job (e.g., {@link FullNextCycle}, {@link NextCycle}). It's there for
73 * people who want maximal flexibility for their hacks.
76 private static final String PAR_NOMAIN = "simulation.nodefaultcycle";
79 * This is the prefix for initializers. These have to be of type
80 * {@link Control}. They are run at the beginning of each experiment, in
81 * the order specified by the configuration.
85 private static final String PAR_INIT = "init";
88 * This is the prefix for controls. These have to be of type
89 * {@link Control}. They are run before each cycle, in the order specified
90 * by the configuration.
94 private static final String PAR_CTRL = "control";
96 // --------------------------------------------------------------------
98 /** The maximum number of cycles to be performed */
99 private static int cycles;
101 /** holds the modifiers of this simulation */
102 private static Control[] controls = null;
104 /** Holds the control schedulers of this simulation */
105 private static Scheduler[] ctrlSchedules = null;
107 // =============== initialization ======================================
108 // =====================================================================
110 /** to prevent construction */
111 private CDSimulator()
115 // =============== private methods =====================================
116 // =====================================================================
119 * Load and run initializers.
121 private static void runInitializers()
124 Object[] inits = Configuration.getInstanceArray(PAR_INIT);
125 String names[] = Configuration.getNames(PAR_INIT);
127 for (int i = 0; i < inits.length; ++i) {
128 System.err.println("- Running initializer " + names[i] + ": "
129 + inits[i].getClass());
130 ((Control) inits[i]).execute();
134 // --------------------------------------------------------------------
136 private static String[] loadControls()
139 boolean nomaincycle = Configuration.contains(PAR_NOMAIN);
140 String[] names = Configuration.getNames(PAR_CTRL);
142 controls = new Control[names.length];
143 ctrlSchedules = new Scheduler[names.length];
145 // provide for an extra control that handles the main cycle
146 controls = new Control[names.length + 1];
147 ctrlSchedules = new Scheduler[names.length + 1];
148 // calling with a prefix that cannot exist
149 controls[names.length] = new FullNextCycle(" ");
150 ctrlSchedules[names.length] = new Scheduler(" ");
152 for (int i = 0; i < names.length; ++i) {
153 controls[i] = (Control) Configuration.getInstance(names[i]);
154 ctrlSchedules[i] = new Scheduler(names[i]);
156 System.err.println("CDSimulator: loaded controls " + Arrays.asList(names));
160 // ---------------------------------------------------------------------
163 * This method is used to check whether the current configuration can be
164 * used for cycle-driven simulations. It checks for the existence of
165 * configuration parameter {@value #PAR_CYCLES}.
167 public static final boolean isConfigurationCycleDriven()
169 return Configuration.contains(PAR_CYCLES);
172 // ---------------------------------------------------------------------
175 * Runs an experiment, resetting everything except the random seed.
177 public static final void nextExperiment()
181 cycles = Configuration.getInt(PAR_CYCLES);
182 if (CommonState.getEndTime() < 0) // not initialized yet
183 CDState.setEndTime(cycles);
187 CDState.setPhase(CDState.PHASE_UNKNOWN);
188 System.err.println("CDSimulator: resetting");
190 ctrlSchedules = null;
192 System.err.println("CDSimulator: running initializers");
198 System.err.println("CDSimulator: starting simulation");
199 for (int i = 0; i < cycles; ++i) {
202 boolean stop = false;
203 for (int j = 0; j < controls.length; ++j) {
204 if (ctrlSchedules[j].active(i))
205 stop = stop || controls[j].execute();
209 //System.err.println("CDSimulator: cycle " + i + " DONE");
212 CDState.setPhase(CDState.POST_SIMULATION);
214 // analysis after the simulation
215 for (int j = 0; j < controls.length; ++j) {
216 if (ctrlSchedules[j].fin)
217 controls[j].execute();