EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][desmoj.core.simulator]

COVERAGE SUMMARY FOR SOURCE FILE [SimProcess.java]

nameclass, %method, %block, %line, %
SimProcess.java0%   (0/1)0%   (0/42)0%   (0/2185)0%   (0/606)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SimProcess0%   (0/1)0%   (0/42)0%   (0/2185)0%   (0/606)
SimProcess (Model, String, boolean): void 0%   (0/1)0%   (0/42)0%   (0/12)
activate (): void 0%   (0/1)0%   (0/72)0%   (0/18)
activate (SimTime): void 0%   (0/1)0%   (0/5)0%   (0/2)
activate (TimeInstant): void 0%   (0/1)0%   (0/151)0%   (0/36)
activate (TimeSpan): void 0%   (0/1)0%   (0/153)0%   (0/41)
activateAfter (Schedulable): void 0%   (0/1)0%   (0/102)0%   (0/29)
activateBefore (Schedulable): void 0%   (0/1)0%   (0/104)0%   (0/30)
canCooperate (): boolean 0%   (0/1)0%   (0/7)0%   (0/1)
clearInterruptCode (): void 0%   (0/1)0%   (0/4)0%   (0/2)
clone (): SimProcess 0%   (0/1)0%   (0/4)0%   (0/1)
cooperate (): void 0%   (0/1)0%   (0/140)0%   (0/44)
freeThread (): void 0%   (0/1)0%   (0/3)0%   (0/2)
getInterruptCode (): InterruptCode 0%   (0/1)0%   (0/3)0%   (0/1)
getMaster (): SimProcess 0%   (0/1)0%   (0/3)0%   (0/1)
getRealTimeConstraint (): long 0%   (0/1)0%   (0/3)0%   (0/1)
getSlaveWaitQueue (): ProcessQueue 0%   (0/1)0%   (0/3)0%   (0/1)
getSupervisor (): ComplexSimProcess 0%   (0/1)0%   (0/3)0%   (0/1)
getUsedResources (): Vector 0%   (0/1)0%   (0/7)0%   (0/2)
hold (SimTime): void 0%   (0/1)0%   (0/5)0%   (0/2)
hold (TimeInstant): void 0%   (0/1)0%   (0/139)0%   (0/41)
hold (TimeSpan): void 0%   (0/1)0%   (0/134)0%   (0/35)
interrupt (InterruptCode): void 0%   (0/1)0%   (0/179)0%   (0/53)
isBlocked (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
isComponent (): boolean 0%   (0/1)0%   (0/7)0%   (0/1)
isInterrupted (): boolean 0%   (0/1)0%   (0/7)0%   (0/1)
isReady (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
isTerminated (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
obtainResources (Resource []): void 0%   (0/1)0%   (0/66)0%   (0/16)
passivate (): void 0%   (0/1)0%   (0/66)0%   (0/16)
prepareTransport (): void 0%   (0/1)0%   (0/140)0%   (0/49)
reActivate (TimeSpan): void 0%   (0/1)0%   (0/128)0%   (0/36)
resetMaster (): void 0%   (0/1)0%   (0/12)0%   (0/4)
resume (): void 0%   (0/1)0%   (0/49)0%   (0/16)
returnAllResources (): void 0%   (0/1)0%   (0/142)0%   (0/34)
returnResources (Res, int): Resource [] 0%   (0/1)0%   (0/220)0%   (0/49)
setBlocked (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setRealTimeConstraint (long): void 0%   (0/1)0%   (0/4)0%   (0/2)
setRunning (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setSlaveWaitQueue (ProcessQueue): void 0%   (0/1)0%   (0/4)0%   (0/2)
setSupervisor (ComplexSimProcess): void 0%   (0/1)0%   (0/4)0%   (0/2)
setTerminated (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
start (): void 0%   (0/1)0%   (0/49)0%   (0/13)

1package desmoj.core.simulator;
2 
3import java.util.ArrayList;
4import java.util.Enumeration;
5import java.util.Vector; //TODO: oder dem Anwender �berlassen...?
6 
7import desmoj.core.advancedModellingFeatures.Res;
8import desmoj.core.report.ErrorMessage;
9 
10/**
11 * Sim-process represents entities with an own active lifecycle. Since
12 * Sim-processes are in fact special entities with extended capabilities (esp.
13 * the method <tt>lifeCycle()</tt>), they inherit from Entity and thus can also be used
14 * in conjunction with events. So they can be handled in both ways, event- and
15 * process-oriented. Clients are supposed to implement the lifeCycle() method to
16 * specify the individual behaviour of a special SimProcess subclass. Since
17 * implementing activity- and transaction-oriented synchronization mechanisms
18 * requires significant changes in this class, methods that have been
19 * implemented by Soenke Claassen have been marked.
20 * 
21 * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011
22 * @author Tim Lechler.
23 * @author Methods: canCooperate, clearInterruptCode, cooperate,
24 *         getInterruptCode, getMaster, getSlaveWaitQueue, IsInterrupted,
25 *         resetMaster and setSlaveWaitQueue by Soenke Claassen
26 * 
27 * Licensed under the Apache License, Version 2.0 (the "License");
28 * you may not use this file except in compliance with the License. You
29 * may obtain a copy of the License at
30 * http://www.apache.org/licenses/LICENSE-2.0
31 *
32 * Unless required by applicable law or agreed to in writing, software
33 * distributed under the License is distributed on an "AS IS"
34 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
35 * or implied. See the License for the specific language governing
36 * permissions and limitations under the License.
37 *
38 */
39public abstract class SimProcess extends Entity {
40 
41        /**
42         * The Thread needed for implementing coroutine behaviour.
43         */
44        private Thread _myThread;
45 
46        /**
47         * Displays the current blocked status of this SimProcess. A sim-process is
48         * blocked whenever it has to wait inside a queue or synchronization object.
49         */
50        private boolean _isBlocked;
51 
52        /**
53         * Displays the current status of this SimProcess. Is <code>true</code> if
54         * lifeCycle method has finished, <code>false</code> if it is still running
55         * or has not been started yet
56         */
57        private boolean _isTerminated;
58 
59        /**
60         * Displays if the thread in of control of this SimProcess is already the
61         * associated simthread. Is <code>true</code> if the simthread is active and
62         * is carrying on its lifeCycle. Is <code>false</code> if it has not started
63         * its lifeCycle yet or is terminated already.
64         */
65        private boolean _isRunning;
66 
67        /**
68         * If this SimProcess is cooperating as a slave with a master process, it
69         * keeps a reference to its master here. Master is set in the
70         * <code>cooperate()</code> -method, when the slave cooperates with his
71         * master and deleted every time the slave process is activated.
72         * 
73         * @author Soenke Claassen
74         */
75        private SimProcess _master;
76 
77        /**
78         * If this SimProcess is cooperating as a slave it has to wait in this
79         * waitQueue until a master is cooperating with it.
80         * 
81         * @author Soenke Claassen
82         */
83        private ProcessQueue<? extends SimProcess> _slaveWaitQueue;
84 
85        /**
86         * The <code>InterruptCode</code> with which this SimProcess is interrupted.
87         * 
88         * @author Soenke Claassen
89         */
90        private InterruptCode _irqCode;
91 
92        /**
93         * The <code>Vector</code> holding all the resources this SimProcess is
94         * using at the moment.
95         * 
96         * @author Soenke Claassen
97         */
98        private Vector<Resource> _usedResources;
99 
100        /**
101         * A reference to the container this SimProcess belongs to. Is
102         * <code>null</code> as long as this SimProcess is not contained in any
103         * <code>ComplexSimProcess</code>.
104         * 
105         * @author Soenke Claassen
106         */
107        private ComplexSimProcess _supervisor;
108        
109        /**
110         * The realTime deadline for this SimProcess in nanoseconds. In case of a
111         * real-time execution (i. e. the execution speed rate is set to a positive
112         * value) the Scheduler will produce a warning message if a deadline is
113         * missed.
114         */
115        private long _realTimeConstraint;
116 
117        /**
118         * Constructs a sim-process.
119         * 
120         * @param name
121         *            java.lang.String : The name of the sim-process
122         * @param owner
123         *            Model : The model this SimProcess is associated to
124         * @param showInTrace
125         *            boolean : Flag for showing SimProcess in trace-files. Set it
126         *            to <code>true</code> if SimProcess should show up in trace.
127         *            Set it to <code>false</code> if SimProcess should not be shown
128         *            in trace.
129         */
130        public SimProcess(Model owner, String name, boolean showInTrace) {
131 
132                super(owner, name, showInTrace);
133 
134                // init variables
135                _isBlocked = false; // not waiting in queue so far
136                _isRunning = false; // not running so far
137                _isTerminated = false; // not terminated either
138                _master = null; // this SimProcess has no master, so far
139                _slaveWaitQueue = null; // this SimProcess is not waiting in any queue
140                _irqCode = null; // this is not interrupted
141 
142                // set up simthread
143                _myThread = new SimThread(getModel().getExperiment().getThreadGroup(),
144                                this);
145 
146                // set up the Vector holding the used Resources
147                _usedResources = new Vector<Resource>();
148 
149                // this SimProcess is not contained in any ComplexSimProcess yet
150                _supervisor = null;
151 
152        }
153 
154        /**
155         * Used to synchronize the change of control between scheduler and
156         * Sim-processes. This method must only be called by the scheduler resp. the
157         * experiment's main thread in order to prevent multiple SimProcess' threads
158         * running in parallel which has to be avoided.
159         */
160        synchronized void resume() {
161 
162                // check that the SimThread has not finished yet
163                if (_isTerminated) {
164                        sendWarning(
165                                        "Can't activate SimProcess! Command ignored.",
166                                        "SimProcess : " + getName() + " Method: void resume()",
167                                        "The sim-process' lifeCycle method has already terminated.",
168                                        "Be sure to check the sim-process' status before resuming."
169                                                        + " Use method isTerminated() to check the current status");
170                        return;
171                }
172 
173                // wake up the SimThread waiting in a block for the sim-process' lock
174                // to be released
175                notify();
176 
177                // now go wait until the next notification by the SimThread
178                // of this SimProcess
179                try {
180                        wait();
181                } catch (InterruptedException irqEx) { // must be caught when using
182                        // wait
183                        // create eror message
184                        ErrorMessage errmsg = new ErrorMessage(getModel(),
185                                        "Simulation stopped!",
186                                        "InterruptedException thrown by Java VM : " + irqEx,
187                                        "Thread conflict assumed.", "Check Java VM.", presentTime());
188                        // throw it back to Experiment's start routine
189                        throw (new desmoj.core.exception.DESMOJException(errmsg));
190                }
191 
192        }
193 
194        /**
195         * Schedules the sim-process to be activated at the specified point in
196         * simulation time. The point of time is given as an offset to the current
197         * simulation time. This will allow a sim-process to continue executing its
198         * <code>lifeCycle</code> method. Thus in contrast to the entity, no Event
199         * is needed for scheduling here.
200         * 
201         * @param dt
202         *            TimeSpan : The offset to the current simulation time this
203         *            process is to be activated
204         */
205        public void activate(TimeSpan dt) {
206                if (isBlocked()) {
207                        sendWarning(
208                                        "Can't activate SimProcess! Command ignored.",
209                                        "SimProcess : " + getName()
210                                                        + " Method: activate(TimeSpan dt)",
211                                        "The sim-process to be activated is blocked inside "
212                                                        + "a higher level synchronization object.",
213                                        "Simprocesses waiting inside higher synchronization "
214                                                        + "constructs can not be activated by other SimProcesses or "
215                                                        + "events!");
216                        return; // is blocked in some synch construction
217                }
218 
219                if (dt == null) {
220                        sendWarning(
221                                        "Can't activate SimProcess! Command ignored.",
222                                        "SimProcess : " + getName() + " Method:  void activate"
223                                                        + "(TimeSpan dt)",
224                                        "The simulation time given as parameter is a null reference",
225                                        "Be sure to have a valid simulation time reference before "
226                                                        + "calling this method");
227                        return; // no proper parameter
228                }
229                // tell in the trace when the sim-process will be activated
230                if (currentlySendTraceNotes()) {
231                        if (this == currentSimProcess()) {
232                                if (dt == TimeSpan.ZERO) {
233                                        sendTraceNote("activates itself immediately (NOW)");
234                                } else {
235                                        if (TimeSpan.isEqual(dt, TimeSpan.ZERO)) {
236                                                sendTraceNote("activates itself now");
237                                        } else {
238                                                sendTraceNote("activates itself at "
239                                                                + TimeOperations.add(presentTime(), dt)
240                                                                                .toString());
241                                        }
242                                }
243                        } else { // this is not the currently running SimProcess
244 
245                                if (dt == TimeSpan.ZERO) {
246                                        sendTraceNote("activates " + getQuotedName()
247                                                        + " immediately (NOW)");
248                                } else {
249                                        if (TimeSpan.isEqual(dt, TimeSpan.ZERO)) {
250                                                sendTraceNote("activates " + getQuotedName() + " now");
251                                        } else {
252                                                sendTraceNote("activates "
253                                                                + getQuotedName()
254                                                                + " at "
255                                                                + TimeOperations.add(presentTime(), dt)
256                                                                                .toString());
257                                        }
258                                }
259                        }
260                }
261 
262                // schedule this SimProcess
263                getModel().getExperiment().getScheduler().schedule(this, null, dt);
264 
265                // debug output
266                if (currentlySendDebugNotes()) {
267                        sendDebugNote("is activated on EventList<br>"
268                                        + getModel().getExperiment().getScheduler().toString());
269                }
270 
271                resetMaster(); // if activate(TimeSpan dt) is called for this
272                // SimProcess,
273                // there is no Master anymore controlling it.
274 
275        }
276        
277    /**
278     * Schedules the sim-process to be activated at the present point in
279     * simulation time, yielding the same result as calling 
280     * <code>activate(new TimeSpan(0))</code>. The process will continue executing 
281     * its <code>lifeCycle</code> method. 
282     */
283    public void activate() {
284        if (isBlocked()) {
285            sendWarning(
286                    "Can't activate SimProcess! Command ignored.",
287                    "SimProcess : " + getName()
288                            + " Method: activate()",
289                    "The sim-process to be activated is blocked inside "
290                            + "a higher level synchronization object.",
291                    "Simprocesses waiting inside higher synchronization "
292                            + "constructs can not be activated by other SimProcesses or "
293                            + "events!");
294            return; // is blocked in some synch construction
295        }
296 
297        // tell in the trace when the sim-process will be activated
298        if (currentlySendTraceNotes()) {
299            if (this == currentSimProcess()) {
300                sendTraceNote("activates itself now");
301            } else { // this is not the currently running SimProcess
302                sendTraceNote("activates " + getQuotedName() + " now");
303            }
304        }
305 
306        // schedule this SimProcess
307        getModel().getExperiment().getScheduler().schedule(this, null, new TimeSpan(0));
308 
309        // debug output
310        if (currentlySendDebugNotes()) {
311            sendDebugNote("is activated on EventList<br>"
312                    + getModel().getExperiment().getScheduler().toString());
313        }
314 
315        resetMaster(); // if activate(TimeSpan dt) is called for this
316        // SimProcess,
317        // there is no Master anymore controlling it.
318    }
319 
320        /**
321         * Schedules the sim-process to be activated at the given point in simulation
322         * time. This will allow a sim-process to continue executing its
323         * <code>lifeCycle</code> method. 
324         * 
325         * @param when
326         *            TimeInstant : The point in simulation time this process is to
327         *            be activated.
328         */
329        public void activate(TimeInstant when) {
330                if (isBlocked()) {
331                        sendWarning(
332                                        "Can't activate SimProcess! Command ignored.",
333                                        "SimProcess : " + getName()
334                                                        + " Method: activate(TimeInstant when)",
335                                        "The sim-process to be activated is blocked inside "
336                                                        + "a higher level synchronization object.",
337                                        "Simprocesses waiting inside higher synchronization "
338                                                        + "constructs can not be activated by other SimProcesses or "
339                                                        + "events!");
340                        return; // is blocked in some synch construction
341                }
342 
343                if (when == null) {
344                        sendWarning(
345                                        "Can't activate SimProcess! Command ignored.",
346                                        "SimProcess : " + getName() + " Method:  void activate"
347                                                        + "(TimeInstant when)",
348                                        "The simulation time given as parameter is a null reference",
349                                        "Be sure to have a valid simulation time reference before "
350                                                        + "calling this method");
351                        return; // no proper parameter
352                }
353                // tell in the trace when the sim-process will be activated
354                if (currentlySendTraceNotes()) {
355                        if (this == currentSimProcess()) {
356                                if (when == presentTime()) {
357                                        sendTraceNote("activates itself immediately (NOW)");
358                                } else {
359                                        if (TimeInstant.isEqual(when, presentTime())) {
360                                                sendTraceNote("activates itself now");
361                                        } else {
362                                                sendTraceNote("activates itself at " + when.toString());
363 
364                                        }
365                                }
366                        } else { // this is not the currently running SimProcess
367 
368                                if (when == presentTime()) {
369                                        sendTraceNote("activates " + getQuotedName()
370                                                        + " immediately (NOW)");
371                                } else {
372                                        // stand auch oben: if (dt.getTimeValue() == 0.0) {
373                                        if (TimeInstant.isEqual(when, presentTime())) {
374                                                sendTraceNote("activates " + getQuotedName() + " now");
375                                        } else {
376                                                sendTraceNote("activates " + getQuotedName() + " at "
377                                                                + when.toString());
378                                        }
379                                }
380                        }
381                }
382 
383                // schedule this SimProcess
384                getModel().getExperiment().getScheduler().schedule(this, null, when);
385 
386                // debug output
387                if (currentlySendDebugNotes()) {
388                        sendDebugNote("is activated on EventList<br>"
389                                        + getModel().getExperiment().getScheduler().toString());
390                }
391 
392                resetMaster(); // if activate(TimeInstant when) is called for this
393                // SimProcess,
394                // there is no Master anymore controlling it.
395        }
396 
397        /**
398         * @deprecated Replaced by activate(TimeSpan dt). Schedules the sim-process
399         *             to be activated at the given time offset to the current
400         *             simulation time. This will allow a sim-process to continue
401         *             executing its <code>lifeCycle</code> method.
402         * 
403         * @param dt
404         *            SimTime : The offset to the current simulation time that this
405         *            SimProcess is due to be activated
406         */
407        @Deprecated
408        public void activate(SimTime dt) {
409                activate(SimTime.toTimeSpan(dt));
410 
411        }
412 
413        /**
414         * Schedules this SimProcess to be activated directly after the given
415         * Schedulable, which itself is already scheduled. Note that this
416         * Sim-process' point of simulation time will be set to be the same as the
417         * Schedulable's time. Thus this SimProcess will continue to execute its
418         * <code>lifeCycle</code> method directly after the given Schedulable but
419         * the simulation clock will not change. Please make sure that the
420         * Schedulable given as parameter is actually scheduled.
421         * 
422         * @param after
423         *            Schedulable : The Schedulable this SimProcess should be
424         *            scheduled after
425         */
426        public void activateAfter(Schedulable after) {
427 
428                if (after == null) {
429                        sendWarning(
430                                        "Can't activate this SimProcess after the given SimProcess "
431                                                        + "parameter! Command ignored.", "SimProcess : "
432                                                        + getName() + " Method: void "
433                                                        + "activateAfter(Schedulable after)",
434                                        "The Schedulable given as parameter is a null reference",
435                                        "Be sure to have a valid Schedulable reference before "
436                                                        + "calling this method");
437                        return; // no proper parameter
438                }
439 
440                if (isBlocked()) {
441                        sendWarning(
442                                        "Can't activate SimProcess! Command ignored.",
443                                        "SimProcess : " + getName()
444                                                        + " Method: void activateAfter(Schedulable after)",
445                                        "The sim-process to be activated is blocked inside "
446                                                        + "a higher level synchronization object.",
447                                        "Simprocesses waiting inside higher synchronization "
448                                                        + "constructs can not be activated by other SimProcesses or "
449                                                        + "events!");
450                        return; // is blocked in some synch construction
451                }
452 
453                if (currentlySendTraceNotes()) {
454                        if (this == currentSimProcess()) {
455                                sendTraceNote("activates itself after " + getQuotedName());
456                        } else {
457                                sendTraceNote("activates " + getQuotedName() + " after "
458                                                + after.getQuotedName());
459                        }
460                }
461 
462                // schedule this SimProcess
463                getModel().getExperiment().getScheduler().scheduleAfter(after, this,
464                                null);
465 
466                if (currentlySendDebugNotes()) {
467                        sendDebugNote("is activated after " + after.getQuotedName()
468                                        + " on EventList<br>"
469                                        + getModel().getExperiment().getScheduler().toString());
470                }
471 
472        }
473 
474        /**
475         * Schedules this SimProcess to be activated directly before the given
476         * Schedulable, which itself is already scheduled. Note that this
477         * Sim-process' point of simulation time will be set to be the same as the
478         * Schedulable's time. Thus this SimProcess will continue to execute its
479         * <code>lifeCycle</code> method directly before the given Schedulable but
480         * the simulation clock will not change. Please make sure that the
481         * Schedulable given as parameter is actually scheduled.
482         * 
483         * @param before
484         *            Schedulable : The Schedulable this SimProcess should be
485         *            scheduled before
486         */
487        public void activateBefore(Schedulable before) {
488 
489                if (before == null) {
490                        sendWarning("Can't activate this SimProcess before the given "
491                                        + "SimProcess parameter", "SimProcess : " + getName()
492                                        + " Method: void activateBefore" + "(Schedulable before)",
493                                        "The Schedulable given as parameter is a null reference",
494                                        "Be sure to have a valid Schedulable reference before "
495                                                        + "calling this method");
496                        return; // no proper parameter
497                }
498 
499                if (isBlocked()) {
500                        sendWarning(
501                                        "Can't activate SimProcess! Command ignored.",
502                                        "SimProcess : "
503                                                        + getName()
504                                                        + " Method: void activateBefore(Schedulable before)",
505                                        "The sim-process to be activated is blocked inside "
506                                                        + "a higher level synchronization object.",
507                                        "Simprocesses waiting inside higher synchronization "
508                                                        + "constructs can not be activated by other SimProcesses or "
509                                                        + "events!");
510                        return; // is blocked in some synch construction
511                }
512 
513                if (currentlySendTraceNotes()) {
514                        if (this == currentSimProcess()) {
515                                sendTraceNote("activates itself before "
516                                                + before.getQuotedName());
517                        } else {
518                                sendTraceNote("activates " + getQuotedName() + " before "
519                                                + before.getQuotedName());
520                        }
521                }
522 
523                // schedule this SimProcess
524                getModel().getExperiment().getScheduler().scheduleBefore(before, this,
525                                null);
526 
527                if (currentlySendDebugNotes()) {
528                        sendDebugNote("activateBefore " + before.getQuotedName()
529                                        + " on EventList<br>"
530                                        + getModel().getExperiment().getScheduler().toString());
531                }
532 
533                // hand control over to scheduler only if this is
534                // a running thread of SimProcess
535                // if ( isRunning ) passivate();
536 
537                resetMaster(); // if activateBefore() is called for this SimProcess,
538                // there is no Master anymore controlling it.
539 
540        }
541 
542        /**
543         * Returns <code>true</code> if this process can cooperate with another
544         * Sim-process. If this process is already cooperating with a master
545         * <code>false</code> is returned.
546         * 
547         * @return boolean : Is this process ready to cooperate with another
548         *         SimProcess?
549         * @author Soenke Claassen
550         */
551        public boolean canCooperate() {
552                return _master == null; // if the master is not set yet this SimProcess
553                // can cooperate with another SimProcess
554        }
555 
556        /**
557         * Resets the interrupt-status of this SimProcess to not interrupted. Should
558         * be called every time the sim-process has successfully dealt with the
559         * interrupt. The internal <code>InterruptCode</code> of this SimProcess
560         * will be reset to <code>null</code>.
561         * 
562         * @author Soenke Claassen
563         */
564        public void clearInterruptCode() {
565                this._irqCode = null;
566        }
567 
568        /**
569         * The current (master) process is calling this method (within
570         * <code>WaitQueue.cooperate()</code>) on the slave process to lead him
571         * through the joint cooperation. After the joint cooperation is finished
572         * the master is still active and after him the slave will be activated.
573         * 
574         * @author Soenke Claassen
575         */
576        public void cooperate() {
577                // this is the slave and current the master
578 
579                // check if this slave already has a master
580                if (this._master != null) {
581                        sendWarning(
582                                        "Slaves can not cooperate with more than one master at a "
583                                                        + "time! The attempted cooperation is ignored.",
584                                        "SimProcess : " + getName() + " Method: cooperate () ",
585                                        "This slave process is already cooperating with another "
586                                                        + "master: " + _master.getName(),
587                                        "Be sure to have finished one cooperation before starting "
588                                                        + "the next one.");
589                        return; // this process has a master already
590                }
591 
592                // check if this slave is not terminated yet
593                if (this._isTerminated) {
594                        sendWarning(
595                                        "Attempt to cooperate with a terminated slave process! "
596                                                        + "The attempted cooperation is ignored.",
597                                        "SimProcess : " + getName() + " Method: cooperate () ",
598                                        "This slave process is already terminated.",
599                                        "Make sure not to cooperate with terminated processes.");
600                        return; // this process is already terminated
601                }
602 
603                // check the master
604                SimProcess currentMaster = currentSimProcess(); // the current master
605                // process
606                if (currentMaster == null) // if currentMaster is only a null pointer
607                {
608                        sendWarning("A non existing process is trying to cooperate as a "
609                                        + "master! The attempted cooperation is ignored!",
610                                        "SimProcess : " + getName() + " Method: cooperate ()",
611                                        "The master process is only a null pointer.",
612                                        "Make sure that only real SimProcesses are cooperating with other "
613                                                        + "processes. ");
614                        return; // the currentMaster process is only a null pointer
615                }
616 
617                if (!isModelCompatible(currentMaster)) {
618                        sendWarning(
619                                        "The given master SimProcess object does not "
620                                                        + "belong to this model. The attempted cooperation is ignored!",
621                                        "SimProcess : " + getName() + " Method: cooperate ()",
622                                        "The master SimProcess is not modelcompatible.",
623                                        "Make sure that the processes all belong to this model.");
624                        return; // the currentMaster is not modelcompatible
625                }
626 
627                // the slave must be waiting in a WaitQueue
628                if (_slaveWaitQueue == null) {
629                        sendWarning(
630                                        "Attempt to cooperate with a slave process, that is not "
631                                                        + "waiting in a WaitQueue. The attempted cooperation is ignored!",
632                                        "SimProcess : " + getName() + " Method: cooperate ()",
633                                        "Slave processes must wait in a WaitQueue before they can get into "
634                                                        + "a cooperation.",
635                                        "Make sure that the slave processes are waiting in a WaitQueue.");
636                        return; // the slave is not waiting in a queue
637                }
638 
639                // now prepare for the real cooperation
640                this._master = currentMaster; // set the master for this slave process
641 
642                // leave a note in the trace
643                if (_master.currentlySendTraceNotes()) {
644                        // trace note for a cooperation without any special conditions
645                        sendTraceNote("cooperates " + this.getQuotedName() + " from "
646                                        + _slaveWaitQueue.getQuotedName());
647                }
648 
649                // get this slave out of his slaveWaitQueue
650                _slaveWaitQueue.remove(this);
651                // this slave process is not waiting in any slaveWaitingQueue anymore
652                _slaveWaitQueue = null;
653                // and therefore this slave process is not blocked anymore
654                this._isBlocked = false;
655 
656        }
657 
658        /**
659         * Method to release the waiting scheduler when the SimThread finishes.
660         */
661        synchronized void freeThread() {
662 
663                notify(); // free the scheduler
664 
665        }
666 
667        /**
668         * Returns the InterruptCode from this SimProcess. If this SimProcess is not
669         * interrupted, the InterruptCode is <code>null</code>.
670         * 
671         * @return irqCode : The InterruptCode of this SimProcess.
672         * @author Soenke Claassen
673         */
674        public InterruptCode getInterruptCode() {
675                return _irqCode;
676        }
677 
678        /**
679         * Returns the master when two SimProcesses are cooperating. If this method
680         * is called on a sim-process which is not a slave <code>null</code> is
681         * returned.
682         * 
683         * @return SimProcess : The master process during the cooperation or
684         *         <code>null</code> if this process is not a slave process.
685         * @author Soenke Claassen
686         */
687        public SimProcess getMaster() {
688                return _master;
689        }
690 
691 
692        /**Returns the realTime deadline for this SimProcess (in nanoseconds). In case of a
693         * real-time execution (i. e. the execution speed rate is set to a positive
694         * value) the Scheduler will produce a warning message if a deadline is
695         * missed.
696         * 
697         * @return the realTimeConstraint in nanoseconds
698         */
699        public long getRealTimeConstraint() {
700                return _realTimeConstraint;
701        }
702        
703        /**
704         * Returns the waiting-queue in which this SimProcess is waiting as a slave
705         * to cooperate with a master. If this method is called on a sim-process
706         * which is not a slave <code>null</code> is returned.
707         * 
708         * @return ProcessQueue : The waiting-queue in which this SimProcess is
709         *         waiting as a slave or <code>null</code> if this SimProcess is not
710         *         waiting as a slave for cooperation.
711         * @author Soenke Claassen
712         */
713        public ProcessQueue<? extends SimProcess> getSlaveWaitQueue() {
714                return _slaveWaitQueue;
715        }
716 
717        /**
718         * Returns the supervising <code>ComplexSimProcess</code> this SimProcess is
719         * contained in.
720         * 
721         * @return desmoj.ComplexSimProcess : The supervising
722         *         <code>ComplexSimProcess</code> this SimProcess is contained in.
723         *         Is <code>null</code> if this SimProcess is not contained in any
724         *         <code>ComplexSimProcess</code>.
725         * @author Soenke Claassen
726         */
727        public ComplexSimProcess getSupervisor() {
728 
729                return _supervisor;
730        }
731 
732        /**
733         * Returns a clone of the internal <code>Vector</code> containing all the
734         * <code>Resource</code> objects this SimProcess is using at the moment.
735         * 
736         * @return java.util.Vector : the internal <code>Vector</code> containing
737         *         all the <code>Resource</code> objects this SimProcess is using at
738         *         the moment.
739         * @author Soenke Claassen
740         */
741        protected Vector<Resource> getUsedResources() {
742 
743                // clone the internal Vector
744                Vector<Resource> usedRes = (Vector<Resource>) _usedResources.clone();
745 
746                // return the cloned Vector
747                return usedRes;
748        }
749 
750        /**
751         * Passivates a sim-process for the given span of time. The simthread of this
752         * Sim-process is put into a lock and the scheduler, resp. the experiment's
753         * main thread is released from its block and continues with the next
754         * EventNote to be processed.
755         * 
756         * @param dt
757         *            TimeSpan : The duration of the sim-process' passivation
758         */
759        public void hold(TimeSpan dt) {
760                if ((dt == null)) {
761                        sendWarning("Can't schedule SimProcess! Command ignored.",
762                                        "SimProcess : " + getName()
763                                                        + " Method: void hold(TimeSpan dt)",
764                                        "The TimeSpan given as parameter is a null reference.",
765                                        "Be sure to have a valid TimeSpan reference before calling this method.");
766                        return; // no proper parameter
767                }
768 
769                if (isBlocked()) {
770                        sendWarning(
771                                        "Can't activate SimProcess! Command ignored.",
772                                        "SimProcess : " + getName() + " Method: hold(TimeSpan dt)",
773                                        "The sim-process to be activated is blocked inside "
774                                                        + "a higher level synchronization object.",
775                                        "Simprocesses waiting inside higher synchronization "
776                                                        + "constructs can not be set to be activated by other "
777                                                        + "SimProcesses or events!");
778                        return; // is blocked in some synch construction
779                }
780 
781                if (isScheduled()) {
782                        sendWarning("Can't schedule SimProcess! Command ignored.",
783                                        "SimProcess : " + getName()
784                                                        + " Method: void hold(TimeSpan dt)",
785                                        "The sim-process to be scheduled is already scheduled.",
786                                        "Use method reActivate(TimeSpan dt) to shift the sim-process "
787                                                        + "to be scheduled at some other point of time.");
788                        return; // was already scheduled
789                }
790 
791                if (currentlySendTraceNotes()) {
792                        if (this == currentSimProcess()) {
793                                sendTraceNote("holds for " + dt.toString() + " until "
794                                                + TimeOperations.add(presentTime(), dt).toString());
795                        } else {
796                                sendTraceNote("holds " + getQuotedName() + "for "
797                                                + dt.toString() + " until "
798                                                + TimeOperations.add(presentTime(), dt).toString());
799                        }
800            skipTraceNote(); // skip passivate message 
801                }
802 
803                // schedule to be reactivated in dt
804                getModel().getExperiment().getScheduler().schedule(this, null, dt);
805 
806                if (currentlySendDebugNotes()) {
807                        sendDebugNote("holds on EventList<br>"
808                                        + getModel().getExperiment().getScheduler().toString());
809                }
810 
811                // hand control over to scheduler only if this is
812                // a running thread of SimProcess
813                passivate();
814        }
815 
816        /**
817         * Passivates a sim-process until the given point in simulation time. The
818         * simthread of this SimProcess is put into a lock and the scheduler, resp.
819         * the experiment's main thread is released from its block and continues
820         * with the next event-note to be processed.
821         * 
822         * @param until
823         *            TimeInstant : The point in simulation time when the
824         *            SimProcess' passivation ends.
825         * 
826         */
827        public void hold(TimeInstant until) {
828                if ((until == null)) {
829                        sendWarning("Can't schedule SimProcess! Command ignored.",
830                                        "SimProcess : " + getName()
831                                                        + " Method: void hold(TimeInstant until)",
832                                        "The TimeInstant given as parameter is a null reference.",
833                                        "Be sure to have a valid TimeInstant reference before calling this method.");
834                        return; // no proper parameter
835                }
836 
837                if (isBlocked()) {
838                        sendWarning(
839                                        "Can't activate SimProcess! Command ignored.",
840                                        "SimProcess : " + getName()
841                                                        + " Method: hold(TimeInstant until)",
842                                        "The sim-process to be activated is blocked inside "
843                                                        + "a higher level synchronization object.",
844                                        "Simprocesses waiting inside higher synchronization "
845                                                        + "constructs can not be set to be activated by other "
846                                                        + "SimProcesses or events!");
847                        return; // is blocked in some synch construction
848                }
849 
850                if (isScheduled()) {
851                        sendWarning("Can't schedule SimProcess! Command ignored.",
852                                        "SimProcess : " + getName()
853                                                        + " Method: void hold(TimeInstant until)",
854                                        "The sim-process to be scheduled is already scheduled.",
855                                        "Use method reActivate(TimeInstant when) to shift the sim-process "
856                                                        + "to be scheduled at some other point of time.");
857                        return; // was already scheduled
858                }
859                
860        if (TimeInstant.isBefore(until, presentTime())) {
861            sendWarning("Can't schedule SimProcess! Command ignored.",
862                    "SimProcess : " + getName()
863                            + " Method: void hold(TimeInstant until)",
864                    "The instant given is in the past.",
865                    "To hold a sim-process, use a TimeInstant no earlier than the present time. "
866                            + "The present time can be obtained using the "
867                            + "presentTime() method.");
868            return; // do not hold
869        }
870 
871                if (currentlySendTraceNotes()) {
872                        if (this == currentSimProcess()) {
873                                sendTraceNote("holds until " + until.toString());
874                        } else {
875                                sendTraceNote("holds " + getQuotedName() + "until "
876                                                + until.toString());
877                        }
878                    skipTraceNote(); // skip passivate message 
879                }
880 
881                // schedule to be reactivated at the point of simulation time "until"
882                getModel().getExperiment().getScheduler().schedule(this, null, until);
883 
884                if (currentlySendDebugNotes()) {
885                        sendDebugNote("holds on EventList<br>"
886                                        + getModel().getExperiment().getScheduler().toString());
887                }
888 
889                // hand control over to scheduler only if this is
890                // a running thread of SimProcess
891                passivate();
892        }
893 
894        /**
895         * @deprecated Replaced by hold(TimeSpan dt). Passivates a sim-process for
896         *             the time given. The simthread of this SimProcess is put into
897         *             a lock and the scheduler, resp. the experiment's main thread
898         *             is released from its block and continues with the next
899         *             EventNote to be processed.
900         * 
901         * @param dt
902         *            desmoj.SimTime : The duration of the sim-process' passivation
903         */
904        @Deprecated
905        public void hold(SimTime dt) {
906                hold(SimTime.toTimeSpan(dt));
907 
908        }
909 
910        /**
911         * Interrupts the sim-process setting the given InterruptCode as the reason
912         * for the interruption. Blocked, terminated or already interrupted
913         * Sim-processes can not be interrupted. In this case a warning message will
914         * be produced and the interrupt will be ignord. If the sim-process is
915         * cooperating as a slave the interrupt will be passed to the master.
916         * 
917         * @param interruptReason
918         *            desmoj.InterruptCode
919         */
920        public void interrupt(InterruptCode interruptReason) {
921 
922                if (interruptReason == null) {
923                        sendWarning(
924                                        "Can't interrupt SimProcess! Command ignored",
925                                        "SimProcess : " + getName() + " Method: void "
926                                                        + "interrupt(InterruptCode interruptReason)",
927                                        "The InterruptCode given as parameter is a null reference.",
928                                        "Be sure to have a valid InterruptCode reference before "
929                                                        + "calling this method.");
930                        return; // no proper parameter
931                }
932 
933                // if the sim-process is cooperating as a slave
934                if (_master != null) {
935                        if (currentlySendTraceNotes()) {
936                                sendTraceNote("interrupts '" + this.getName() + "' , who ...");
937                        }
938 
939                        // interrupt the master, too. (with the same reason/InterruptCode)
940                        _master.interrupt(interruptReason);
941                }
942 
943                if (isBlocked()) {
944                        sendWarning("Can't interrupt SimProcess! Command ignored",
945                                        "SimProcess : " + getName() + " Method: void "
946                                                        + "interrupt(InterruptCode interruptReason)",
947                                        "Blocked SimProcesses can not be interrupted.",
948                                        "You can check if a sim-process is blocked using method "
949                                                        + "isBlocked().");
950                        return; // is Blocked
951                }
952 
953                if (isTerminated()) {
954                        sendWarning("Can't interrupt SimProcess! Command ignored",
955                                        "SimProcess : " + getName() + " Method: void "
956                                                        + "interrupt(InterruptCode interruptReason)",
957                                        "Terminated SimProcesses can not be interrupted.",
958                                        "You can check if a sim-process is terminated using method "
959                                                        + "isTerminated().");
960                        return; // is Terminated
961                }
962 
963                if (_irqCode != null) {
964                        sendWarning(
965                                        "Can't interrupt SimProcess! Command ignored",
966                                        "SimProcess : " + getName() + " Method: void "
967                                                        + "interrupt(InterruptCode interruptReason)",
968                                        "SimProcesses has already a InterruptCode set :"
969                                                        + _irqCode.getName(),
970                                        "SimProcesses may only be interrupted if no other "
971                                                        + "InterruptCode is set on that SimProcess. You can check "
972                                                        + "on that using mehtod getInterruptCode, which must return "
973                                                        + "null if no other InterruptCode is set.");
974                        return; // is Interrupted
975                }
976 
977                if (this == currentSimProcess()) {
978                        sendWarning("Can't interrupt SimProcess! Command ignored",
979                                        "SimProcess : " + getName() + " Method: void "
980                                                        + "interrupt(InterruptCode interruptReason)",
981                                        "SimProcess is the currently active SimProcess.",
982                                        "Make sure not to interrupt the currently active "
983                                                        + "SimProcess.");
984                        return; // is currentSimProcess
985                }
986 
987                if (currentlySendTraceNotes()) {
988                        sendTraceNote("interrupts '" + this.getName() + "', with reason "
989                                        + interruptReason.getName() + " ["
990                                        + interruptReason.getCodeNumber() + "]");
991                }
992 
993                _irqCode = interruptReason; // set the InterruptCode
994 
995                // if on EventList, remove first ...
996                if (isScheduled()) {
997                        skipTraceNote(2);
998                        cancel();
999                } else {
1000                        skipTraceNote();
1001                }
1002                // ... then activate after the one interrupting this SimProcess
1003                activateAfter(current());
1004        }
1005 
1006        /**
1007         * Returns the current block-status of the sim-process. If a sim-process is
1008         * blocked, it is waiting inside a queue or synchronization block for it's
1009         * release.
1010         * 
1011         * @return boolean : Is <code>true</code> if SimProcess is blocked,
1012         *         <code>false</code> otherwise
1013         */
1014        public boolean isBlocked() {
1015 
1016                return _isBlocked;
1017 
1018        }
1019 
1020        /**
1021         * Returns the current component status of this SimProcess. If a sim-process
1022         * is a component of a <code>ComplexSimProcess</code> it is blocked and
1023         * passivated. It exists only within the <code>ComplexSimProcess</code>;
1024         * it's own lifeCycle is stopped and will only be activated again when it is
1025         * removed from the <code>ComplexSimProcess</code>.
1026         * 
1027         * @return boolean :<code>true</code> if and only if this SimProcess is a
1028         *         component (part of) a <code>ComplexSimProcess</code>;
1029         *         <code>false</code> otherwise.
1030         * @author Soenke Claassen
1031         */
1032        public boolean isComponent() {
1033 
1034                return (_supervisor != null);
1035        }
1036 
1037        /**
1038         * Returns the current interrupt-status of this SimProcess. If a sim-process
1039         * is interrupted, it should deal with the interrupt and then call the
1040         * <code>clearInterruptCode()</code> -method.
1041         * 
1042         * @return boolean : Is <code>true</code> if this SimProcess is interrupted,
1043         *         <code>false</code> otherwise.
1044         * @author Soenke Claassen
1045         */
1046        public boolean isInterrupted() {
1047                return (_irqCode != null);
1048        }
1049 
1050        /**
1051         * Returns the current running status of the sim-process. If a sim-process is
1052         * not ready, it has already finished its <code>lifeCycle()</code> method
1053         * and can not further be used as a sim-process. A terminated SimProcess can
1054         * still be used like any other Entity which it is derived from.
1055         * 
1056         * @return boolean : Is <code>true</code> if the sim-process is terminated,
1057         *         <code>false</code> otherwise
1058         * @see Entity
1059         */
1060        boolean isReady() {
1061 
1062                return _isRunning;
1063 
1064        }
1065 
1066        /**
1067         * Returns the current status of the sim-process. If a sim-process is
1068         * terminated, it has already finished its <code>lifeCycle()</code> method
1069         * and can not further be used as a sim-process. A terminated SimProcess can
1070         * still be used like any other Entity which it is derived from.
1071         * 
1072         * @return boolean : Is <code>true</code> if the sim-process is terminated,
1073         *         <code>false</code> otherwise
1074         * @see Entity
1075         */
1076        public boolean isTerminated() {
1077 
1078                return _isTerminated;
1079 
1080        }
1081 
1082        /**
1083         * Override this method in a subclass of SimProcess to implement that
1084         * Sim-process' specific behaviour. This method starts after a sim-process has
1085         * been created and activated by the scheduler.
1086         */
1087        public abstract void lifeCycle();
1088 
1089        /**
1090         * Makes the sim-process obtain an array of resources and store them for
1091         * further usage.
1092         * 
1093         * @param obtainedResources
1094         *            Resource[] : The array of resources obtained.
1095         * 
1096         * @author Soenke Claassen
1097         */
1098        public void obtainResources(Resource[] obtainedResources) {
1099                if (obtainedResources.length <= 0) {
1100                        sendWarning("Attempt to obtain resources, but got none! Command "
1101                                        + "ignored!", "SimProcess : " + getName()
1102                                        + " Method:  void obtain"
1103                                        + "Resources(Resource[] obtainedResources)",
1104                                        "The array of obtained resources is empty.",
1105                                        "Make sure to obtain at least one resource. Check if the "
1106                                                        + "resource pool can provide any resources.");
1107                        return; // parameter contains nothing
1108                }
1109 
1110                // put all the obtained resources in the Vector of used resources
1111                for (int i = 0; i < obtainedResources.length; i++) {
1112                        _usedResources.addElement(obtainedResources[i]);
1113                }
1114 
1115                // for debugging purposes
1116                if (currentlySendDebugNotes()) {
1117                        // make a string of all resources used by this SimProcess
1118                        String t = "uses: ";
1119 
1120                        for (Enumeration<Resource> e = _usedResources.elements(); e.hasMoreElements();) {
1121                                t += "<br>" + (e.nextElement()).getName();
1122                        }
1123 
1124                        sendDebugNote(t);
1125                }
1126        }
1127 
1128        /**
1129         * Passivates the sim-process for an indefinite time. This method must be
1130         * called by the sim-process' own Thread only. The sim-process can only be
1131         * reactivated by another SimProcess or Entity.
1132         */
1133        public synchronized void passivate() {
1134 
1135                if (currentlySendTraceNotes()) {
1136                        if (this == currentSimProcess()) {
1137                                sendTraceNote("passivates");
1138                        } else {
1139                                sendTraceNote("passivates " + getQuotedName());
1140                        }
1141                }
1142 
1143                notify(); // frees the scheduler after wait()
1144 
1145                try {
1146                        wait();
1147                } catch (InterruptedException ioEx) {
1148                        // create eror message
1149                        ErrorMessage errmsg = new ErrorMessage(getModel(),
1150                                        "Simulation stopped!",
1151                                        "Exception thrown by Java VM" + ioEx,
1152                                        "Thread conflict assumed.", "Check Java VM.", presentTime());
1153                        // throw it back to Experiment's start routine
1154                        throw (new desmoj.core.exception.DESMOJException(errmsg));
1155                }
1156 
1157                // if simulation is not running, throw SimFinishedException to stop
1158                // thread
1159                if (getModel().getExperiment().isAborted()) {
1160                        throw (new desmoj.core.exception.SimFinishedException(getModel(),
1161                                        getName(), presentTime()));
1162                }
1163 
1164        }
1165 
1166        /**
1167         * The current (master) process is calling this method (within
1168         * <code>TransportJunction.cooperate()</code>) on the slave process to make
1169         * him prepare for the transportation. After the transport is finished the
1170         * master is still active and after him the slave will be activated.
1171         * 
1172         * @author Soenke Claassen
1173         */
1174        public void prepareTransport() {
1175                // this is the slave and current the master
1176 
1177                // check if this slave already has a master
1178                if (this._master != null) {
1179                        sendWarning(
1180                                        "Slaves can not be transported from more than one master at "
1181                                                        + "a time! The attempted transport is ignored.",
1182                                        "SimProcess : " + getName()
1183                                                        + " Method: prepareTransport () ",
1184                                        "This slave process is already transported by another "
1185                                                        + "master: " + _master.getName(),
1186                                        "Be sure to have finished one transportation before starting "
1187                                                        + "the next one.");
1188                        return; // this process has a master already
1189                }
1190 
1191                // check if this slave is not terminated yet
1192                if (this._isTerminated) {
1193                        sendWarning("Attempt to transport a terminated slave process! "
1194                                        + "The attempted transport is ignored.", "SimProcess : "
1195                                        + getName() + " Method: prepareTransport () ",
1196                                        "This slave process is already terminated.",
1197                                        "Make sure not to transport terminated processes.");
1198                        return; // this process is already terminated
1199                }
1200 
1201                // check the master
1202                SimProcess currentMaster = currentSimProcess(); // the current master
1203                // process
1204                if (currentMaster == null) // if currentMaster is only a null pointer
1205                {
1206                        sendWarning(
1207                                        "A non existing process is trying to transport other "
1208                                                        + "processes as a master! The attempted transport is ignored!",
1209                                        "SimProcess : " + getName()
1210                                                        + " Method: prepareTransport ()",
1211                                        "The master process is only a null pointer.",
1212                                        "Make sure that only real SimProcesses are transporting other "
1213                                                        + "processes. ");
1214                        return; // the currentMaster process is only a null pointer
1215                }
1216 
1217                if (!isModelCompatible(currentMaster)) {
1218                        sendWarning(
1219                                        "The given master SimProcess object does not "
1220                                                        + "belong to this model. The attempted transport is ignored!",
1221                                        "SimProcess : " + getName()
1222                                                        + " Method: prepareTransport ()",
1223                                        "The master SimProcess is not modelcompatible.",
1224                                        "Make sure that the processes all belong to this model.");
1225                        return; // the currentMaster is not modelcompatible
1226                }
1227 
1228                // the slave must be waiting in a WaitQueue
1229                if (_slaveWaitQueue == null) {
1230                        sendWarning(
1231                                        "Attempt to transport a slave process, that is not "
1232                                                        + "waiting in a TransportJunction. The attempted transport is ignored!",
1233                                        "SimProcess : " + getName()
1234                                                        + " Method: prepareTransport ()",
1235                                        "Slave processes must wait in a TransportJunction before they can be "
1236                                                        + "transported.",
1237                                        "Make sure that the slave processes are waiting in a "
1238                                                        + "TransportJunction.");
1239                        return; // the slave is not waiting in a queue
1240                }
1241 
1242                // now prepare for the real cooperation
1243                this._master = currentMaster; // set the master for this slave process
1244 
1245                // leave a note in the trace
1246                if (_master.currentlySendTraceNotes()) {
1247                        // trace note for a transport without any special conditions
1248                        sendTraceNote("transports " + this.getQuotedName() + " from "
1249                                        + _slaveWaitQueue.getQuotedName());
1250                }
1251 
1252                // get this slave out of his slaveWaitQueue
1253                _slaveWaitQueue.remove(this);
1254                // this slave process is not waiting in any slaveWaitingQueue anymore
1255                _slaveWaitQueue = null;
1256                // and therefore this slave process is not blocked anymore
1257                this._isBlocked = false;
1258 
1259        }
1260 
1261        /**
1262         * Re-schedules the sim-process to be activated at the given TimeSpan offset
1263         * to the current simulation time. The Simprocess has already been scheduled
1264         * but is now supposed to be reactivated at some other point of simulation
1265         * time.
1266         * 
1267         * @param dt
1268         *            TimeSpan : The offset to the current simulation time that this
1269         *            SimProcess is due to be re-activated
1270         */
1271        public void reActivate(TimeSpan dt) {
1272                if (isBlocked()) {
1273                        sendWarning(
1274                                        "Can't reactivate SimProcess! Command ignored.",
1275                                        "SimProcess : " + getName()
1276                                                        + " Method: reActivate(TimeSpan dt)",
1277                                        "The sim-process to be activated is blocked inside "
1278                                                        + "a higher level synchronization object.",
1279                                        "Simprocesses waiting inside higher synchronization "
1280                                                        + "constructs can not be activated by other SimProcesses or "
1281                                                        + "events!");
1282                        return; // is blocked in some synch construction
1283                }
1284 
1285                if (!isScheduled()) {
1286                        sendWarning("Can't reactivate SimProcess! Command ignored.",
1287                                        "SimProcess : " + getName()
1288                                                        + " Method: reActivate(TimeSpan dt)",
1289                                        "The sim-process to be reactivated is not scheduled.",
1290                                        "Use method activate(TimeSpan dt) to activate a sim-process"
1291                                                        + "that is not scheduled yet.");
1292                        return; // was already scheduled
1293                }
1294 
1295                if (dt == null) {
1296                        sendWarning(
1297                                        "Can't reactivate SimProcess! Command ignored.",
1298                                        "SimProcess : " + getName() + " Method:  void reActivate"
1299                                                        + "(TimeSpan dt)",
1300                                        "The simulation time given as parameter is a null reference",
1301                                        "Be sure to have a valid simulation time reference before "
1302                                                        + "calling this method");
1303                        return; // no proper parameter
1304                }
1305 
1306                if (currentlySendTraceNotes()) {
1307                        if (this == currentSimProcess()) {
1308                                if (dt == TimeSpan.ZERO)
1309                                        sendTraceNote("reactivates itself now");
1310                                else
1311                                        sendTraceNote("reactivates itself at "
1312                                                        + TimeOperations.add(presentTime(), dt));
1313                        } else {
1314                                if (dt == TimeSpan.ZERO)
1315                                        sendTraceNote("reactivates " + getQuotedName() + " now");
1316                                else
1317                                        sendTraceNote("reactivates " + getQuotedName() + " at "
1318                                                        + TimeOperations.add(presentTime(), dt));
1319                        }
1320                }
1321 
1322                getModel().getExperiment().getScheduler().reSchedule(this, dt);
1323 
1324                resetMaster(); // if reActivate(TimeSpan dt) is called for this
1325                // SimProcess,
1326                // there is no Master anymore controlling it.
1327        }
1328 
1329        /**
1330         * Gets the InterruptCode from the master and resets the master to
1331         * <code>null</code>.
1332         * 
1333         * @author Soenke Claassen
1334         */
1335        public void resetMaster() {
1336                if (this._master != null) {
1337                        _irqCode = _master.getInterruptCode();
1338                }
1339 
1340                this._master = null;
1341        }
1342 
1343        /**
1344         * Makes the sim-process return all resources it holds at the moment to all
1345         * the different Res pools it is holding resources from. This is useful in
1346         * situations the Simprocess is about to terminate.
1347         * 
1348         * @author Soenke Claassen
1349         */
1350        public void returnAllResources() {
1351                // check if something can be returned
1352                if (_usedResources.isEmpty()) {
1353                        sendWarning(
1354                                        "Attempt to return all resources, but the "
1355                                                        + "SimProcess does not hold any resources! Command ignored!",
1356                                        "SimProcess : " + getName()
1357                                                        + " Method: returnAllResources()",
1358                                        "If the sim-process does not hold any resources it is "
1359                                                        + "impossible to return any.",
1360                                        "Make sure that the sim-process holds resources that "
1361                                                        + "should be returned!");
1362                        return; // return nothing, go to where you came from
1363                }
1364 
1365                // repeat while vector of usedResources is not empty
1366                while (!_usedResources.isEmpty()) {
1367                        // get the first resource and check the Res pool it belongs to
1368                        Res crntResPool = ((Resource) _usedResources.firstElement())
1369                                        .getResPool();
1370 
1371                        // counter how many resources of that res pool are used
1372                        int n = 1;
1373 
1374                        // search the whole vector of usedResources for resources of the
1375                        // current
1376                        // Res pool
1377                        for (int i = 1; i < _usedResources.size(); i++) {
1378                                // is the resource of the desired Res pool?
1379                                if (((Resource) _usedResources.elementAt(i)).getResPool() == crntResPool) {
1380                                        n++; // increase the counter
1381                                }
1382                        } // end for-loop
1383 
1384                        // make the array to store the resources which will be returned
1385                        Resource[] returningRes = new Resource[n];
1386 
1387                        // counter for the index of the array
1388                        int k = 0;
1389 
1390                        // collect all the resources from the Vector of usedResources
1391                        for (int j = 0; j < _usedResources.size(); j++) {
1392                                // is the resource of the desired Res pool?
1393                                if ((_usedResources.elementAt(j)).getResPool() == crntResPool) {
1394                                        // put res in array
1395                                        returningRes[k] = _usedResources.elementAt(j);
1396                                        k++; // increase counter of array
1397                                }
1398                                if (k == n) // array is full
1399                                        break; // stop the for-loop
1400                        }
1401 
1402                        // return the array of resources to the Res pool they belong to
1403                        crntResPool.takeBack(returningRes);
1404 
1405                        // remove the returned resources from the vector of usedResources
1406                        for (int m = 0; m < n; m++) // go through the array of
1407                        // returningResources
1408                        {
1409                                // remove each resource that is in the array of
1410                                // returningResources
1411                                _usedResources.removeElement(returningRes[m]);
1412                        }
1413 
1414                } // end while
1415 
1416                // for debugging purposes
1417                if (currentlySendDebugNotes()) {
1418                        // make a string including all elements of the vector usedResources
1419                        String s = "All resources returned! Contents of vector usedResources: ";
1420 
1421                        if (_usedResources.isEmpty()) // anything left ?
1422                        {
1423                                s += "<br>none";
1424                        }
1425 
1426                        for (Enumeration<Resource> e = _usedResources.elements(); e.hasMoreElements();) {
1427                                s += e.nextElement();
1428                        }
1429 
1430                        // send a debugNote representing the state of the vector
1431                        // usedResources
1432                        sendDebugNote(s);
1433                }
1434 
1435        } // end method returnAllResources
1436 
1437        /**
1438         * Makes the sim-process return a certain number of resources of the given
1439         * resource pool.
1440         * 
1441         * @param resPool
1442         *            Res : The resource pool which resources will be returned.
1443         * @param n
1444         *            int : The number of resources which will be returned.
1445         * @return Resource[] : the array containing the resources which will be
1446         *         returned.
1447         * @author Soenke Claassen
1448         */
1449        public Resource[] returnResources(Res resPool, int n) {
1450                // check if nothing should be returned
1451                if (n <= 0) {
1452                        sendWarning(
1453                                        "Attempt to return no or a negative number of resources! "
1454                                                        + " Command ignored!", "SimProcess : " + getName()
1455                                                        + " Method:  Resource[] "
1456                                                        + "returnResources(Res resPool, int n)",
1457                                        "It makes no sense to return nothing or a negative number "
1458                                                        + "of resources.",
1459                                        "Make sure to return at least one resource. Only resources "
1460                                                        + "which have been obtained once can be returned!");
1461                        return null; // return nothing, go to where you came from
1462                }
1463 
1464                // check if nothing can be returned
1465                if (_usedResources.isEmpty()) {
1466                        sendWarning(
1467                                        "Attempt to return a number of resources, but the "
1468                                                        + "SimProcess does not hold any resources! Command ignored!",
1469                                        "SimProcess : " + getName() + " Method:  Resource[] "
1470                                                        + "returnResources(Res resPool, int n)",
1471                                        "If the sim-process does not hold any resources it is "
1472                                                        + "impossible to return any.",
1473                                        "Make sure that the sim-process holds the resources that "
1474                                                        + "should be returned!");
1475                        return null; // return nothing, go to where you came from
1476                }
1477 
1478                // make the array to store the resources which will be returned
1479                Resource[] returningRes = new Resource[n];
1480 
1481                // counter for the index of the array
1482                int j = 0;
1483 
1484                // collect all the resources from the Vector of usedResources
1485                for (int i = 0; i < _usedResources.size(); i++) {
1486                        // is the resource of the desired kind?
1487                        if ((_usedResources.elementAt(i)).getResPool() == resPool) {
1488                                // put res in array
1489                                returningRes[j] = _usedResources.elementAt(i);
1490                                j++; // increase counter of array
1491                        }
1492                        if (j == n) // array is full
1493                                break; // stop the for-loop
1494                }
1495 
1496                // for debugging: make a string of all returning resources
1497                String s = "<b>returns</b> to Res '" + resPool.getName() + "' : ";
1498 
1499                // remove the returning resources from the vector of usedResources
1500                for (int m = 0; m < j; m++) // go through the array of
1501                // returningResources
1502                {
1503                        // remove each resource that is in the array of returningResources
1504                        _usedResources.removeElement(returningRes[m]);
1505 
1506                        // add them to string of returning resources
1507                        s += "<br>" + returningRes[m].getName();
1508                }
1509 
1510                if (j < n) // array is not full
1511                {
1512                        sendWarning("Attempt to return " + n
1513                                        + " resources to the Res pool. "
1514                                        + "But the sim-process holds only" + j
1515                                        + "resources of that " + "kind. The " + j
1516                                        + "resources will be returned.", "SimProcess : "
1517                                        + getName() + " Method:  Resource[] "
1518                                        + "returnResources(Res resPool, int n)",
1519                                        "The sim-process can not return " + n + " resources, "
1520                                                        + "because it holds only" + j + "resources.",
1521                                        "Make sure that the sim-process holds at least as many "
1522                                                        + "resources as it should return.");
1523                }
1524 
1525                // for debugging purposes
1526                if (currentlySendDebugNotes()) {
1527                        sendDebugNote(s);
1528 
1529                        // make a string of all resources still held by this SimProcess
1530                        String t = "still holds: ";
1531 
1532                        if (_usedResources.isEmpty()) // anything left ?
1533                        {
1534                                t += "<br>none";
1535                        }
1536 
1537                        for (Enumeration<Resource> e = _usedResources.elements(); e.hasMoreElements();) {
1538                                t += "<br>" + (e.nextElement()).getName();
1539                        }
1540 
1541                        sendDebugNote(t);
1542                }
1543 
1544                return returningRes; // return the array of resources
1545        }
1546 
1547        /**
1548         * Sets the sim-process' blocked status to the boolean value given. This is
1549         * necessary for some operations in conjunction with some synchronization
1550         * classes.
1551         * 
1552         * @param blockStatus
1553         *            boolean : The new value for the blocked status
1554         */
1555        public void setBlocked(boolean blockStatus) {
1556 
1557                _isBlocked = blockStatus;
1558 
1559        }
1560        
1561        /**Sets the realTime deadline for this SimProcess (in nanoseconds). In case of a
1562         * real-time execution (i. e. the execution speed rate is set to a positive
1563         * value) the Scheduler will produce a warning message if a deadline is
1564         * missed.
1565         * 
1566         * @param realTimeConstraint the realTimeConstraint in nanoseconds to set
1567         */
1568        public void setRealTimeConstraint(long realTimeConstraint) {
1569                this._realTimeConstraint = realTimeConstraint;
1570        }
1571        
1572        /**
1573         * Sets the sim-process' running status to the boolean value given. This is
1574         * necessary for some operations in conjunction with synchronization
1575         * classes.
1576         * 
1577         * @param runStatus
1578         *            boolean : The new value for the running status
1579         */
1580        void setRunning(boolean runStatus) {
1581 
1582                _isRunning = runStatus;
1583 
1584        }
1585 
1586        /**
1587         * Sets the sim-process' slaveWaitQueue variable to the ProcessQueue in which
1588         * this SimProcess is waiting as a slave to cooperate with a master.
1589         * 
1590         * @param slvWaitQueue
1591         *            ProcessQueue : The waiting-queue in which this SimProcess is
1592         *            waiting as a slave to cooperate with a master.
1593         * @author Soenke Claassen
1594         */
1595        public void setSlaveWaitQueue(ProcessQueue<? extends SimProcess> slvWaitQueue) {
1596                _slaveWaitQueue = slvWaitQueue;
1597        }
1598 
1599        /**
1600         * Sets the supervising <code>ComplexSimProcess</code> this SimProcess is
1601         * contained in. Setting it to <code>null</code> indicates that this
1602         * Sim-process is not contained in any <code>ComplexSimProcess</code>
1603         * (anymore).
1604         * 
1605         * @param complexProcess
1606         *            desmoj.ComplexSimProcess : The <code>ComplexSimProcess</code>
1607         *            which serves as a container for this SimProcess.
1608         * @author Soenke Claassen
1609         */
1610        protected void setSupervisor(ComplexSimProcess complexProcess) {
1611 
1612                this._supervisor = complexProcess;
1613        }
1614 
1615        /**
1616         * Sets the attribute indicating that this SimProcess' simthread has
1617         * finished to the given value. This method is used by class
1618         * <code>SimThread<code> only.
1619         * 
1620         * @param termValue
1621         *            boolean : The new value for the attribute indicating the
1622         *            SimThread's end
1623         */
1624        void setTerminated(boolean termValue) {
1625 
1626                _isTerminated = termValue; // Hasta la vista, baby!
1627 
1628        }
1629 
1630        /**
1631         * Starts the simthread associated with this SimProcess. This is method must
1632         * be called the first time a sim-process is supposed to start processing its
1633         * <code>lifeCycle()</code> method.
1634         */
1635        synchronized void start() {
1636 
1637                // setting this flag shows that the simthread is now ready to take over
1638                // control from the scheduler's thread
1639                _isRunning = true;
1640 
1641                // start thread and let it run into the block
1642                _myThread.start();
1643 
1644                // put thread in to a wait for synchronization
1645                try {
1646                        wait();
1647                } catch (InterruptedException irqEx) {
1648                        // create eror message
1649                        ErrorMessage errmsg = new ErrorMessage(getModel(),
1650                                        "Simulation stopped!", "Exception thrown by Java VM"
1651                                                        + irqEx, "Thread conflict assumed.",
1652                                        "Check Java VM.", presentTime());
1653                        // throw it back to Experiment's start routine
1654                        throw (new desmoj.core.exception.DESMOJException(errmsg));
1655                }
1656 
1657                // check if simulation has been stopped in between and throw SimFinished
1658                if (getModel().getExperiment().isAborted()) {
1659                        throw (new desmoj.core.exception.SimFinishedException(getModel(),
1660                                        getName(), presentTime()));
1661                }
1662        }
1663        
1664    /**
1665     * As there is no generally appliciable means of cloning a SimProcess
1666     * (which would require cloning the execution state as well), this 
1667     * method returns a </code>CloneNotSupportedException</code>.
1668     * 
1669     * @return SimProcess : A copy of this process.
1670     */  
1671    protected SimProcess clone() throws CloneNotSupportedException {
1672        throw new CloneNotSupportedException();
1673    }        
1674} // end class SimProcess

[all classes][desmoj.core.simulator]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov