Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
kill another out of date script
[simgrid.git] / contrib / psg / src / peersim / edsim / CDScheduler.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.edsim;
20
21 import peersim.core.*;
22 import peersim.cdsim.CDProtocol;
23 import peersim.config.*;
24 import peersim.dynamics.NodeInitializer;
25
26 /**
27  * Schedules the first execution of the cycle based protocol instances in the
28  * event driven engine. It implements {@link Control} but it will most often be
29  * invoked only once for each protocol as an initializer, since the scheduled
30  * events schedule themselves for the consecutive executions (see
31  * {@link NextCycleEvent}).
32  *
33  * <p>
34  * All {@link CDProtocol} specifications in the configuration need to contain a
35  * {@link Scheduler} specification at least for the step size (see config
36  * parameter {@value peersim.core.Scheduler#PAR_STEP} of {@link Scheduler}).
37  * This value is used as the cycle length for the corresponding protocol.
38  *
39  * @see NextCycleEvent
40  */
41 public class CDScheduler implements Control, NodeInitializer {
42
43         // ============================== fields ==============================
44         // ====================================================================
45
46         /**
47          * Parameter that is used to define the class that is used to schedule the
48          * next cycle. Its type is (or extends) {@link NextCycleEvent}. Defaults to
49          * {@link NextCycleEvent}.
50          * 
51          * @config
52          */
53         private static final String PAR_NEXTC = "nextcycle";
54
55         /**
56          * The protocols that this scheduler schedules for the first execution. It
57          * might contain several protocol names, separated by whitespace. All
58          * protocols will be scheduled based on the common parameter set for this
59          * scheduler and the parameters of the protocol (cycle length). Protocols
60          * are scheduled independently of each other.
61          * 
62          * @config
63          */
64         private static final String PAR_PROTOCOL = "protocol";
65
66         /**
67          * If set, it means that the initial execution of the given protocol is
68          * scheduled for a different random time for all nodes. The random time is a
69          * sample between the current time (inclusive) and the cycle length
70          * (exclusive), the latter being specified by the step parameter (see
71          * {@link Scheduler}) of the assigned protocol.
72          * 
73          * @see #execute
74          * @config
75          */
76         private static final String PAR_RNDSTART = "randstart";
77
78         /**
79          * Contains the scheduler objects for all {@link CDProtocol}s defined in the
80          * configuration. The length of the array is the number of protocols
81          * defined, but those entries that belong to protocols that are not
82          * {@link CDProtocol}s are null.
83          */
84         public static final Scheduler[] sch;
85
86         private final NextCycleEvent[] nce;
87
88         private final int[] pid;
89
90         private final boolean randstart;
91
92         // =============================== initialization ======================
93         // =====================================================================
94
95         /**
96          * Loads protocol schedulers for all protocols.
97          */
98         static {
99
100                 String[] names = Configuration.getNames(Node.PAR_PROT);
101                 sch = new Scheduler[names.length];
102                 for (int i = 0; i < names.length; ++i) {
103                         if (Network.prototype.getProtocol(i) instanceof CDProtocol)
104                                 // with no default values for step to avoid
105                                 // "overscheduling" due to lack of step option.
106                                 sch[i] = new Scheduler(names[i], false);
107                 }
108         }
109
110         // --------------------------------------------------------------------
111
112         /**
113          * Initialization based on configuration parameters.
114          */
115         public CDScheduler(String n) {
116                 String[] prots = Configuration.getString(n + "." + PAR_PROTOCOL).split("\\s");
117                 pid = new int[prots.length];
118                 nce = new NextCycleEvent[prots.length];
119                 for (int i = 0; i < prots.length; ++i) {
120                         pid[i] = Configuration.lookupPid(prots[i]);
121                         if (!(Network.prototype.getProtocol(pid[i]) instanceof CDProtocol)) {
122                                 throw new IllegalParameterException(n + "." + PAR_PROTOCOL,
123                                                 "Only CDProtocols are accepted here");
124                         }
125                         nce[i] = (NextCycleEvent) Configuration.getInstance(n + "."
126                                         + PAR_NEXTC, new NextCycleEvent(null));
127                 }
128                 randstart = Configuration.contains(n + "." + PAR_RNDSTART);
129         }
130
131         // ========================== methods ==================================
132         // =====================================================================
133
134         /**
135          * Schedules the protocol at all nodes for the first execution adding it to
136          * the priority queue of the event driven simulation. The time of the first
137          * execution is determined by {@link #firstDelay}. The implementation calls
138          * {@link #initialize} for all nodes.
139          * 
140          * @see #initialize
141          */
142         public boolean execute() {
143
144                 for (int i = 0; i < Network.size(); ++i) {
145                         initialize(Network.get(i));
146                 }
147
148                 return false;
149         }
150
151         // --------------------------------------------------------------------
152
153         /**
154          * Schedules the protocol at given node for the first execution adding it to
155          * the priority queue of the event driven simulation. The time of the first
156          * execution is determined by a reference point in time and
157          * {@link #firstDelay}, which defines the delay from the reference point.
158          * The reference point is the maximum of the current time, and the value of
159          * parameter {@value peersim.core.Scheduler#PAR_FROM} of the protocol being
160          * scheduled. If the calculated time of the first execution is not valid
161          * according to the schedule of the protocol then no execution is scheduled
162          * for that protocol.
163          * <p>
164          * A final note: for performance reasons, the recommended practice is not to
165          * use parameter {@value peersim.core.Scheduler#PAR_FROM} in protocols, but
166          * to schedule {@link CDScheduler} itself for the desired time, whenever
167          * possible (e.g., it is not possible if {@link CDScheduler} is used as a
168          * {@link NodeInitializer}).
169          */
170         public void initialize(Node n) {
171                 /*
172                  * XXX If "from" is not the current time and this is used as a control
173                  * (not node initializer) then we dump _lots_ of events in the queue
174                  * that are just stored there until "from" comes. This reduces
175                  * performance, and should be fixed. When fixed, the final comment can
176                  * be removed from the docs.
177                  */
178
179                 final long time = CommonState.getTime();
180                 for (int i = 0; i < pid.length; ++i) {
181                         Object nceclone = null;
182                         try {
183                                 nceclone = nce[i].clone();
184                         } catch (CloneNotSupportedException e) {
185                         } // cannot possibly happen
186
187                         final long delay = firstDelay(sch[pid[i]].step);
188                         final long nexttime = Math.max(time, sch[pid[i]].from) + delay;
189                         if (nexttime < sch[pid[i]].until)
190                                 EDSimulator.add(nexttime - time, nceclone, n, pid[i]);
191                 }
192         }
193
194         // --------------------------------------------------------------------
195
196         /**
197          * Returns the time (through giving the delay from the current time) when
198          * this even is first executed. If {@value #PAR_RNDSTART} is not set, it
199          * returns zero, otherwise a random value between 0, inclusive, and
200          * cyclelength, exclusive.
201          * 
202          * @param cyclelength
203          *            The cycle length of the cycle based protocol for which this
204          *            method is called
205          */
206         protected long firstDelay(long cyclelength) {
207
208                 if (randstart)
209                         return CommonState.r.nextLong(cyclelength);
210                 else
211                         return 0;
212         }
213 }