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

COVERAGE SUMMARY FOR SOURCE FILE [ResourceDB.java]

nameclass, %method, %block, %line, %
ResourceDB.java0%   (0/3)0%   (0/28)0%   (0/1694)0%   (0/474)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ResourceDB0%   (0/1)0%   (0/20)0%   (0/1656)0%   (0/458)
ResourceDB (Experiment): void 0%   (0/1)0%   (0/23)0%   (0/7)
additionalStatus (): boolean 0%   (0/1)0%   (0/128)0%   (0/38)
checkForDeadlock (SimProcess): boolean 0%   (0/1)0%   (0/291)0%   (0/86)
checkProcess (SimProcess, String): boolean 0%   (0/1)0%   (0/18)0%   (0/7)
checkRes (Res, String): boolean 0%   (0/1)0%   (0/18)0%   (0/7)
debugIsOn (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
debugOff (): void 0%   (0/1)0%   (0/4)0%   (0/2)
debugOn (): void 0%   (0/1)0%   (0/4)0%   (0/2)
deleteResAllocation (Res, SimProcess, int): void 0%   (0/1)0%   (0/153)0%   (0/48)
deleteResRequest (SimProcess, Res, int): void 0%   (0/1)0%   (0/125)0%   (0/40)
findCycleProc (SimProcess): void 0%   (0/1)0%   (0/192)0%   (0/43)
findCycleRes (Res): void 0%   (0/1)0%   (0/209)0%   (0/44)
noteResourceAllocation (Res, SimProcess, int): void 0%   (0/1)0%   (0/120)0%   (0/36)
noteResourceRequest (SimProcess, Res, int): void 0%   (0/1)0%   (0/84)0%   (0/28)
reduce (SimProcess): void 0%   (0/1)0%   (0/33)0%   (0/8)
sendDebugNote (String): void 0%   (0/1)0%   (0/15)0%   (0/3)
sendMessage (Message): void 0%   (0/1)0%   (0/22)0%   (0/11)
sendTraceNote (String): void 0%   (0/1)0%   (0/22)0%   (0/4)
sendWarning (String, String, String, String): void 0%   (0/1)0%   (0/17)0%   (0/3)
toHtmlString (): String 0%   (0/1)0%   (0/175)0%   (0/40)
     
class ResourceDB$AssignedResources0%   (0/1)0%   (0/4)0%   (0/19)0%   (0/8)
ResourceDB$AssignedResources (SimProcess, int): void 0%   (0/1)0%   (0/9)0%   (0/4)
getProcess (): SimProcess 0%   (0/1)0%   (0/3)0%   (0/1)
getSeizedUnits (): int 0%   (0/1)0%   (0/3)0%   (0/1)
setSeizedUnits (int): void 0%   (0/1)0%   (0/4)0%   (0/2)
     
class ResourceDB$RequestedResources0%   (0/1)0%   (0/4)0%   (0/19)0%   (0/8)
ResourceDB$RequestedResources (Res, int): void 0%   (0/1)0%   (0/9)0%   (0/4)
getRequestedUnits (): int 0%   (0/1)0%   (0/3)0%   (0/1)
getResPool (): Res 0%   (0/1)0%   (0/3)0%   (0/1)
setRequestedUnits (int): void 0%   (0/1)0%   (0/4)0%   (0/2)

1package desmoj.core.simulator;
2 
3//34567890123456789012345678901234567890123456789012345678901234567890123456
4 
5import java.util.Enumeration;
6import java.util.Hashtable;
7import java.util.Vector;
8 
9import desmoj.core.advancedModellingFeatures.Res;
10import desmoj.core.report.DebugNote;
11import desmoj.core.report.ErrorMessage;
12import desmoj.core.report.Message;
13import desmoj.core.report.TraceNote;
14 
15/**
16 * In the resource database every Simprocess and the resources it requests or
17 * holds at the moment are stored. This information is needed i.e. for detecting
18 * deadlocks. An instance will be created, when an experiment is created.
19 * 
20 * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011
21 * @author Soenke Claassen
22 * 
23 * Licensed under the Apache License, Version 2.0 (the "License");
24 * you may not use this file except in compliance with the License. You
25 * may obtain a copy of the License at
26 * http://www.apache.org/licenses/LICENSE-2.0
27 *
28 * Unless required by applicable law or agreed to in writing, software
29 * distributed under the License is distributed on an "AS IS"
30 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
31 * or implied. See the License for the specific language governing
32 * permissions and limitations under the License.
33 *
34 */
35 
36public class ResourceDB {
37 
38        // ****** attributes ******
39 
40        /**
41         * The reference to the experiment this ResourceDB belongs to.
42         */
43        private Experiment _owner;
44 
45        /**
46         * Flag indicating if this resourceDB should be listed in the debug output
47         * file.
48         */
49        private boolean _debugMode;
50 
51        /**
52         * Stores for every resource pool (the <code>Res</code> is the key to the
53         * hashtable) a Vector holding all the pairs of a sim-process and the number
54         * of resources the sim-process holds at the moment (see the inner class
55         * <code>AssignedResources</code>).
56         */
57        private Hashtable<Res, Vector<AssignedResources>> _assignmentTable;
58 
59        /**
60         * Stores for every SimProcess the resource pool (<code>Res</code>) he
61         * is requesting resources from and the number of requested resources (see
62         * the inner class <code>RequestedResources</code>). The sim-process is
63         * building the key to the table entries which in turn are holding objects
64         * of the inner class <code>RequestedResources</code>.
65         */
66        private Hashtable<SimProcess, RequestedResources> _requestTable;
67 
68        /**
69         * Stores for every resource pool (the <code>Res</code> is the key to the
70         * hashtable) the effective available capacity of the resource as an
71         * <code>Integer</code> object. Which is the sum of the current available
72         * capactiy of resources in the Res pool and the returned units of that Res
73         * pool due to reduction (the units which might be returned in the future
74         * because they are not stuck in a deadlock).
75         */
76        private Hashtable<Res, Integer> _effCapacity;
77 
78        /**
79         * Stores all the visited resources when traversing the resource allocation
80         * graph. Maybe another implementation is performing better. You are invited
81         * to think about it.
82         */
83        private Vector<Res> _visitedRes;
84 
85        /**
86         * Stores all the visited SimProcesses when traversing the resource
87         * allocation graph. Maybe another implementation is performing better. You
88         * are invited to think about it.
89         */
90        private Vector<SimProcess> _visitedProcs;
91 
92        /**
93         * Stores all the sim-processes which are involved in a deadlock. Is filled
94         * when the method <code>checkForDeadlock()</code> is called.
95         */
96        private Vector<SimProcess> _deadlockedProcs;
97 
98        /**
99         * Stores all the resource pools (<code>Res</code>) which are involved
100         * in a deadlock. The Vector is filled when the method
101         * <code>checkForDeadlock()</code> is called.
102         */
103        private Vector<Res> _deadlockedRes;
104 
105        /**
106         * Stores all the visited resources when traversing the resource allocation
107         * graph is done with examining all it's children vertices. Maybe another
108         * implementation is performing better. You are invited to think about it.
109         */
110        private Vector<Res> _doneRes;
111 
112        /**
113         * Stores all the visited SimProcesses when traversing the resource
114         * allocation graph is done with examining all it's children vertices. Maybe
115         * another implementation is performing better. You are invited to think
116         * about it.
117         */
118        private Vector<SimProcess> _doneProcs;
119 
120        /**
121         * Stores the cycle in the resource allocation graph as a string
122         * representation. Is built up as the graph containing the cycle (deadlock)
123         * is drawn.
124         */
125        private StringBuffer _resAllocGraph;
126 
127        /**
128         * Stores all the elements not belonging to the the cycle in the resource
129         * allocation graph as a string representation. Is built up as the graph
130         * containing the cycle (deadlock) is drawn.
131         */
132        private StringBuffer _nonCycleGraph;
133 
134        /**
135         * Indicates the method where something has gone wrong. Is passed as a
136         * parameter to i.e. the method <code>checkProcess()</code>.
137         */
138        private String _where;
139 
140        /**
141         * Indicates whether a cycle in the resource allocation graph is found or
142         * not. Is set to <code>true</code> if a cycle (and therefore a possible
143         * deadlock) is found and <code>false</code> if no cycle is found.
144         */
145        private boolean _cycleFound;
146 
147        // ****** inner class ******
148 
149        /**
150         * AssignedResources is an inner class of <code>ResourceDB</code> to
151         * encapsulate the pairs of: SimProcess and the number of resources it
152         * holds. These pairs are stored in the vector
153         * <code>arrayOfAssignedResources</code>.
154         */
155        private static class AssignedResources extends java.lang.Object {
156 
157                // ****** attributes of inner class ******
158 
159                /**
160                 * The sim-process using the resources at the moment.
161                 */
162                private SimProcess process;
163 
164                /**
165                 * The number of resources seized by the sim-process.
166                 */
167                private int seizedUnits;
168 
169                // ****** methods of inner class ******
170 
171                /**
172                 * Constructor for a AssignedResources object.
173                 * 
174                 * @param sProc
175                 *            SimProcess : The sim-process holding the resources.
176                 * @param seizedRes
177                 *            int : The number of resources occupied by the sim-process.
178                 */
179                protected AssignedResources(SimProcess sProc, int seizedRes) {
180                        // init variables
181                        this.process = sProc;
182                        this.seizedUnits = seizedRes;
183                }
184 
185                /**
186                 * Returns the sim-process which holds a number of resources.
187                 * 
188                 * @return SimProcess : The sim-process which holds a number of
189                 *         resources.
190                 */
191                protected SimProcess getProcess() {
192                        return this.process;
193                }
194 
195                /**
196                 * Returns the number of resources seized by the sim-process.
197                 * 
198                 * @return int : The number of resources seized by the sim-process.
199                 */
200                protected int getSeizedUnits() {
201                        return this.seizedUnits;
202                }
203 
204                /**
205                 * Sets the number of resources seized by the sim-process to the given
206                 * value.
207                 * 
208                 * @param newQuantity
209                 *            int : The new number of resources held by the sim-process.
210                 */
211                protected void setSeizedUnits(int newQuantity) {
212                        this.seizedUnits = newQuantity;
213                }
214 
215        } // end inner class
216 
217        // ****** inner class ******
218 
219        /**
220         * RequestedResources is an inner class of <code>ResourceDB</code> to
221         * encapsulate the pairs of: a resource pool <code>Res</code> and the
222         * number of resources requested by a sim-process. These pairs are stored in
223         * the vector <code>arrayOfRequestedResources</code>.
224         */
225        private static class RequestedResources extends java.lang.Object {
226 
227                // ****** attributes of inner class ******
228 
229                /**
230                 * The Res from which the resources are requested.
231                 */
232                private Res resourcePool;
233 
234                /**
235                 * The number of resources requested from the resource pool Res.
236                 */
237                private int requestedUnits;
238 
239                // ****** methods of inner class ******
240 
241                /**
242                 * Constructor for a RequestedResources object.
243                 * 
244                 * @param resPool
245                 *            Res : The resource pool from which resources are
246                 *            requested.
247                 * @param requestedRes
248                 *            int : The number of resources requested from the resource
249                 *            pool <code>Res</code>.
250                 */
251                protected RequestedResources(Res resPool, int requestedRes) {
252                        // init variables
253                        this.resourcePool = resPool;
254                        this.requestedUnits = requestedRes;
255                }
256 
257                /**
258                 * Returns the resource pool <code>Res</code> from which a number of
259                 * resources are requested.
260                 * 
261                 * @return Res : The resource pool <code>Res</code> from which a
262                 *         number of resources are requested.
263                 */
264                protected Res getResPool() {
265                        return this.resourcePool;
266                }
267 
268                /**
269                 * Returns the number of resources requested from the resource pool
270                 * <code>Res</code>.
271                 * 
272                 * @return int : The number of resources requested from the resource
273                 *         pool <code>Res</code>.
274                 */
275                protected int getRequestedUnits() {
276                        return this.requestedUnits;
277                }
278 
279                /**
280                 * Sets the number of resources requested from a certain resource pool
281                 * <code>Res</code> to the given value.
282                 * 
283                 * @param newQuantity
284                 *            int : The new number of resources requested from the
285                 *            resource pool <code>Res</code>.
286                 */
287                protected void setRequestedUnits(int newQuantity) {
288                        this.requestedUnits = newQuantity;
289                }
290 
291        } // end inner class
292 
293        // ****** methods ******
294 
295        /**
296         * This private constructor is defined to prevent the compiler from
297         * generating a default public constructor.
298         */
299        /* Constructor is never used 
300        private ResourceDB() {
301 
302                // make the hashtables to store all the information
303                _assignmentTable = new Hashtable<Res, Vector<AssignedResources>>();
304                _requestTable = new Hashtable<SimProcess, RequestedResources>();
305                _effCapacity = new Hashtable<Res, Integer>();
306        }
307        */
308 
309        /**
310         * This constructor is called from the constructor of
311         * <code>Experiment</code> to make sure that for every experiment there is
312         * a new resource DB. The debug output for this <code>ResourceDB</code> is
313         * turned on by default. But you have to make sure, that the default output
314         * for the experiment is turned on, too.
315         * 
316         * @param owner
317         *            desmoj.Experiment : the experiment this resource database
318         *            belongs to.
319         */
320        protected ResourceDB(Experiment owner) {
321 
322                this._owner = owner;
323 
324                // make the hashtables to store all the information
325                _assignmentTable = new Hashtable<Res, Vector<AssignedResources>>();
326                _requestTable = new Hashtable<SimProcess, RequestedResources>();
327                _effCapacity = new Hashtable<Res, Integer>();
328 
329                // turn the debug output on, so the ResourceDB can produce debug output
330                debugOn();
331        }
332 
333        /**
334         * Checks the additional status of a deadlock, i.e. if the deadlock is a
335         * pending or a transient one. Returns <code>true</code> if it is a
336         * pending deadlock and <code>false</code> if it is a transient deadlock.
337         * 
338         * @return boolean :<code>true</code> if it is a pending deadlock and
339         *         <code>false</code> if it is a transient deadlock.
340         */
341        private synchronized boolean additionalStatus() {
342 
343                // we have to update the effCapacity for every Res
344                // get all the resource pools
345                for (Enumeration<Res> resPools = _assignmentTable.keys(); resPools
346                                .hasMoreElements();) {
347                        // get hold of the resouce pool
348                        Res rs = (Res) resPools.nextElement();
349 
350                        // put the number of available resource in the effCapacity hashtable
351                        _effCapacity.put(rs, Integer.valueOf(rs.getAvail()));
352                }
353 
354                // don't mess with the original, get yourself a copy of the visited
355                // processes
356        Vector<SimProcess> listOfProcs = (Vector<SimProcess>) _visitedProcs.clone();
357 
358                // do we have to search the whole list of SimProcesses from the
359                // beginning
360                // again, after some reduction has taken place?
361                boolean startAgain = false;
362 
363                do // do while some reduction was made
364                {
365                        // reset startAgain to false
366                        startAgain = false;
367 
368                        // for every SimProcess in the list
369                        for (int i = 0; i < listOfProcs.size(); i++) {
370                                SimProcess crntProc = (SimProcess) listOfProcs.elementAt(i);
371 
372                                // get the request resources for this SimProcess
373                                RequestedResources reqRes = (RequestedResources) _requestTable
374                                                .get(crntProc);
375 
376                                if (reqRes == null) {
377                                        reduce(crntProc);
378 
379                                        // delete the sim-process from the list
380                                        listOfProcs.removeElementAt(i);
381 
382                                        // start again
383                                        startAgain = true;
384                                        break; // break the for loop
385                                }
386 
387                                // get the Res pool
388                                Res crntRes = reqRes.getResPool();
389                                // and the requested units
390                                int vReq = reqRes.getRequestedUnits();
391 
392                                // get the virtual requested units of resources by the
393                                // SimProcess.
394                                // that is the maximum request size of all SimProcesses ahead of
395                                // it in
396                                // the queue (needed when the queue has a no-pass filling rule)
397 
398                                // check if the Res queue has a no-pass filling rule
399                                if (!crntRes.getPassBy()) {
400                                        // loop through all the processes in the queue of this Res
401                                        // pool
402                                        for (SimProcess proc = (SimProcess) crntRes.getQueue()
403                                                        .first(); proc != crntProc; proc = (SimProcess) crntRes
404                                                        .getQueue().succ(proc)) {
405                                                // how many resources is the proc requesting from
406                                                // crntRes?
407                                                int procReq = 0;
408                                                RequestedResources reqR = (RequestedResources) _requestTable
409                                                                .get(proc);
410 
411                                                // is the Res pool the same?
412                                                if (crntRes == reqR.getResPool()) {
413                                                        // get the number of requested units
414                                                        procReq = reqR.getRequestedUnits();
415 
416                                                        // if the number is greater
417                                                        if (vReq < procReq) {
418                                                                vReq = procReq; // change the virtual requested
419                                                                // units
420                                                        } // end inner if
421                                                } // end if
422 
423                                        } // end for loop through the queue of this Res pool
424                                } // end if the Res has a no-pass filling rule
425 
426                                // if the sim-process can be satisfied in the future
427                                // i.e. vReq < effCapacity of crntRes
428                                if (vReq <= ((Integer) _effCapacity.get(crntRes)).intValue()) {
429                                        reduce(crntProc);
430 
431                                        // delete the sim-process from the list
432                                        listOfProcs.removeElementAt(i);
433 
434                                        // start again
435                                        startAgain = true;
436                                } // end if
437 
438                        } // end outer for
439 
440                } while (startAgain);
441 
442                // for debugging purposes during SW development only
443                // System.out.println("The list of processes: " +
444                // listOfProcs.toString());
445 
446                // are there still elements in the list (the list is NOT empty)
447                if (!listOfProcs.isEmpty()) {
448                        return true; // pending deadlock
449                } else {
450                        return false; // transient deadlock
451                }
452        }
453 
454        /**
455         * This method is called when a sim-process can not get the resources desired
456         * to check if a possible deadlock situation has occured.
457         * 
458         * @param unsatProc
459         *            desmoj.SimProcess : The sim-process which can not get the
460         *            resources desired. The unsatisfied process.
461         * @return boolean : is <code>true</code> if a deadlock is found,
462         *         <code>false</code> otherwise.
463         */
464        public synchronized boolean checkForDeadlock(SimProcess unsatProc) {
465 
466                _where = "protected synchronized boolean checkForDeadlock(SimProcess "
467                                + "unsatProc)";
468 
469                // check for null reference
470                if (!checkProcess(unsatProc, _where))
471                        return false; // if the sim-process is not valid just return
472 
473                _visitedProcs = new Vector<SimProcess>();
474                _visitedRes = new Vector<Res>();
475                _doneProcs = new Vector<SimProcess>();
476                _doneRes = new Vector<Res>();
477                _deadlockedProcs = new Vector<SimProcess>();
478                _deadlockedRes = new Vector<Res>();
479 
480                _cycleFound = false;
481 
482                _resAllocGraph = new StringBuffer();
483                _nonCycleGraph = new StringBuffer();
484 
485                // look for a cycle starting with the unsatisfied process
486                findCycleProc(unsatProc);
487 
488                if (_cycleFound) {
489                        // check what kind of deadlock is discovered
490 
491                        // check if a total deadlock is discovered (all the visited
492                        // processes
493                        // are involved in the deadlock)
494                        if (_deadlockedProcs.size() == _visitedProcs.size()) {
495                                System.out
496                                                .println("A total deadlock was detected in your model "
497                                                                + "at simulation time "
498                                                                + _owner.getSimClock().getTime() + " .");
499                                System.out.println("Please check the error file!");
500                                System.out
501                                                .println("The debug file also might help to learn more about "
502                                                                + "this deadlock");
503 
504                                sendTraceNote("has detected a <b>total deadlock</b> situation. Please "
505                                                + "check the error file! Turn the debug mode on (if not "
506                                                + "done already) and check the debug file to learn more "
507                                                + "about this deadlock.");
508 
509                                sendDebugNote("A <b>total deadlock</b> situation is detected in your "
510                                                + "simulation! <br>Examine the information provided by the "
511                                                + "resource database above.");
512 
513                                // same information is provide by noteResourceRequest() already,
514                                // if debugIsOn
515                                if (!debugIsOn()) {
516                                        sendDebugNote(this.toHtmlString());
517                                }
518 
519                                sendWarning(
520                                                "A <b>total deadlock</b> is detected in the resource "
521                                                                + "allocation graph. <br>The simulation can not continue properly due "
522                                                                + "to this deadlock.",
523                                                "ResourceDB Method: " + _where,
524                                                "The sim-process '"
525                                                                + unsatProc.getName()
526                                                                + "' can not get the "
527                                                                + "resources desired, because they are occupied by another "
528                                                                + "SimProcess. <br>The following chain of resource allocations and "
529                                                                + "requests has lead to the deadlock: <br>"
530                                                                + _resAllocGraph,
531                                                "Check if a situation as described above can happen in the real "
532                                                                + "system, too. <br>Check if your model may not be implemented "
533                                                                + "correctly!");
534                        } else // no total deadlock
535                        {
536                                // check if a pending or transient deadlock is discovered
537                                if (additionalStatus()) {
538                                        // pending deadlock
539                                        System.out
540                                                        .println("A pending deadlock was detected in your model "
541                                                                        + "at simulation time "
542                                                                        + _owner.getSimClock().getTime() + " .");
543                                        System.out.println("Please check the error file!");
544                                        System.out
545                                                        .println("The debug file also might help to learn more about "
546                                                                        + "this deadlock");
547 
548                                        sendTraceNote("has detected a <b>pending deadlock</b> situation. Please "
549                                                        + "check the error file! <br>Turn the debug mode on (if not "
550                                                        + "done already) and check the debug file to learn more "
551                                                        + "about this deadlock.");
552 
553                                        sendDebugNote("A <b>pending deadlock</b> situation is detected in your "
554                                                        + "simulation! <br>Examine the information provided by the "
555                                                        + "resource database above.");
556 
557                                        // same information is provided by noteResourceRequest()
558                                        // already, if debugIsOn
559                                        if (!debugIsOn()) {
560                                                sendDebugNote(this.toHtmlString());
561                                        }
562 
563                                        sendWarning(
564                                                        "A <b>pending deadlock</b> is detected in the resource "
565                                                                        + "allocation graph. <br>Some of the processes in the "
566                                                                        + "simulation are stuck in the deadlock and can not "
567                                                                        + "continue properly.",
568                                                        "ResourceDB Method: " + _where,
569                                                        "The sim-process '"
570                                                                        + unsatProc.getName()
571                                                                        + "' can not get the "
572                                                                        + "resources desired, because they are occupied by another "
573                                                                        + "SimProcess. <br>The following chain of resource allocations and "
574                                                                        + "requests has lead to the deadlock: <br>"
575                                                                        + _resAllocGraph
576                                                                        + "<br>Furthermore the following resource allocations and requests "
577                                                                        + "are present: <br>" + _nonCycleGraph,
578                                                        "Check if a situation as described above can happen in the real "
579                                                                        + "system, too. <br>Check if your model may not be implemented "
580                                                                        + "correctly!");
581                                } else // transient deadlock
582                                {
583                                        System.out
584                                                        .println("A transient deadlock was detected in your model "
585                                                                        + "at simulation time "
586                                                                        + _owner.getSimClock().getTime() + " . ");
587                                        System.out
588                                                        .println("Although this situation may self-resolve, better "
589                                                                        + "check the error and debug files!");
590 
591                                        sendTraceNote("has detected a <b>transient deadlock</b> situation. <br>"
592                                                        + "Although this situation may self-resolve, better "
593                                                        + "check the error and debug files!");
594 
595                                        sendDebugNote("A <b>transient deadlock</b> situation is detected in your "
596                                                        + "simulation! <br>Better examine the information provided "
597                                                        + "by the resource database above.");
598 
599                                        // same information is provide by noteResourceRequest()
600                                        // already, if debugIsOn
601                                        if (!debugIsOn()) {
602                                                sendDebugNote(this.toHtmlString());
603                                        }
604 
605                                        sendWarning(
606                                                        "A <b>transient deadlock</b> is detected in the resource "
607                                                                        + "allocation graph. <br>This situation may self-resolve, "
608                                                                        + "but at the moment some processes are blocked.",
609                                                        "ResourceDB Method: " + _where,
610                                                        "The sim-process '"
611                                                                        + unsatProc.getName()
612                                                                        + "' can not get the "
613                                                                        + "resources desired, because they are occupied by another "
614                                                                        + "SimProcess at the moment. <br>The following chain of resource "
615                                                                        + "allocations and requests has lead to the deadlock: <br>"
616                                                                        + _resAllocGraph
617                                                                        + "<br>Furthermore the following resource allocations and "
618                                                                        + "requests are present: <br>"
619                                                                        + _nonCycleGraph,
620                                                        "Check if a situation as described above can happen in the real "
621                                                                        + "system, too. <br>Check if your model may not be implemented "
622                                                                        + "correctly!");
623                                }
624                        }
625 
626                        // set the deadlockDetected field for all the Res's involved to true
627                        for (Enumeration<Res> e = _deadlockedRes.elements(); e.hasMoreElements();) {
628                                ((Res) e.nextElement()).setDeadlockDetected(true); // that's it
629                        }
630 
631                        // for debugging purposes during SW development only
632                        /*
633                         * System.out.println("The following SimProcesses have been visited " +
634                         * "to determine the resource allocation graph: " +
635                         * visitedProcs.toString());
636                         * 
637                         * System.out.println("The following SimProcesses are involved in
638                         * the " + "deadlock: " + deadlockedProcs.toString());
639                         */
640 
641                } // end if cycle found
642 
643                return _cycleFound;
644 
645        }
646 
647        /**
648         * Checks whether the process using the ResourceDB is a valid process.
649         * 
650         * @return boolean : Returns whether the sim-process is valid or not.
651         * @param p
652         *            SimProcess : Is this SimProcess a valid one?
653         */
654        private boolean checkProcess(SimProcess p, String where) {
655                if (p == null) // if p is a null pointer instead of a process
656                {
657                        sendWarning("Attempt to insert a non existing process into a "
658                                        + "ResourceDB . The attempted action is ignored!",
659                                        "ResourceDB Method: " + where,
660                                        "The given process is only a null pointer.",
661                                        "Make sure that only real SimProcesses are using resources.");
662                        return false;
663                }
664 
665                // the resource database is a singleton and therefore has to store
666                // information for all resource pools -> no checking for model
667                // compatibility
668 
669                /*
670                 * if (!isModelCompatible( p ) ) // if p is not modelcompatible {
671                 * sendWarning ( "The process which should be inserted in the "+
672                 * "ResourceDB does not belong to this model. The attempted action " +
673                 * "is ignored!" , "ResourceDB: " + getName() + " Method: " + where ,
674                 * "The given process is not modelcompatible.", "Make sure that
675                 * processes are using only resources within" + " their model."); return
676                 * false; }
677                 */
678                return true;
679        }
680 
681        /**
682         * Checks whether the resource pool <code>Res</code> using the ResourceDB
683         * is a valid <code>Res</code>.
684         * 
685         * @return boolean : Returns whether the <code>Res</code> is valid or not.
686         * @param r
687         *            Res : Is this resource pool <code>Res</code> a valid one?
688         */
689        private boolean checkRes(Res r, String where) {
690                if (r == null) // if r is a null pointer instead of a Res
691                {
692                        sendWarning("Attempt to insert a non existing Res into a "
693                                        + "ResourceDB . The attempted action is ignored!",
694                                        "ResourceDB: Method: " + where,
695                                        "The given Res is only a null pointer.",
696                                        "Make sure that only real resource pools (Res) are using the "
697                                                        + "resource database.");
698                        return false;
699                }
700 
701                // the resource database is a singleton and therefore has to store
702                // information for all resource pools -> no checking for model
703                // compatibility
704                /*
705                 * if (!isModelCompatible( r ) ) // if r is not modelcompatible {
706                 * sendWarning ( "The Res which should be inserted in the "+ "ResourceDB
707                 * does not belong to this model. The attempted action " + "is ignored!" ,
708                 * "ResourceDB: " + getName() + " Method: " + where , "The given Res is
709                 * not modelcompatible.", "Make sure that resource pools (Res) are using
710                 * only a resource " + "database within their model."); return false; }
711                 */
712                return true;
713        }
714 
715        /**
716         * Shows if this resourceDB currently produces debug output.
717         * 
718         * @return boolean : true, if resourceDB shows in debug, false if not
719         */
720        public boolean debugIsOn() {
721 
722                return _debugMode; // that's all
723 
724        }
725 
726        /**
727         * Switches off debug output for this resourceDB.
728         */
729        public void debugOff() {
730 
731                _debugMode = false; // yep, that's it!
732 
733        }
734 
735        /**
736         * Switches on debug output for this resourceDB.
737         */
738        public void debugOn() {
739 
740                _debugMode = true; // yep, that's true!
741 
742        }
743 
744        /**
745         * Deletes an entry in the resource data base (should be called when a
746         * Sim-process is done with it's requested number of resources from a
747         * resource pool (<code>Res</code> )). The sim-process and the number of
748         * requested resources will be deleted in the corresponding Vector (of the
749         * Res pool) in the assignment hashtable. The Res pool is the key to this
750         * hashtable, specifying the Vector which holds all the (SimProcess/number
751         * of requested resources)-pairs.
752         * 
753         * @param resPool
754         *            desmoj.Res : The resource pool which has provided the
755         *            resources. (The key to the hashtable)
756         * @param doneProc
757         *            desmoj.SimProcess : The Simprocess giving back his allocated
758         *            resources. He should be done with the resources now.
759         * @param quantity
760         *            int : The number of resources the sim-process has used.
761         */
762        public void deleteResAllocation(Res resPool, SimProcess doneProc,
763                        int quantity) {
764                _where = "protected void deleteResAllocation(Res resPool, "
765                                + "SimProcess doneProc, int quantity)";
766 
767                // checks for null references and negative quantity
768                if (!checkProcess(doneProc, _where))
769                        return; // if the sim-process is not valid just return
770 
771                if (!checkRes(resPool, _where))
772                        return; // if the Res is not valid just return
773 
774                if (quantity <= 0) {
775                        sendWarning("Attempt to delete a negative or zero quantity from a "
776                                        + "ResourceDB . The attempted action is ignored!",
777                                        "ResourceDB Method: " + _where,
778                                        "The given quantity is zero or negative.",
779                                        "Make sure to only use positive quantities which are more than "
780                                                        + "nothing.");
781                        return; // if the quantity is negative or zero just return
782                }
783 
784                // check if there is an entry for the given Res pool in the assignment
785                // hashtable
786                if (!_assignmentTable.containsKey(resPool)) { // if no entry -> error
787                        sendWarning(
788                                        "Attempt to delete an entry in the resource database "
789                                                        + "for a resource pool (Res), but the Res pool does not exist in the "
790                                                        + "database. The attempted action is ignored!",
791                                        "ResourceDB Method: " + _where,
792                                        "The given resource pool has no entry in the database.",
793                                        "Make sure that the given resource pool has provided resources "
794                                                        + "before you try to delete it's entry in the database.");
795                        return; // the Res pool is not registered in the resourceDB
796                } else // get hold of the corresponding Vector
797                {
798                        Vector<AssignedResources> resPoolVec = (Vector<AssignedResources>) _assignmentTable.get(resPool);
799 
800                        // flag to indicate whether the given SimProcess is found in the
801                        // Vector
802                        boolean foundInVec = false;
803 
804                        // search the whole Vector to find the given SimProcess
805                        for (int i = 0; i < resPoolVec.size(); i++) {
806                                // get hold of the pair (SimProcess / number of resources)
807                                AssignedResources assigRes = (AssignedResources) resPoolVec
808                                                .elementAt(i);
809 
810                                // is the given SimProcess found?
811                                if (assigRes.getProcess() == doneProc) {
812                                        // note that the given SimProcess is found in the Vector
813                                        foundInVec = true;
814 
815                                        // delete the whole entry in the Vector
816                                        resPoolVec.remove(assigRes);
817 
818                                        // is the given quantity not exactly the same as found in
819                                        // the Vector?
820                                        if (!(assigRes.getSeizedUnits() == quantity)) {
821                                                // will be more resources deleted than the process has
822                                                // allocated?
823                                                if (quantity > assigRes.getSeizedUnits()) {
824                                                        sendWarning(
825                                                                        "Attempt to delete more resources than "
826                                                                                        + "the sim-process has allocated. Only all the formerly "
827                                                                                        + "allocated resources will be deleted in the database and "
828                                                                                        + "no more!",
829                                                                        "ResourceDB Method: " + _where,
830                                                                        "The entry in the database has not registered as many "
831                                                                                        + "allocated resources as there should be deleted now.",
832                                                                        "Make sure to only delete the same quantity of "
833                                                                                        + "resources as there were allocated once.");
834                                                } else // there will be less resources deleted than
835                                                // once
836                                                // allocated
837                                                {
838                                                        // reduce the quantity of allocated resources
839                                                        assigRes.setSeizedUnits(assigRes.getSeizedUnits()
840                                                                        - quantity);
841 
842                                                        // put the updated pair of (SimProcess/number of
843                                                        // resources)
844                                                        // back in the Vector
845                                                        resPoolVec.add(assigRes);
846                                                } // end inner else
847 
848                                        } // end outer if
849                                } // end outer outer if
850                        } // end for loop
851 
852                        // is the given SimProcess not found in the Vector?
853                        if (!foundInVec) {
854                                sendWarning(
855                                                "Can't find the sim-process for which there should be "
856                                                                + "deleted allocated resources. The attempted action can't be "
857                                                                + "performed!", "ResourceDB Method: " + _where,
858                                                "The entry in the database for the given SimProcess "
859                                                                + "can not be found.",
860                                                "Make sure to only delete resources which a sim-process "
861                                                                + "has allocated already.");
862                        } // end if
863 
864                        // is the Vector empty now?
865                        if (resPoolVec.isEmpty()) {
866                                // remove the Res pool Vector from the assignment hashtable
867                                _assignmentTable.remove(resPool);
868                        } else // there is still something in the Vector, so...
869                        {
870                                // put the updated Vector back in the assignment hashtable
871                                _assignmentTable.put(resPool, resPoolVec);
872                        }
873 
874                } // end outer else
875 
876                // update the effective available capacity of the Res pool
877                // effCapacity.put( resPool, new Integer( resPool.getAvail() ) );
878 
879                // for debugging purposes
880                if (debugIsOn())
881                        sendDebugNote(this.toHtmlString());
882        }
883 
884        /**
885         * Deletes an entry in the resource data base (should be called when a
886         * Sim-process receives it's requested number of resources from a resource
887         * pool (<code>Res</code> )). The resource pool and the number of
888         * requested resources will be deleted in the request hashtable. The
889         * Sim-process is the key to this hashtable, specifying the
890         * RequestedResources object which holds the (resource pool/number of
891         * requested resources)-pair.
892         * 
893         * @param gainProc
894         *            desmoj.SimProcess : The Simprocess giving up his request for
895         *            the resources. Hopefully he gets satisfied.
896         * @param resPool
897         *            desmoj.Res : The resource pool which provides the resources.
898         * @param quantity
899         *            int : The number of resources the sim-process gets.
900         */
901        public void deleteResRequest(SimProcess gainProc, Res resPool, int quantity) {
902                _where = "protected void deleteResRequest(SimProcess gainProc, "
903                                + "Res resPool,        int quantity)";
904 
905                // checks for null references and negative quantity
906                if (!checkProcess(gainProc, _where))
907                        return; // if the sim-process is not valid just return
908 
909                if (!checkRes(resPool, _where))
910                        return; // if the Res is not valid just return
911 
912                if (quantity <= 0) {
913                        sendWarning("Attempt to delete a negative or zero quantity from a "
914                                        + "ResourceDB . The attempted action is ignored!",
915                                        "ResourceDB Method: " + _where,
916                                        "The given quantity is zero or negative.",
917                                        "Make sure to only use positive quantities which are more than "
918                                                        + "nothing.");
919                        return; // if the quantity is negative or zero just return
920                }
921 
922                // check if there is an entry for the given SimProcess in the request
923                // hashtable
924                if (!_requestTable.containsKey(gainProc)) { // if no entry -> error
925                        sendWarning(
926                                        "Attempt to delete an entry in the resource database "
927                                                        + "for a sim-process, but the sim-process does not exist in the "
928                                                        + "database. The attempted action is ignored!",
929                                        "ResourceDB Method: " + _where,
930                                        "The given SimProcess has no entry in the database.",
931                                        "Make sure that the given SimProcess has requested resources "
932                                                        + "before you try to delete it's entry in the database.");
933                        return; // the sim-process is not registered in the resourceDB
934                }
935 
936                // get hold of the pair (resource pool / number of resources)
937                RequestedResources reqRes = (RequestedResources) _requestTable
938                                .get(gainProc);
939 
940                // is the given resource not the same as in the database?
941                if (reqRes.getResPool() != resPool) {
942                        sendWarning(
943                                        "Can't find the resource pool which requested resources "
944                                                        + "should be deleted. The attempted action can't be performed!",
945                                        "ResourceDB Method: " + _where,
946                                        "The entry in the database for the given resource pool "
947                                                        + "can not be found.",
948                                        "Make sure to only delete requested resources of a  "
949                                                        + "resource pool from which resources are requested already.");
950                }
951 
952                // will be more resources deleted than the process has requested?
953                if (quantity > reqRes.getRequestedUnits()) {
954                        sendWarning(
955                                        "Attempt to delete more requested resources than "
956                                                        + "the sim-process has requested. Only all the formerly "
957                                                        + "requested resources will be deleted in the database and "
958                                                        + "no more!",
959                                        "ResourceDB Method: " + _where,
960                                        "The entry in the database has not registered as many "
961                                                        + "requested resources as there should be deleted now.",
962                                        "Make sure to only delete the same quantity of requested "
963                                                        + "resources as there were requested once.");
964 
965                        // trick the database
966                        quantity = reqRes.getRequestedUnits();
967                }
968 
969                // is the given quantity exactly the same as found in the reqRes?
970                if ((reqRes.getRequestedUnits() == quantity)) {
971                        // remove the entry for the sim-process from the request hashtable
972                        _requestTable.remove(gainProc);
973                } else // there will be less resources deleted than once requested
974                {
975                        // reduce the quantity of requested resources
976                        reqRes.setRequestedUnits(reqRes.getRequestedUnits() - quantity);
977 
978                        // put the updated pair of (resource pool/number of resources)
979                        // back in the request hashtable
980                        _requestTable.put(gainProc, reqRes);
981                } // end else
982 
983                // for debugging purposes
984                if (debugIsOn())
985                        sendDebugNote(this.toHtmlString());
986        }
987 
988        /**
989         * Try to find a cycle in the resource allocation graph starting with the
990         * vertex specified in the parameter <code>SimProcess vertex</code>. If
991         * we can spot a cycle in the resource allocation graph it is likely that we
992         * have found a deadlock.
993         * 
994         * @param vertex
995         *            desmoj.SimProcess : The point to start the search of the
996         *            resource allocation graph to find a deadlock (cycle in the
997         *            graph).
998         */
999        private void findCycleProc(SimProcess vertex) {
1000                // mark the given SimProcess vertex as visited
1001                _visitedProcs.addElement(vertex);
1002 
1003                // mark the given SimProcess vertex as possible member of a cycle
1004                // as no cycle is found yet
1005                if (!_cycleFound) {
1006                        _deadlockedProcs.addElement(vertex);
1007                }
1008 
1009                // get the adjacent Res vertex to this SimProcess vertex
1010                RequestedResources reqRes = (RequestedResources) _requestTable
1011                                .get(vertex);
1012 
1013                // if the RequestedResources for this SimProcess contains an adjacent
1014                // Res
1015                if (reqRes != null) {
1016                        // get hold of the adjacent Res
1017                        Res resVertex = reqRes.getResPool();
1018 
1019                        // get the number of requested resources
1020                        int nReqRes = reqRes.getRequestedUnits();
1021 
1022                        // is the Res vertex not visited already
1023                        if (!_visitedRes.contains(resVertex)) {
1024                                // remember if there is a cycle found already or not
1025                                boolean oldCycleStatus = _cycleFound;
1026 
1027                                // get the length of resAllocGraph and nonCycleGraph so far
1028                                int len = _resAllocGraph.length();
1029                                int lenNoCycle = _nonCycleGraph.length();
1030 
1031                                // draw the nonCycle part of the resource request graph
1032                                _nonCycleGraph.append("SimProcess '" + vertex.getName()
1033                                                + "' is waiting for " + nReqRes
1034                                                + " unit(s) from the resource pool '"
1035                                                + resVertex.getName() + "' , but <br>");
1036 
1037                                // 'draw' the cycle of the resource request graph only as no
1038                                // cycle is found yet
1039                                if (!_cycleFound) {
1040                                        // draw the cycle
1041                                        _resAllocGraph.append("SimProcess '" + vertex.getName()
1042                                                        + "' is waiting for " + nReqRes
1043                                                        + " unit(s) from the resource pool '"
1044                                                        + resVertex.getName() + "' , <br>");
1045                                }
1046 
1047                                // get the length of resAllocGraph and nonCycleGraph now (after
1048                                // appending it)
1049                                int m = _resAllocGraph.length();
1050                                int k = _nonCycleGraph.length();
1051 
1052                                // look for a cycle in the subsequent graph
1053                                findCycleRes(resVertex);
1054 
1055                                // if no cycle is found in the subsequent graph delete the cycle
1056                                // 'drawing'
1057                                if (!_cycleFound) {
1058                                        // delete the drawing from the cycle graph
1059                                        _resAllocGraph.delete(len, m);
1060                                }
1061 
1062                                // if a new cycle is found in the newly investigated subsequent
1063                                // graph, that means
1064                                // the status has changed while investigating the subsequent
1065                                // path
1066                                if (oldCycleStatus != _cycleFound) {
1067                                        // delete the drawing from the nonCycle graph
1068                                        _nonCycleGraph.delete(lenNoCycle, k);
1069                                }
1070 
1071                        } else // the vertex is visited
1072                        {
1073                                if (!_doneRes.contains(resVertex) && // but is not done with his
1074                                                // sons AND
1075                                                !_cycleFound) // no cycle is found so far
1076                                {
1077                                        // deadlock cycle found
1078                                        _cycleFound = true;
1079 
1080                                        // "draw" the cycle part of the resource request graph
1081                                        _resAllocGraph.append("SimProcess '" + vertex.getName()
1082                                                        + "' is waiting for " + nReqRes
1083                                                        + " unit(s) from the resource pool '"
1084                                                        + resVertex.getName() + "' , <br>");
1085                                } // end inner if
1086                                else // is done with his sons (everything is invetigated from
1087                                // here on)
1088                                {
1089                                        // draw the nonCycle path of the resource allocation graph
1090                                        // how you came here
1091                                        _nonCycleGraph.append("SimProcess '" + vertex.getName()
1092                                                        + "' is waiting for " + nReqRes
1093                                                        + " unit(s) from the resource pool '"
1094                                                        + resVertex.getName() + "' . <br>");
1095                                } // end inner else
1096 
1097                        } // end outer else (the vertex is visited)
1098                } // end outer if
1099 
1100                // mark the given SimProcess as "done with the investigation
1101                // of all his sons"
1102                _doneProcs.addElement(vertex);
1103 
1104                // if no cycle is found yet delete the given SimProcess vertex as
1105                // possible member of a cycle
1106                if (!_cycleFound) {
1107                        _deadlockedProcs.removeElement(vertex);
1108                }
1109 
1110        }
1111 
1112        /**
1113         * Try to find a cycle in the resource allocation graph starting with the
1114         * vertex specified in the parameter <code>Res vertex</code>. If we can
1115         * spot a cycle in the resource allocation graph it is likely that we have
1116         * found a deadlock.
1117         * 
1118         * @param vertex
1119         *            desmoj.Res : The point to start the search of the resource
1120         *            allocation graph to find a deadlock (cycle in the graph).
1121         */
1122        private void findCycleRes(Res vertex) {
1123 
1124                // mark the given Res vertex as visited
1125                _visitedRes.addElement(vertex);
1126 
1127                // mark the given Res vertex as possible member of a cycle
1128                // as no cycle is found yet
1129                if (!_cycleFound) {
1130                        _deadlockedRes.addElement(vertex);
1131                }
1132 
1133                // get all the adjacent SimProcess vertices to this Res vertex
1134                Vector<AssignedResources> assigToProcVec = _assignmentTable.get(vertex);
1135 
1136                // if the Vector for this Res contains some adjacent SimProcesses
1137                if (assigToProcVec != null) {
1138                        // for every adjacent SimProcess
1139                        for (Enumeration<AssignedResources> enumAssigProc = assigToProcVec.elements(); enumAssigProc
1140                                        .hasMoreElements();) {
1141                                // start a new path and remember if there is a cycle found in
1142                                // the old path or not
1143                                boolean oldCycleStatus = _cycleFound;
1144 
1145                                // get hold of the adjacent AssignedResource
1146                                AssignedResources assigRes = enumAssigProc.nextElement();
1147 
1148                                // get hold of the adjacent SimProcess
1149                                SimProcess procVertex = assigRes.getProcess();
1150 
1151                                // get the number of assigned resources
1152                                int nAssigRes = assigRes.getSeizedUnits();
1153 
1154                                // is the vertex not visited already
1155                                if (!_visitedProcs.contains(procVertex)) {
1156                                        // get the length of resAllocGraph and nonCycleGraph so far
1157                                        int len = _resAllocGraph.length();
1158                                        int lenNoCycle = _nonCycleGraph.length();
1159 
1160                                        // draw the nonCycle part of the resource allocation graph
1161                                        _nonCycleGraph.append(nAssigRes + " unit(s) from '"
1162                                                        + vertex.getName() + "' is/are currently "
1163                                                        + "used by '" + procVertex.getName() + "' . <br>");
1164 
1165                                        // 'draw' the cycle part of the resource allocation graph
1166                                        // only as no cycle is found yet
1167                                        if (!_cycleFound) {
1168                                                // draw the cycle
1169                                                _resAllocGraph.append("but " + nAssigRes
1170                                                                + " unit(s) from '" + vertex.getName()
1171                                                                + "' is/are currently " + "used by '"
1172                                                                + procVertex.getName() + "' and <br>");
1173                                        }
1174 
1175                                        // get the length of resAllocGraph and nonCycleGraph now
1176                                        // (after appending it)
1177                                        int m = _resAllocGraph.length();
1178                                        int k = _nonCycleGraph.length();
1179 
1180                                        // look for a cycle in the subsequent graph
1181                                        findCycleProc(procVertex);
1182 
1183                                        // if no cycle is found in the subsequent graph delete the
1184                                        // 'drawing'
1185                                        if (!_cycleFound) {
1186                                                // delete the drawing from the cycle graph
1187                                                _resAllocGraph.delete(len, m);
1188                                        }
1189 
1190                                        // if a new cycle is found in the newly investigated
1191                                        // subsequent graph, that means
1192                                        // the status has changed while investigating the subsequent
1193                                        // path
1194                                        if (oldCycleStatus != _cycleFound) {
1195                                                // delete the drawing from the nonCycle graph
1196                                                _nonCycleGraph.delete(lenNoCycle, k);
1197                                        }
1198 
1199                                } else // the vertex is visited
1200                                {
1201                                        if (!_doneProcs.contains(procVertex) && // but is not done
1202                                                        // with his sons AND
1203                                                        !_cycleFound) // no cycle is found so far
1204                                        {
1205                                                // deadlock cycle found!
1206                                                _cycleFound = true;
1207 
1208                                                // "draw" the cycle part of the resource allocation
1209                                                // graph
1210                                                _resAllocGraph.append("but " + nAssigRes
1211                                                                + " unit(s) from '" + vertex.getName()
1212                                                                + "' is/are currently " + "used by '"
1213                                                                + procVertex.getName() + "'.<br>");
1214                                        } // end inner if
1215                                        else // is done with his sons (everything form here is
1216                                        // investigated)
1217                                        {
1218                                                // draw the nonCycle path of the resource allocation
1219                                                // graph how you came here
1220                                                _nonCycleGraph.append(nAssigRes + " unit(s) from '"
1221                                                                + vertex.getName() + "' is/are currently "
1222                                                                + "used by '" + procVertex.getName()
1223                                                                + "' . <br>");
1224                                        } // end inner else
1225 
1226                                } // end else
1227                        } // end for loop
1228                } // end outer if
1229 
1230                // mark the given Res as "done with the investigation
1231                // of all his sons"
1232                _doneRes.addElement(vertex);
1233 
1234                // if no cycle is found yet delete the given Res vertex as
1235                // possible member of a cycle
1236                if (!_cycleFound) {
1237                        _deadlockedRes.removeElement(vertex);
1238                }
1239 
1240        }
1241 
1242        /**
1243         * Makes an entry in the resource data base when a sim-process is allocating
1244         * a number of resources from a resource pool (<code>Res</code>). The
1245         * Sim-process and the number of allocated resources will be saved in the
1246         * assignment hashtable. The resource pool is the key to this hashtable.
1247         * 
1248         * @param resourcePool
1249         *            desmoj.Res : The resource pool which is providing the
1250         *            resources.
1251         * @param allocatingProcess
1252         *            desmoj.SimProcess : The Simprocess which is allocating the
1253         *            resources.
1254         * @param quantity
1255         *            int : The number of resources the sim-process is allocating.
1256         */
1257        public void noteResourceAllocation(Res resourcePool,
1258                        SimProcess allocatingProcess, int quantity) {
1259                _where = "protected void noteResourceAllocation(Res resourcePool,"
1260                                + "SimProcess allocatingProcess, int quantity)";
1261 
1262                // checks for null references and negative quantity
1263                if (!checkProcess(allocatingProcess, _where))
1264                        return; // if the sim-process is not valid just return
1265 
1266                if (!checkRes(resourcePool, _where))
1267                        return; // if the Res is not valid just return
1268 
1269                if (quantity <= 0) {
1270                        sendWarning("Attempt to insert a negative or zero quantity into a "
1271                                        + "ResourceDB . The attempted action is ignored!",
1272                                        "ResourceDB Method: " + _where,
1273                                        "The given quantity is zero or negative.",
1274                                        "Make sure to only use positive quantities which are more than "
1275                                                        + "nothing.");
1276                        return; // if the quantity is negative or zero just return
1277                }
1278 
1279                // make the AssignedResources object which will be inserted in the
1280                // assignment hashtable, see innerclass AssignedResources
1281                AssignedResources assigResources = new AssignedResources(
1282                                allocatingProcess, quantity);
1283 
1284                // is for the given resource pool existing an entry in the
1285                // assignment hashtable already?
1286                if (_assignmentTable.containsKey(resourcePool)) // there is an entry ...
1287                {
1288                        // flag to indicate whether there is already an entry in the Vector
1289                        // for this SimProcess
1290                        boolean simProcAlreadyAlloc = false;
1291 
1292                        // get the Vector containing all pairs of SimProcesses and number of
1293                        // assigned resources for the given resource pool
1294                        Vector<AssignedResources> arrayOfAssigResources = (Vector<AssignedResources>) _assignmentTable
1295                                        .get(resourcePool);
1296 
1297                        // search the Vector of the given resource pool to find if the
1298                        // SimProcess is already allocating resources from this resource
1299                        // pool
1300                        for (int i = 0; i < arrayOfAssigResources.size(); i++) {
1301                                // get hold of the pair (SimProcess / number of resources)
1302                                AssignedResources alreadyAssigRes = (AssignedResources) arrayOfAssigResources
1303                                                .elementAt(i);
1304 
1305                                // is the sim-process already allocating resources of this
1306                                // resource
1307                                // pool? Then add the newly assigned number of resources.
1308                                if (alreadyAssigRes.getProcess() == allocatingProcess) {
1309                                        // delete the old entry in the Vector
1310                                        arrayOfAssigResources.remove(alreadyAssigRes);
1311 
1312                                        // add the new number of assigned resources to the old
1313                                        // number
1314                                        alreadyAssigRes.setSeizedUnits(alreadyAssigRes
1315                                                        .getSeizedUnits()
1316                                                        + quantity);
1317 
1318                                        // put the updated pair of SimProcess and number of
1319                                        // allocated
1320                                        // resources back in the Vector
1321                                        arrayOfAssigResources.add(alreadyAssigRes);
1322 
1323                                        // note that the sim-process is allocating resources already
1324                                        // from this
1325                                        // resource pool
1326                                        simProcAlreadyAlloc = true;
1327 
1328                                } // end inner if
1329                                else
1330                                        ;
1331                        } // end for
1332 
1333                        // make a new entry in the existing Vector (of this SimProcess) if
1334                        // there is none already
1335                        if (!simProcAlreadyAlloc) {
1336                                arrayOfAssigResources.add(assigResources);
1337                        }
1338 
1339                        else
1340                                ; // nothing in this else branch
1341 
1342                        // put the updated Vector back in the Hashtable
1343                        _assignmentTable.put(resourcePool, arrayOfAssigResources);
1344 
1345                } // end outer if
1346 
1347                else { // there is no entry for this Res pool in the assignment
1348                        // hashtable
1349                        // make a new Vector as a new entry in the assignment hashtable
1350                        Vector<AssignedResources> resPoolVector = new Vector<AssignedResources>();
1351                        // insert the pair (SimProcess/number of assigned resources) in
1352                        // the Vector
1353                        resPoolVector.add(assigResources);
1354                        // store the Vector as a new entry of the Res pool in the
1355                        // assignment hashtable
1356                        _assignmentTable.put(resourcePool, resPoolVector);
1357                } // end outer else
1358 
1359                // update the effective available capacity of the Res pool
1360                // effCapacity.put( resourcePool, new Integer( resourcePool.getAvail() )
1361                // );
1362 
1363                // for debugging purposes
1364                if (debugIsOn())
1365                        sendDebugNote(this.toHtmlString());
1366        }
1367 
1368        /**
1369         * Makes an entry in the resource data base when a sim-process is requesting
1370         * a number of resources from a resource pool (<code>Res</code>). The
1371         * resource pool and the number of requested resources will be saved in the
1372         * request hashtable. The sim-process is the key to this hashtable.
1373         * 
1374         * @param requestingProcess
1375         *            desmoj.SimProcess : The Simprocess which is requesting the
1376         *            resources.
1377         * @param resourcePool
1378         *            desmoj.Res : The resource pool which should provide the
1379         *            resources.
1380         * @param quantity
1381         *            int : The number of resources the sim-process wants to get.
1382         */
1383        public void noteResourceRequest(SimProcess requestingProcess,
1384                        Res resourcePool, int quantity) {
1385                _where = "protected void noteResourceRequest(SimProcess requestingProcess, "
1386                                + "Res resourcePool, int quantity)";
1387 
1388                // checks for null references and negative quantity
1389                if (!checkProcess(requestingProcess, _where))
1390                        return; // if the sim-process is not valid just return
1391 
1392                if (!checkRes(resourcePool, _where))
1393                        return; // if the Res is not valid just return
1394 
1395                if (quantity <= 0) {
1396                        sendWarning("Attempt to insert a negative or zero quantity into a "
1397                                        + "ResourceDB . The attempted action is ignored!",
1398                                        "ResourceDB Method: " + _where,
1399                                        "The given quantity is zero or negative.",
1400                                        "Make sure to only use positive quantities which are more than "
1401                                                        + "nothing.");
1402                        return; // if the quantity is negative or zero just return
1403                }
1404 
1405                // make the RequestedResources object which will be inserted in the
1406                // request hashtable, see innerclass RequestedResources
1407                RequestedResources reqResources = new RequestedResources(resourcePool,
1408                                quantity);
1409                // is for the given SimProcess existing an entry in the
1410                // request hashtable already?
1411                if (_requestTable.containsKey(requestingProcess)) // there is an entry
1412                // ...
1413                {
1414                        sendWarning(
1415                                        "Attempt to make a sim-process request resources from "
1416                                                        + "more than one resource pool. The attempted action is ignored!",
1417                                        "ResourceDB Method: " + _where,
1418                                        "A sim-process can request resource from only one resource pool, "
1419                                                        + "because then he is blocked until he gets the desired resources.",
1420                                        "The sim-process '"
1421                                                        + requestingProcess
1422                                                        + "' should be blocked in "
1423                                                        + "a queue for some other resource request already. Don't manipulate "
1424                                                        + "these internal queues.");
1425                        return; // if the process is requesting other resources already
1426                }
1427 
1428                // insert the RequestedResources pair (resource pool/#requested
1429                // resources)
1430                // in the request hashtable
1431                _requestTable.put(requestingProcess, reqResources);
1432 
1433                // for debugging purposes
1434                if (debugIsOn())
1435                        sendDebugNote(this.toHtmlString());
1436        }
1437 
1438        /**
1439         * Calculates the new effective available capacity of all resources the
1440         * given SimProcess holds units from. The given SimProcess will return the
1441         * resources he holds in the future, so the returning resource units will be
1442         * added to the effective available capacity of the resources.
1443         * 
1444         * @param process
1445         *            desmoj.SimProcess : the sim-process which will return the
1446         *            resources it holds in the future. So the returning resource
1447         *            units can be added to the effective available capacity of the
1448         *            resources.
1449         */
1450        private void reduce(SimProcess process) {
1451 
1452                // get the Vector of all the resources this SimProcess holds at the
1453                // moment
1454                Vector<Resource> usedResVec = process.getUsedResources();
1455 
1456                // for every resource unit the sim-process holds
1457                for (Enumeration<Resource> e = usedResVec.elements(); e.hasMoreElements();) {
1458                        // get the resource
1459                        Resource resource = e.nextElement();
1460 
1461                        // get the Res pool the resource belongs to
1462                        Res resPool = resource.getResPool();
1463 
1464                        // increment the effective available capacity of the Res pool
1465                        int effCap = ((Integer) _effCapacity.get(resPool)).intValue();
1466                        effCap++;
1467 
1468                        // save the newly calculated effective capacity in the hashtable
1469                        _effCapacity.put(resPool, Integer.valueOf(effCap));
1470                } // end for
1471 
1472        }
1473 
1474        /**
1475         * Creates and sends a debugnote to the experiment's messagedistributor.
1476         * Debugnotes express the internal state of the ResourceDB to visualize the
1477         * changes of state to help find bugs. The information about the simulation
1478         * time is extracted from the experiment and must not be given as a
1479         * parameter.
1480         * 
1481         * @param description
1482         *            java.lang.String : The description of the ResourceDB's
1483         *            internal state to be passed with this debugnote
1484         */
1485        protected void sendDebugNote(String description) {
1486 
1487                sendMessage(new DebugNote(_owner.getModel(), _owner.getSimClock()
1488                                .getTime(), "resource database", description));
1489 
1490        }
1491 
1492        /**
1493         * Sends a message to the messagedistributor handled by the experiment. This
1494         * ResourceDB must already be connected to an experiment in order to have a
1495         * messagedistributor available to send this message to and an appropriate
1496         * messagereceiver must already be registered at the messagedistributor to
1497         * receive that type of message passed on to it. If no messaging subsystem
1498         * is available to this ResourceDB, then the mesage is printed to the
1499         * standard <code>out</code> printstream as configured in the local Java
1500         * runtime environment of the computer this simulation is running on. Note
1501         * that there are shorthands for sending the standard DESMO-J messages.
1502         * These methods create and send the appropriate Message on-the-fly:
1503         * <ul>
1504         * <li><code>sendTraceNote()</clode> to send a tracenote</li>
1505         * <li><code>sendDebugNote()</code> to send the data needed to debug models</li>
1506         * <li><code>sendWarning()</code> to send an errormessage that does not
1507         * stop the experiment</li>
1508         * </ul>
1509         * @param m Message : The message to be transmitted
1510         * @see ResourceDB#sendTraceNote
1511         * @see ResourceDB#sendDebugNote
1512         * @see ResourceDB#sendWarning
1513         */
1514        protected void sendMessage(Message m) {
1515 
1516                if (m == null) {
1517                        sendWarning("Can't send Message!",
1518                                        "ResourceDB Method: SendMessage(Message m)",
1519                                        "The Message given as parameter is a null reference.",
1520                                        "Be sure to have a valid Message reference.");
1521                        return; // no proper parameter
1522                }
1523 
1524                if (_owner != null) { // is ResourceDB connected to Experiment?
1525                        _owner.getMessageManager().receive(m);
1526                        return;
1527                }
1528 
1529                // if not connected to messaging system, write to standard out
1530                System.out.println(m);
1531 
1532        }
1533 
1534        /**
1535         * Creates and sends a tracenote to the experiment's messagedistributor. The
1536         * information about the simulation time, model and component producing this
1537         * tracenote is extracted from the experiment and must not be given as
1538         * parameters.
1539         * 
1540         * @param description
1541         *            java.lang.String : The description of the tracenote
1542         */
1543        protected void sendTraceNote(String description) {
1544 
1545                sendMessage(new TraceNote(_owner.getModel(), description, _owner
1546                                .getSimClock().getTime(), _owner.getScheduler()
1547                                .getCurrentEntity(), _owner.getScheduler().getCurrentEvent()));
1548 
1549        }
1550 
1551        /**
1552         * Creates and sends an error message to warn about a erroneous condition in
1553         * the DESMO-J framework to the experiment's messagedistributor. Be sure to
1554         * have a correct location, since the object and method that the error
1555         * becomes apparent is not necessary the location it was produced in. The
1556         * information about the simulation time is extracted from the Experiment
1557         * and must not be given as a parameter.
1558         * 
1559         * @param description
1560         *            java.lang.String : The description of the error that occured
1561         * @param location
1562         *            java.lang.String : The class and method the error occured in
1563         * @param reason
1564         *            java.lang.String : The reason most probably responsible for
1565         *            the error to occur
1566         * @param prevention
1567         *            java.lang.String : The measures a user should take to prevent
1568         *            this warning to be issued again
1569         */
1570        protected void sendWarning(String description, String location,
1571                        String reason, String prevention) {
1572 
1573                // compose the ErrorMessage and send it in one command
1574                sendMessage(new ErrorMessage(_owner.getModel(), description, location,
1575                                reason, prevention, _owner.getSimClock().getTime()));
1576 
1577        }
1578 
1579        /**
1580         * Returns a string representation of the resource database with some HTML
1581         * formatting tags. Lists first for every SimProcess all the resources he is
1582         * requesting and second for every resource pool (<code>Res</code>) all
1583         * the sim-processes that are using resources from that resource pool. This
1584         * information is useful for debugging purposes.
1585         * 
1586         * @return java.lang.String : The string representation of this resource
1587         *         database.
1588         */
1589        public String toHtmlString() {
1590 
1591                // make a StringBuffer to store all the information
1592                StringBuffer buffer = new StringBuffer(); // strings
1593 
1594                buffer.append("<u>List of all SimProcesses requesting resources:</u>");
1595 
1596                // list for every SimProcess all the resources he is requesting
1597                if (_requestTable.isEmpty()) { // no SimProcess is requesting any
1598                        // resources
1599                        buffer.append("<br>---   (empty)   ---<br>");
1600                } else { // there are some SimProcesses requesting some resources
1601 
1602                        // loop through all the sim-processes waiting on resources
1603                        for (Enumeration<SimProcess> waitingProcs = _requestTable.keys(); waitingProcs
1604                                        .hasMoreElements();) {
1605                                SimProcess process = (SimProcess) waitingProcs.nextElement();
1606                                buffer.append("<br>SimProcess '" + process.toString()
1607                                                + "' is waiting on: " + "<ul>"); // start indent list
1608 
1609                                RequestedResources reqRes = (RequestedResources) _requestTable
1610                                                .get(process);
1611 
1612                                if (reqRes == null) {
1613                                        buffer.append("nothing!");
1614                                } else {
1615                                        buffer.append(reqRes.getRequestedUnits() + " resource(s) "
1616                                                        + "from '" + reqRes.getResPool().toString()
1617                                                        + "'<br>");
1618                                }
1619 
1620                                buffer.append("</ul>"); // end indent list
1621 
1622                        } // end for loop through all SimProcesses
1623                } // end all the entries in the requestTable
1624 
1625                // list for every resource pool all the sim-processes holding his
1626                // resources
1627                buffer
1628                                .append("<u>List of all resource pools with resources used at the "
1629                                                + "moment:</u>");
1630 
1631                if (_assignmentTable.isEmpty()) {// no resources are allocated by any
1632                        // process
1633                        buffer.append("<br>---   (empty)   ---<br>");
1634                } else { // list the resources with their allocating processes
1635 
1636                        // loop through all the resource pools used at the moment
1637                        for (Enumeration<Res> usedRes = _assignmentTable.keys(); usedRes
1638                                        .hasMoreElements();) {
1639                                Res resPool = (Res) usedRes.nextElement();
1640                                buffer.append("<br>resource pool '" + resPool.toString()
1641                                                + "' is " + "providing: <ul>"); // start indent list
1642 
1643                                // get the Vector holding all the pairs of
1644                                // (SimProcess/allocated resources) for this resource pool
1645                                Vector<AssignedResources> allocVector = _assignmentTable.get(resPool);
1646 
1647                                if (allocVector == null || allocVector.isEmpty()) {
1648                                        buffer.append("nothing!");
1649                                } else {
1650                                        // loop through the Vector
1651                                        for (Enumeration<AssignedResources> processQtyPairs = allocVector.elements(); processQtyPairs
1652                                                        .hasMoreElements();) {
1653                                                AssignedResources assignedRes = processQtyPairs
1654                                                                .nextElement();
1655                                                buffer
1656                                                                .append(assignedRes.getSeizedUnits()
1657                                                                                + " resource(s) " + "to '"
1658                                                                                + assignedRes.getProcess().toString()
1659                                                                                + "'<br>");
1660                                        }
1661                                }
1662 
1663                                buffer.append("</ul>"); // end indent list
1664 
1665                        } // end for loop through all resource pools
1666 
1667                } // end outer else
1668 
1669                return buffer.toString();
1670        }
1671}

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