Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
peersimgrid release 1.0
[simgrid.git] / contrib / psg / src / peersim / cdsim / CDSimulator.java
1 /*
2  * Copyright (c) 2003-2005 The BISON Project
3  *
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.
7  *
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.
12  *
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.
16  *
17  */
18
19 package peersim.cdsim;
20
21 import java.util.*;
22 import peersim.config.*;
23 import peersim.core.*;
24
25 /**
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.
33  * <p>
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}.
41  * <p>
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.
48  * <p>
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.
54  * @see Configuration
55  */
56 public class CDSimulator
57 {
58
59 // ============== fields ===============================================
60 // =====================================================================
61
62 /**
63  * Parameter representing the maximum number of cycles to be performed
64  * @config
65  */
66 public static final String PAR_CYCLES = "simulation.cycles";
67
68 /**
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.
74  * @config
75  */
76 private static final String PAR_NOMAIN = "simulation.nodefaultcycle";
77
78 /**
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.
82  * @see Configuration
83  * @config
84  */
85 private static final String PAR_INIT = "init";
86
87 /**
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.
91  * @see Configuration
92  * @config
93  */
94 private static final String PAR_CTRL = "control";
95
96 // --------------------------------------------------------------------
97
98 /** The maximum number of cycles to be performed */
99 private static int cycles;
100
101 /** holds the modifiers of this simulation */
102 private static Control[] controls = null;
103
104 /** Holds the control schedulers of this simulation */
105 private static Scheduler[] ctrlSchedules = null;
106
107 // =============== initialization ======================================
108 // =====================================================================
109
110 /** to prevent construction */
111 private CDSimulator()
112 {
113 }
114
115 // =============== private methods =====================================
116 // =====================================================================
117
118 /**
119  * Load and run initializers.
120  */
121 private static void runInitializers()
122 {
123
124         Object[] inits = Configuration.getInstanceArray(PAR_INIT);
125         String names[] = Configuration.getNames(PAR_INIT);
126
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();
131         }
132 }
133
134 // --------------------------------------------------------------------
135
136 private static String[] loadControls()
137 {
138
139         boolean nomaincycle = Configuration.contains(PAR_NOMAIN);
140         String[] names = Configuration.getNames(PAR_CTRL);
141         if (nomaincycle) {
142                 controls = new Control[names.length];
143                 ctrlSchedules = new Scheduler[names.length];
144         } else {
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(" ");
151         }
152         for (int i = 0; i < names.length; ++i) {
153                 controls[i] = (Control) Configuration.getInstance(names[i]);
154                 ctrlSchedules[i] = new Scheduler(names[i]);
155         }
156         System.err.println("CDSimulator: loaded controls " + Arrays.asList(names));
157         return names;
158 }
159
160 // ---------------------------------------------------------------------
161
162 /**
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}.
166  */
167 public static final boolean isConfigurationCycleDriven()
168 {
169         return Configuration.contains(PAR_CYCLES);
170 }
171
172 // ---------------------------------------------------------------------
173
174 /**
175  * Runs an experiment, resetting everything except the random seed. 
176  */
177 public static final void nextExperiment()
178 {
179
180         // Reading parameter
181         cycles = Configuration.getInt(PAR_CYCLES);
182         if (CommonState.getEndTime() < 0) // not initialized yet
183                 CDState.setEndTime(cycles);
184
185         // initialization
186         CDState.setCycle(0);
187         CDState.setPhase(CDState.PHASE_UNKNOWN);
188         System.err.println("CDSimulator: resetting");
189         controls = null;
190         ctrlSchedules = null;
191         Network.reset();
192         System.err.println("CDSimulator: running initializers");
193         runInitializers();
194
195         // main cycle
196         loadControls();
197
198         System.err.println("CDSimulator: starting simulation");
199         for (int i = 0; i < cycles; ++i) {
200                 CDState.setCycle(i);
201
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();
206                 }
207                 if (stop)
208                         break;
209                 //System.err.println("CDSimulator: cycle " + i + " DONE");
210         }
211
212         CDState.setPhase(CDState.POST_SIMULATION);
213
214         // analysis after the simulation
215         for (int j = 0; j < controls.length; ++j) {
216                 if (ctrlSchedules[j].fin)
217                         controls[j].execute();
218         }
219 }
220
221 }