1 | package de.uka.ipd.sdq.scheduler.processes.impl; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.List; |
5 | |
6 | import de.uka.ipd.sdq.probfunction.math.util.MathTools; |
7 | import de.uka.ipd.sdq.scheduler.ISchedulableProcess; |
8 | import de.uka.ipd.sdq.scheduler.SchedulerModel; |
9 | import de.uka.ipd.sdq.scheduler.entities.SchedulerEntity; |
10 | import de.uka.ipd.sdq.scheduler.events.IDelayedAction; |
11 | import de.uka.ipd.sdq.scheduler.events.ProceedEvent; |
12 | import de.uka.ipd.sdq.scheduler.loaddistribution.IResourceInstanceConstraint; |
13 | import de.uka.ipd.sdq.scheduler.loaddistribution.constraints.MultipleResourceInstancesConstraint; |
14 | import de.uka.ipd.sdq.scheduler.loaddistribution.constraints.SingleResourceInstanceConstraint; |
15 | import de.uka.ipd.sdq.scheduler.processes.IActiveProcess; |
16 | import de.uka.ipd.sdq.scheduler.processes.PROCESS_STATE; |
17 | import de.uka.ipd.sdq.scheduler.queueing.IRunQueue; |
18 | import de.uka.ipd.sdq.scheduler.resources.IResourceInstance; |
19 | import de.uka.ipd.sdq.scheduler.sensors.IProcessStateSensor; |
20 | import de.uka.ipd.sdq.scheduler.strategy.IScheduler; |
21 | |
22 | public class ActiveProcess extends SchedulerEntity implements IActiveProcess { |
23 | |
24 | /** |
25 | * Creates a new wrapper containing the running information of a process. |
26 | * |
27 | * @param process |
28 | * The process that should be executed. |
29 | * |
30 | * @param id |
31 | * A unique identifier of the process. |
32 | */ |
33 | public ActiveProcess(SchedulerModel model, ISchedulableProcess process) { |
34 | super(model, ActiveProcess.class.getName()); |
35 | |
36 | this.affinityConstraint = null; |
37 | this.currentDemand = 0; |
38 | this.idealInstanceConstraint = null; |
39 | this.lastInstanceConstraint = null; |
40 | this.lastUpdateTime = 0; |
41 | this.proceedEvent = new ProceedEvent(model); |
42 | this.process = process; |
43 | this.processStateSensorList = new ArrayList<IProcessStateSensor>(); |
44 | this.runqueue = null; |
45 | this.state = PROCESS_STATE.READY; |
46 | } |
47 | |
48 | // ///////////////////////////////////////////////////////////////////// |
49 | // Basics |
50 | // ///////////////////////////////////////////////////////////////////// |
51 | |
52 | private ISchedulableProcess process; |
53 | private IRunQueue runqueue; |
54 | |
55 | public void update() { |
56 | } |
57 | |
58 | public IRunQueue getRunQueue() { |
59 | return runqueue; |
60 | } |
61 | |
62 | public void setRunQueue(IRunQueue runqueue){ |
63 | this.runqueue = runqueue; |
64 | } |
65 | |
66 | public ISchedulableProcess getSchedulableProcess() { |
67 | return process; |
68 | } |
69 | |
70 | public String getName() { |
71 | return process.getId(); |
72 | } |
73 | |
74 | public String getId(){ |
75 | return process.getId(); |
76 | } |
77 | |
78 | @Override |
79 | public String toString() { |
80 | return process.toString(); |
81 | } |
82 | |
83 | @Override |
84 | public boolean equals(Object obj) { |
85 | if (obj instanceof ActiveProcess) { |
86 | ActiveProcess process = (ActiveProcess) obj; |
87 | return process.getId().equals(this.getId()); |
88 | } |
89 | return false; |
90 | } |
91 | |
92 | @Override |
93 | public int hashCode() { |
94 | String id = getId(); |
95 | int hashCode = id.hashCode(); |
96 | return hashCode; |
97 | } |
98 | |
99 | // ///////////////////////////////////////////////////////////////////// |
100 | // Process State |
101 | // ///////////////////////////////////////////////////////////////////// |
102 | |
103 | private PROCESS_STATE state = PROCESS_STATE.READY; |
104 | private List<IProcessStateSensor> processStateSensorList; |
105 | |
106 | public PROCESS_STATE getState() { |
107 | return state; |
108 | } |
109 | |
110 | public void setState(PROCESS_STATE new_state) { |
111 | state = new_state; |
112 | for (IProcessStateSensor sensor : processStateSensorList) { |
113 | sensor.update(new_state); |
114 | } |
115 | } |
116 | |
117 | /* (non-Javadoc) |
118 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#setRunning() |
119 | */ |
120 | public void setRunning() { |
121 | setState(PROCESS_STATE.RUNNING); |
122 | just_blanced = false; |
123 | } |
124 | |
125 | /* (non-Javadoc) |
126 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#setReady() |
127 | */ |
128 | public void setReady() { |
129 | setState(PROCESS_STATE.READY); |
130 | } |
131 | |
132 | /* (non-Javadoc) |
133 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#setWaiting() |
134 | */ |
135 | public void setWaiting() { |
136 | setState(PROCESS_STATE.WAITING); |
137 | } |
138 | |
139 | /* (non-Javadoc) |
140 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#isRunning() |
141 | */ |
142 | public boolean isRunning() { |
143 | return getState() == PROCESS_STATE.RUNNING; |
144 | } |
145 | |
146 | /* (non-Javadoc) |
147 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#isReady() |
148 | */ |
149 | public boolean isReady() { |
150 | return getState() == PROCESS_STATE.READY; |
151 | } |
152 | |
153 | /* (non-Javadoc) |
154 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#isWaiting() |
155 | */ |
156 | public boolean isWaiting() { |
157 | return getState() == PROCESS_STATE.WAITING; |
158 | } |
159 | |
160 | /* (non-Javadoc) |
161 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#addStateSensor(de.uka.ipd.sdq.scheduler.processes.IProcessStateSensor) |
162 | */ |
163 | public void addStateSensor(IProcessStateSensor sensor) { |
164 | processStateSensorList.add(sensor); |
165 | } |
166 | |
167 | /* (non-Javadoc) |
168 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#removeStateSensor(de.uka.ipd.sdq.scheduler.processes.IProcessStateSensor) |
169 | */ |
170 | public void removeStateSensor(IProcessStateSensor sensor) { |
171 | processStateSensorList.remove(sensor); |
172 | } |
173 | |
174 | // ///////////////////////////////////////////////////////////////////// |
175 | // Timing |
176 | // ///////////////////////////////////////////////////////////////////// |
177 | |
178 | private double currentDemand = 0; |
179 | private double lastUpdateTime = 0; |
180 | |
181 | /* (non-Javadoc) |
182 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#getCurrentDemand() |
183 | */ |
184 | public double getCurrentDemand() { |
185 | return currentDemand; |
186 | } |
187 | |
188 | /* (non-Javadoc) |
189 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#setCurrentDemand(double) |
190 | */ |
191 | public void setCurrentDemand(double currentDemand) { |
192 | assert MathTools.equalsDouble(this.currentDemand, 0.0) : this.currentDemand; |
193 | this.currentDemand = currentDemand; |
194 | } |
195 | |
196 | public void toNow() { |
197 | double currentTime = getModel().getSimulationControl().getCurrentSimulationTime(); |
198 | if (isRunning()) { |
199 | double passedTime = currentTime - lastUpdateTime; |
200 | if (passedTime > MathTools.EPSILON_ERROR) { |
201 | passTimeProcessing(passedTime); |
202 | } |
203 | } |
204 | lastUpdateTime = currentTime; |
205 | } |
206 | |
207 | |
208 | protected void passTimeProcessing(double passedTime) { |
209 | currentDemand -= passedTime; |
210 | if(MathTools.equalsDouble(currentDemand, 0)) |
211 | currentDemand = 0; |
212 | } |
213 | |
214 | |
215 | // ///////////////////////////////////////////////////////////////////// |
216 | // Resource Instance Constraints |
217 | // ///////////////////////////////////////////////////////////////////// |
218 | |
219 | private MultipleResourceInstancesConstraint affinityConstraint; |
220 | private SingleResourceInstanceConstraint idealInstanceConstraint; |
221 | private SingleResourceInstanceConstraint lastInstanceConstraint; |
222 | private double movedAtTime = 0; |
223 | private boolean just_blanced = false; |
224 | |
225 | /* (non-Javadoc) |
226 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#setAffineInstances(java.util.List) |
227 | */ |
228 | public void setAffineInstances(List<IResourceInstance> instanceList) { |
229 | affinityConstraint = new MultipleResourceInstancesConstraint( |
230 | instanceList); |
231 | } |
232 | |
233 | /* (non-Javadoc) |
234 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#hasAffinityList() |
235 | */ |
236 | public boolean hasAffinityList() { |
237 | return affinityConstraint != null; |
238 | } |
239 | |
240 | /* (non-Javadoc) |
241 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#checkAffinity(de.uka.ipd.sdq.scheduler.resources.IResourceInstance) |
242 | */ |
243 | public boolean checkAffinity(IResourceInstance instance) { |
244 | return checkInstanceConstraint(affinityConstraint, instance); |
245 | } |
246 | |
247 | /* (non-Javadoc) |
248 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#removeNonAffineInstances(java.util.List) |
249 | */ |
250 | public void removeNonAffineInstances(List<IResourceInstance> instances) { |
251 | if (hasAffinityList()) { |
252 | for (IResourceInstance instance : instances) { |
253 | if (!affinityConstraint.check(instance)) { |
254 | instances.remove(instance); |
255 | } |
256 | } |
257 | } |
258 | } |
259 | |
260 | /* (non-Javadoc) |
261 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#setIdealInstance(de.uka.ipd.sdq.scheduler.resources.IResourceInstance) |
262 | */ |
263 | public void setIdealInstance(IResourceInstance instance) { |
264 | if (instance != null) { |
265 | idealInstanceConstraint = new SingleResourceInstanceConstraint(instance); |
266 | } else { |
267 | idealInstanceConstraint = null; |
268 | } |
269 | |
270 | |
271 | } |
272 | |
273 | /* (non-Javadoc) |
274 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#hasIdealInstance() |
275 | */ |
276 | public boolean hasIdealInstance() { |
277 | return idealInstanceConstraint != null; |
278 | } |
279 | |
280 | /* (non-Javadoc) |
281 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#isIdealInstance(de.uka.ipd.sdq.scheduler.resources.IResourceInstance) |
282 | */ |
283 | public boolean isIdealInstance(IResourceInstance instance) { |
284 | return checkInstanceConstraint(idealInstanceConstraint, instance); |
285 | } |
286 | |
287 | /* (non-Javadoc) |
288 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#getIdealInstance() |
289 | */ |
290 | public IResourceInstance getIdealInstance() { |
291 | if (hasIdealInstance()) { |
292 | return idealInstanceConstraint.getResourceInstance(); |
293 | } |
294 | return null; |
295 | } |
296 | |
297 | |
298 | /* (non-Javadoc) |
299 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#setLastInstance(de.uka.ipd.sdq.scheduler.resources.IResourceInstance) |
300 | */ |
301 | public void setLastInstance(IResourceInstance instance) { |
302 | if (instance != null){ |
303 | lastInstanceConstraint = new SingleResourceInstanceConstraint(instance); |
304 | } else { |
305 | lastInstanceConstraint = null; |
306 | } |
307 | } |
308 | |
309 | /* (non-Javadoc) |
310 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#hasLastInstance() |
311 | */ |
312 | public boolean hasLastInstance() { |
313 | return lastInstanceConstraint != null; |
314 | } |
315 | |
316 | /* (non-Javadoc) |
317 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#getLastInstance() |
318 | */ |
319 | public IResourceInstance getLastInstance() { |
320 | if (hasLastInstance()) |
321 | return lastInstanceConstraint.getResourceInstance(); |
322 | return null; |
323 | } |
324 | |
325 | /* (non-Javadoc) |
326 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#isLastInstance(de.uka.ipd.sdq.scheduler.resources.IResourceInstance) |
327 | */ |
328 | public boolean isLastInstance(IResourceInstance instance) { |
329 | return checkInstanceConstraint(lastInstanceConstraint, instance); |
330 | } |
331 | |
332 | private boolean checkInstanceConstraint( |
333 | IResourceInstanceConstraint constraint, IResourceInstance instance) { |
334 | if (constraint != null) { |
335 | return constraint.check(instance); |
336 | } |
337 | // if no constraint is defined, every instance is accepted. |
338 | return true; |
339 | } |
340 | |
341 | |
342 | // ///////////////////////////////////////////////////////////////////// |
343 | // Load Balancing |
344 | // ///////////////////////////////////////////////////////////////////// |
345 | |
346 | public boolean isMovable(IResourceInstance targetInstance) { |
347 | return checkAffinity(targetInstance) && !just_blanced; |
348 | } |
349 | |
350 | public void wasMovedTo(IResourceInstance dest) { |
351 | this.setLastInstance(dest); |
352 | this.setIdealInstance(dest); |
353 | this.just_blanced = true; |
354 | } |
355 | |
356 | |
357 | // ///////////////////////////////////////////////////////////////////// |
358 | // Events |
359 | // ///////////////////////////////////////////////////////////////////// |
360 | |
361 | private ProceedEvent proceedEvent = null; |
362 | |
363 | /* (non-Javadoc) |
364 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#scheduleProceedEvent() |
365 | */ |
366 | public void scheduleProceedEvent(IScheduler scheduler) { |
367 | cancelProceedEvent(); |
368 | proceedEvent.setScheduler(scheduler); |
369 | proceedEvent.schedule(this, getCurrentDemand()); |
370 | } |
371 | |
372 | /* (non-Javadoc) |
373 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#cancelProceedEvent() |
374 | */ |
375 | public void cancelProceedEvent() { |
376 | proceedEvent.removeEvent(); |
377 | } |
378 | |
379 | |
380 | /* (non-Javadoc) |
381 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#getTimeUntilNextInterruption() |
382 | */ |
383 | public double getTimeUntilNextInterruption() { |
384 | return currentDemand; |
385 | } |
386 | |
387 | /* (non-Javadoc) |
388 | * @see de.uka.ipd.sdq.scheduler.processes.impl.IRunnableProcess#setDelayedAction(de.uka.ipd.sdq.scheduler.events.IDelayedAction) |
389 | */ |
390 | public void setDelayedAction(IDelayedAction action) { |
391 | this.proceedEvent.setDelayedAction(action); |
392 | } |
393 | |
394 | public IActiveProcess createNewInstance(SchedulerModel model, ISchedulableProcess process) { |
395 | return new ActiveProcess(model, process); |
396 | } |
397 | |
398 | @Override |
399 | public IActiveProcess createNewInstance(ISchedulableProcess process) { |
400 | // TODO Auto-generated method stub |
401 | return null; |
402 | } |
403 | |
404 | } |