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

COVERAGE SUMMARY FOR SOURCE FILE [Res.java]

nameclass, %method, %block, %line, %
Res.java0%   (0/2)0%   (0/37)0%   (0/1813)0%   (0/468)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Res0%   (0/1)0%   (0/33)0%   (0/1794)0%   (0/460)
<static initializer> 0%   (0/1)0%   (0/3)0%   (0/2)
Res (Model, String, int, boolean, boolean): void 0%   (0/1)0%   (0/116)0%   (0/31)
Res (Model, String, int, int, int, boolean, boolean): void 0%   (0/1)0%   (0/199)0%   (0/60)
activateAsNext (SimProcess): void 0%   (0/1)0%   (0/39)0%   (0/15)
activateFirst (): void 0%   (0/1)0%   (0/44)0%   (0/16)
avgUsage (): double 0%   (0/1)0%   (0/58)0%   (0/14)
changeLimit (int): void 0%   (0/1)0%   (0/98)0%   (0/26)
checkProcess (SimProcess, String): boolean 0%   (0/1)0%   (0/46)0%   (0/15)
createReporter (): Reporter 0%   (0/1)0%   (0/5)0%   (0/2)
deadlockCheckOff (): void 0%   (0/1)0%   (0/55)0%   (0/13)
deadlockCheckOn (): void 0%   (0/1)0%   (0/57)0%   (0/15)
deliver (int): Resource [] 0%   (0/1)0%   (0/118)0%   (0/21)
getAvail (): int 0%   (0/1)0%   (0/3)0%   (0/1)
getDeadlockCheck (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
getLimit (): int 0%   (0/1)0%   (0/3)0%   (0/1)
getMinimum (): int 0%   (0/1)0%   (0/3)0%   (0/1)
getPassBy (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
getQueue (): QueueList 0%   (0/1)0%   (0/3)0%   (0/1)
getQueueStrategy (): String 0%   (0/1)0%   (0/4)0%   (0/1)
getRefused (): long 0%   (0/1)0%   (0/3)0%   (0/1)
getUsers (): long 0%   (0/1)0%   (0/3)0%   (0/1)
getidNumber (): long 0%   (0/1)0%   (0/3)0%   (0/1)
heldResources (SimProcess): int 0%   (0/1)0%   (0/29)0%   (0/6)
isDeadlockDetected (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
provide (int): boolean 0%   (0/1)0%   (0/376)0%   (0/92)
reset (): void 0%   (0/1)0%   (0/20)0%   (0/7)
setDeadlockDetected (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setPassBy (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
takeBack (Resource []): void 0%   (0/1)0%   (0/162)0%   (0/41)
takeBack (int): void 0%   (0/1)0%   (0/180)0%   (0/39)
updateProvidedRes (SimProcess, Resource []): void 0%   (0/1)0%   (0/67)0%   (0/15)
updateStatistics (int): void 0%   (0/1)0%   (0/37)0%   (0/9)
updateTakenBackRes (SimProcess, Resource []): void 0%   (0/1)0%   (0/43)0%   (0/9)
     
class Res$UsedResources0%   (0/1)0%   (0/4)0%   (0/19)0%   (0/8)
Res$UsedResources (SimProcess, Vector): void 0%   (0/1)0%   (0/9)0%   (0/4)
getOccupiedResources (): Vector 0%   (0/1)0%   (0/3)0%   (0/1)
getProcess (): SimProcess 0%   (0/1)0%   (0/3)0%   (0/1)
setOccupiedResources (Vector): void 0%   (0/1)0%   (0/4)0%   (0/2)

1package desmoj.core.advancedModellingFeatures;
2 
3//34567890123456789012345678901234567890123456789012345678901234567890123456
4 
5import java.util.Enumeration;
6import java.util.Vector;
7 
8import desmoj.core.simulator.Model;
9import desmoj.core.simulator.QueueBased;
10import desmoj.core.simulator.QueueList;
11import desmoj.core.simulator.QueueListFifo;
12import desmoj.core.simulator.QueueListLifo;
13import desmoj.core.simulator.QueueListRandom;
14import desmoj.core.simulator.Resource;
15import desmoj.core.simulator.ResourceDB;
16import desmoj.core.simulator.SimProcess;
17import desmoj.core.simulator.TimeInstant;
18import desmoj.core.simulator.TimeOperations;
19import desmoj.core.simulator.TimeSpan;
20import desmoj.core.statistic.StatisticObject;
21 
22/**
23 * Res is the place where resources are stored in a pool. Processes can come by
24 * and the resource pool will <code>provide()</code> resources to them. Each
25 * process has to give back the same resources it once has acquired by calling
26 * the <code>takeBack()</code> method of the Res. Res is used to implement
27 * process synchronization between processes, which are using resources. The
28 * resource pool has a limited capacity. A process can acquire one or more
29 * resources and use them. After usage the process must release this or these
30 * same resources to make them available to other processes. If a process can
31 * not get the number of resources needed, it has to wait in a queue until
32 * enough resources are released by other processes. A process can release its
33 * resources anytime. After the resourcepool has <code>"takenBack"()</code> the
34 * used resources the waiting-queue is checked for processes waiting for them.
35 * The first sort criteria of the queue is always highest priorities first, the
36 * second queueing discipline of the underlying queue and the capacity limit can
37 * be determined by the user (default is FIFO and unlimited capacity). Under
38 * certain circumstances a deadlock might block some waiting
39 * 
40 * @see QueueBased
41 * 
42 * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011
43 * @author Soenke Claassen
44 * 
45 * Licensed under the Apache License, Version 2.0 (the "License");
46 * you may not use this file except in compliance with the License. You
47 * may obtain a copy of the License at
48 * http://www.apache.org/licenses/LICENSE-2.0
49 *
50 * Unless required by applicable law or agreed to in writing, software
51 * distributed under the License is distributed on an "AS IS"
52 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
53 * or implied. See the License for the specific language governing
54 * permissions and limitations under the License.
55 *
56 */
57 
58public class Res extends desmoj.core.simulator.QueueBased {
59 
60        // ****** attributes ******
61 
62        /**
63         * The number identifying a Res object. Because it is a class variable each
64         * <code>Res</code> will get its own ID number starting by zero.
65         */
66        private static long resNumber = 0;
67 
68        /**
69         * The ID number of this <code>Res</code> object.
70         */
71        private long _idNumber;
72 
73        /**
74         * The queue, actually storing the processes waiting for resources
75         */
76        protected QueueList<SimProcess> _queue;
77 
78        /**
79         * The vector holding all the pairs (used resources of this Res, the
80         * Sim-process which holds the resources at the moment). See: inner class
81         * UsedResources
82         */
83        private Vector<UsedResources> _arrayOfUsedResources;
84 
85        /**
86         * The vector holding all the resources of this resource pool not used at
87         * the moment.
88         */
89        private Vector<Resource> _unUsedResources;
90 
91        /**
92         * The resource database keeping track of which SimProcesses holding which
93         * resources and SimPorcesses requesting resources.
94         */
95        private ResourceDB _resourceDB;
96 
97        /**
98         * To indicate whether the check for deadlocks is active or not. Default is
99         * <code>true</code>= deadlock check enabled.
100         */
101        private boolean _deadlockCheck = true;
102 
103        /**
104         * Is set to <code>true</code> if a deadlock is detected where this Res is
105         * involved in. Otherwise it remains <code>false</code>. Default is
106         * <code>false</code>.
107         */
108        private boolean _deadlockDetected = false;
109 
110        /**
111         * The number of resources in the Res (capacity)
112         */
113        private int _limit;
114 
115        /**
116         * The minimum number of resources being available
117         */
118        private int _minimum;
119 
120        /**
121         * Number of resources available at the moment
122         */
123        private int _avail;
124 
125        /**
126         * Number of processes having acquired and released one or more resources
127         */
128        private long _users;
129 
130        /**
131         * Weighted sum of available resources (in the Res over the time)
132         */
133        private double _wSumAvail;
134 
135        /**
136         * The last time the Res has been used
137         */
138        private TimeInstant _lastUsage;
139 
140        /**
141         * Counter for the sim-processes which are refused to be enqueued, because
142         * the queue capacity is full.
143         */
144        private long _refused;
145 
146        /**
147         * Indicates the method where something has gone wrong. Is passed as a
148         * parameter to the method <code>checkProcess()</code>.
149         */
150        private String _where;
151 
152        /**
153         * Flag to indicate whether an entity can pass by other entities in the
154         * queue which are enqueued before that entity in the queue. Is
155         * <code>false</code> as default value.
156         */
157        private boolean _passBy = false;
158 
159        // ****** inner class ******
160 
161        /**
162         * UsedResources is an inner class of Res to encapsulate the pairs of:
163         * Sim-process and an array of resources it holds. These pairs are stored in
164         * the vector <code>arrayOfUsedResources</code>.
165         */
166        private static class UsedResources extends java.lang.Object {
167 
168                // ****** attributes of inner class ******
169 
170                /**
171                 * The sim-process using the resources at the moment.
172                 */
173                private SimProcess process;
174 
175                /**
176                 * The array of resources occupied by the sim-process. In fact the array
177                 * is a java.util.Vector because one does not know how many resources
178                 * the sim-process holds and the number of held resources might vary.
179                 */
180                private Vector<Resource> occupiedResources;
181 
182                // ****** methods of inner class ******
183 
184                /**
185                 * Constructor for a UsedResources object.
186                 * 
187                 * @param sProc
188                 *            SimProcess : The sim-process holding the resources.
189                 * @param occupiedRes
190                 *            java.util.Vector : The resources occupied by the
191                 *            SimProcess.
192                 */
193                protected UsedResources(SimProcess sProc, Vector<Resource> occupiedRes) {
194                        // init variables
195                        this.process = sProc;
196                        this.occupiedResources = occupiedRes;
197                }
198 
199                /**
200                 * Returns the sim-process which holds a number of resources.
201                 * 
202                 * @return SimProcess : The sim-process which holds a number of
203                 *         resources.
204                 */
205                protected SimProcess getProcess() {
206                        return this.process;
207                }
208 
209                /**
210                 * Returns the array of resources occupied by the sim-process.
211                 * 
212                 * @return java.util.Vector : The array of resources occupied by the
213                 *         SimProcess.
214                 */
215                protected Vector<Resource> getOccupiedResources() {
216                        return this.occupiedResources;
217                }
218 
219                /**
220                 * Sets the array of resources occupied by the sim-process to the given
221                 * array <code>newArrayOfOccupiedResources</code>.
222                 * 
223                 * @param newArrayOfOccupiedResources
224                 *            Vector : The new array of resources held by the
225                 *            SimProcess.
226                 */
227                protected void setOccupiedResources(Vector<Resource> newArrayOfOccupiedResources) {
228                        this.occupiedResources = newArrayOfOccupiedResources;
229                }
230 
231        } // end inner class
232 
233        /**
234         * Constructor for a Res with a number of initial resources in it. The
235         * queueing discipline and the capacity limit of the underlying queue can be
236         * chosen, too.
237         * 
238         * @param owner
239         *            Model : The model this Res is associated to.
240         * @param name
241         *            java.lang.String : The Res's name
242         * @param sortOrder
243         *            int : determines the sort order of the underlying queue
244         *            implementation. Choose a constant from <code>QueueBased</code>
245         *            like <code>QueueBased.FIFO</code> or
246         *            <code>QueueBased.LIFO</code> or ...
247         * @param qCapacity
248         *            int : The capacity of the queue, that is how many processes
249         *            can be enqueued. Zero (0) means unlimited capacity.
250         * @param capacity
251         *            int : The number of resources the Res starts with. Must be
252         *            positive and greater than 0.
253         * @param showInReport
254         *            boolean : Flag, if Res should produce a report or not.
255         * @param showInTrace
256         *            boolean : Flag for trace to produce trace messages.
257         */
258        public Res(Model owner, String name, int sortOrder, int qCapacity,
259                        int capacity, boolean showInReport, boolean showInTrace) {
260                super(owner, name, showInReport, showInTrace); // construct QueueBased
261 
262                _idNumber = resNumber++; // increment the resNumber and get it as
263                // IDNumber
264 
265        // determine the queueing strategy
266        switch (sortOrder) {
267        case QueueBased.FIFO :
268            _queue = new QueueListFifo<SimProcess>(); break;
269        case QueueBased.LIFO :
270            _queue = new QueueListLifo<SimProcess>(); break;
271        case QueueBased.RANDOM :
272            _queue = new QueueListRandom<SimProcess>(); break;
273        default :
274            sendWarning(
275                    "The given sortOrder parameter " + sortOrder + " is not valid! "
276                            + "A queue with Fifo sort order will be created.",
277                    "Res : "
278                            + getName()
279                            + " Constructor: Res (Model owner, String name, int "
280                            + "sortOrder, long qCapacity, int capacity, boolean "
281                            + "showInReport, boolean showInTrace)",
282                    "A valid positive integer number must be provided to "
283                            + "determine the sort order of the queue.",
284                    "Make sure to provide a valid positive integer number "
285                            + "by using the constants in the class QueueBased, like "
286                            + "QueueBased.FIFO, QueueBased.LIFO or QueueBased.RANDOM.");
287            _queue = new QueueListFifo<SimProcess>(); 
288        }
289        
290        // give the QueueList a reference to this QueueBased
291        _queue.setQueueBased(this);
292 
293                // set the capacity of the queue
294                queueLimit = qCapacity;
295 
296                // check if it the capacity does make sense
297                if (qCapacity < 0) {
298                        sendWarning(
299                                        "The given capacity of the queue is negative! "
300                                                        + "A queue with unlimited capacity will be created instead.",
301                                        "Res : "
302                                                        + getName()
303                                                        + " Constructor: Res (Model owner, String name, int "
304                                                        + "sortOrder, long qCapacity, int capacity,        boolean "
305                                                        + "showInReport, boolean showInTrace)",
306                                        "A negative capacity for a queue does not make sense.",
307                                        "Make sure to provide a valid positive capacity "
308                                                        + "for the underlying queue.");
309                        // set the capacity to the maximum value
310                        queueLimit = Integer.MAX_VALUE;
311                }
312 
313                // check if qCapacity is zero (that means unlimited capacity)
314                if (qCapacity == 0) {
315                        // set the capacity to the maximum value
316                        queueLimit = Integer.MAX_VALUE;
317                }
318 
319                // construct a vector to hold all the UnUsedResources at the moment
320                _unUsedResources = new Vector<Resource>();
321 
322                // construct a vector to hold the UsedResources (see the inner class)
323                _arrayOfUsedResources = new Vector<UsedResources>();
324 
325                // get a reference to the resource database
326                _resourceDB = owner.getExperiment().getResourceDB();
327 
328                this._limit = capacity;
329                this._minimum = capacity;
330                this._avail = capacity;
331                this._users = 0;
332                this._wSumAvail = 0.0;
333                this._refused = 0;
334                this._lastUsage = presentTime();
335 
336                if (capacity <= 0) // nothing or less in the resource pool, you fool!
337                {
338                        sendWarning(
339                                        "Attempt to construct a Res with nothing or a negativ"
340                                                        + " number of resources. Initial number of resources is set to one!",
341                                        "Res: "
342                                                        + getName()
343                                                        + " Constructor: Res (Model owner, String name, int sortOrder, "
344                                                        + "long qCapacity, int capacity, boolean showInReport, "
345                                                        + "boolean showInTrace)",
346                                        "A negative number of resources does not make sense here.",
347                                        "Make sure to initialize the capacity of a Res always with"
348                                                        + " a positive number of resources.");
349 
350                        _limit = _minimum = _avail = 1; // set it to 1, that makes more
351                        // sense
352                }
353 
354                // make the resource objects and store them in the vector of unused
355                // resources
356                for (int i = 0; i < capacity; i++) {
357                        // make the resources and give them the name of the Res pool
358                        Resource aResource = new Resource(owner, name, this, true);
359 
360                        _unUsedResources.addElement(aResource);
361                }
362        }
363 
364        // ****** methods ******
365 
366        /**
367         * Constructor for a Res with a number of initial resources in it. The
368         * underlying queue has a Fifo queueing discipline and unlimited capacity.
369         * 
370         * @param owner
371         *            Model : The model this Res is associated to.
372         * @param name
373         *            java.lang.String : The Res's name
374         * @param capacity
375         *            int : The number of resources the Res starts with. Must be
376         *            positive and greater than 0.
377         * @param showInReport
378         *            boolean : Flag, if Res should produce a report or not.
379         * @param showInTrace
380         *            boolean : Flag for trace to produce trace messages.
381         */
382        public Res(Model owner, String name, int capacity, boolean showInReport,
383                        boolean showInTrace) {
384                super(owner, name, showInReport, showInTrace); // construct QueueBased
385 
386                _idNumber = resNumber++; // increment the resNumber and get it as
387                // IDNumber
388 
389                // make an actual queue and give it a reference of this "QueueBased"-Res
390                _queue = new QueueListFifo<SimProcess>();
391                _queue.setQueueBased(this);
392 
393                // construct a vector to hold all the UnUsedResources at the moment
394                _unUsedResources = new Vector<Resource>();
395 
396                // construct a vector to hold the UsedResources (see the inner class)
397                _arrayOfUsedResources = new Vector<UsedResources>();
398 
399                // get a reference to the resource database
400                _resourceDB = owner.getExperiment().getResourceDB();
401 
402                this._limit = capacity;
403                this._minimum = capacity;
404                this._avail = capacity;
405                this._users = 0;
406                this._wSumAvail = 0.0;
407                this._refused = 0;
408                this._lastUsage = presentTime();
409 
410                if (capacity <= 0) // nothing or less in the resource pool, you fool!
411                {
412                        sendWarning(
413                                        "Attempt to construct a Res with nothing or a negativ"
414                                                        + " number of resources. Initial number of resources is set to one!",
415                                        "Res: "
416                                                        + getName()
417                                                        + " Constructor: Res (desmoj.Model owner, String name, "
418                                                        + "int capacity, boolean showInReport, boolean showInTrace)",
419                                        "A negative number of resources does not make sense here.",
420                                        "Make sure to initialize the capacity of a Res always with"
421                                                        + " a positive number of resources.");
422 
423                        _limit = _minimum = _avail = 1; // set it to 1, that makes more
424                        // sense
425                }
426 
427                // make the resource objects and store them in the vector of unused
428                // resources
429                for (int i = 0; i < capacity; i++) {
430                        // make the resources and give them the name of the Res pool
431                        Resource aResource = new Resource(owner, name, this, true);
432 
433                        _unUsedResources.addElement(aResource);
434                }
435        }
436 
437        /**
438         * Activates the sim-process <code>process</code>, given as a parameter of
439         * this method, as the next process. This process should be a sim-process
440         * waiting in the queue for some resources.
441         * 
442         * @param process
443         *            SimProcess : The process that is to be activated as next.
444         */
445        protected void activateAsNext(SimProcess process) {
446                _where = "protected void activateAsNext(SimProcess process)";
447 
448                if (process != null) {
449                        // if the given process is not valid just return
450                        if (!checkProcess(process, _where)) {
451                                return;
452                        }
453 
454                        // if the process is scheduled (on the event-list) already
455                        if (process.isScheduled()) {
456                                process.skipTraceNote(); // don't tell the user, that we ...
457                                process.cancel(); // get the process from the event-list
458                        }
459 
460                        // remember if the process is blocked at the moment
461                        boolean wasBlocked = process.isBlocked();
462 
463                        // unblock the process to be able to activate him
464                        if (wasBlocked) {
465                                process.setBlocked(false); // the process is not blocked
466                                // anymore
467                                // and
468                        } // ready to become activated
469 
470                        // don't tell the user, that we activate the process after the
471                        // current process
472                        process.skipTraceNote();
473                        process.activateAfter(current());
474 
475                        // the process status is still "blocked"
476                        if (wasBlocked) {
477                                process.setBlocked(true);
478                        }
479                } // end outer if
480        }
481 
482        /**
483         * Activates the first process waiting in the queue. That is a process which
484         * was trying to acquire resources, but there were not enough left in the
485         * Res. Or another process was first in the queue to be served. This method
486         * is called every time a process returns resources or when a process in the
487         * waiting-queue is satisfied.
488         */
489        protected void activateFirst() {
490                _where = "protected void activateFirst()";
491 
492                // first is the first process in the queue (or null if none is in the
493                // queue)
494                SimProcess first = _queue.first();
495 
496                if (first != null) {
497                        // if first is not modelcompatible just return
498                        if (!checkProcess(first, _where)) {
499                                return;
500                        }
501 
502                        // if first is scheduled (on the event-list) already
503                        if (first.isScheduled()) {
504                                first.skipTraceNote(); // don't tell the user, that we ...
505                                first.cancel(); // get the process from the event-list
506                        }
507 
508                        // remember if first is blocked at the moment
509                        boolean wasBlocked = first.isBlocked();
510 
511                        // unblock the process to be able to activate him
512                        if (wasBlocked) {
513                                first.setBlocked(false);
514                        }
515 
516                        // don't tell the user, that we activate first after the current
517                        // process
518                        first.skipTraceNote();
519                        first.activateAfter(current());
520 
521                        // the status of first is still "blocked"
522                        if (wasBlocked) {
523                                first.setBlocked(true);
524                        }
525                } // end outer if
526        }
527 
528        /**
529         * Returns the average usage of the Res. That means: in average, which
530         * percentage of the resources were in use over the time?
531         * 
532         * @return double : the average usage of the resources in the Res.
533         */
534        public double avgUsage() {
535                TimeInstant now = presentTime(); // what is the time?
536 
537                // how long since the last reset
538                TimeSpan diff = TimeOperations.diff(now, resetAt());
539 
540                double wSumAvl = _wSumAvail
541                                + ((double) _avail * TimeOperations.diff(now, _lastUsage)
542                                                .getTimeInEpsilon());
543                if (TimeSpan.isEqual(diff, TimeSpan.ZERO)) // just reseted
544                {
545                        sendWarning(
546                                        "A division by zero error occured.",
547                                        "Res: " + this.getName() + " Method: double avgUsage ()",
548                                        "The time difference between the last reset and now is zero.",
549                                        "Do not reset any model component at the same time the simulation is "
550                                                        + "over or will be stopped.");
551 
552                        return UNDEFINED; // see QueueBased: UNDEFINED = -1
553                }
554 
555                // calculate the average usage
556                double avgUsg = 1.0 - ((wSumAvl / diff.getTimeInEpsilon()) / _limit);
557                // return the rounded average usage
558                return StatisticObject.round(avgUsg);
559        }
560 
561        /**
562         * Changes the limit of the available resources in the Res. Sets the number
563         * of the maximum available resources to m. m must be positive. This is only
564         * allowed as long as the Res has not been used or the Res has just been
565         * reset.
566         * 
567         * @param m
568         *            int : The new limit (capacity) of the Res. Must be positive.
569         */
570        public void changeLimit(int m) {
571                if (_limit != _minimum || _users != 0) // if Res is already used
572                {
573                        sendWarning(
574                                        "Attempt to change the limit of a Res already"
575                                                        + " in use. The limit will remain unchanged!",
576                                        "Res: " + this.getName()
577                                                        + " Method: void changeLimit (long m)",
578                                        "The limit of a Res which has already be used can not"
579                                                        + " be changed afterwards.",
580                                        "Do not try to change the limit of a Res which might have been"
581                                                        + " used already. Or reset the Res before changing its limit.");
582 
583                        return; // without changing the limit
584                }
585 
586                if (m <= 0) // Trying to set the limit to 0 or a negative value.
587                {
588                        sendWarning(
589                                        "Attempt to change the limit of a Res to zero"
590                                                        + " or a negative number. The limit will remain unchanged!",
591                                        "Res: " + this.getName() + " Method: void changeLimit "
592                                                        + "(long m)",
593                                        "The limit of a Res can not be set to zero or a negative"
594                                                        + " number. That would make no sense.",
595                                        "Do not try to change the limit of a Res to negative "
596                                                        + "or zero. Choose a positive integer instead.");
597 
598                        return; // ignore this rubbish
599                }
600 
601                // adjust the number of resources stored in the array of unused
602                // resources
603                if (m > _limit) // the limit is increasing
604                {
605                        for (int i = _limit; i < m; i++) {
606                                // make the resources and give them the name of the Res pool
607                                Resource aResource = new Resource(getModel(), getName(), this,
608                                                true);
609                                _unUsedResources.addElement(aResource);
610                        }
611                }
612 
613                if (m < _limit) // the limit is decreasing
614                        for (int i = m; i < _limit; i++) {
615                                _unUsedResources.removeElementAt(i);
616                        }
617 
618                // set the limit and the minimum to the new value
619                _limit = _minimum = _avail = m;
620 
621        }
622 
623        /**
624         * Checks whether the process using the Res is a valid process.
625         * 
626         * @return boolean : Returns whether the sim-process is valid or not.
627         * @param p
628         *            SimProcess : Is this SimProcess a valid one?
629         */
630        protected boolean checkProcess(SimProcess p, String where) {
631                if (p == null) // if p is a null pointer instead of a process
632                {
633                        sendWarning("A non existing process is trying to use a Res "
634                                        + "object. The attempted action is ignored!", "Res: "
635                                        + getName() + " Method: " + where,
636                                        "The process is only a null pointer.",
637                                        "Make sure that only real SimProcesses are using Res's.");
638                        return false;
639                }
640 
641                if (!isModelCompatible(p)) // if p is not modelcompatible
642                {
643                        sendWarning(
644                                        "The process trying to use a Res object does"
645                                                        + " not belong to this model. The attempted action is ignored!",
646                                        "Res: " + getName() + " Method: " + where,
647                                        "The process is not modelcompatible.",
648                                        "Make sure that processes are using only Res's within"
649                                                        + " their model.");
650                        return false;
651                }
652                return true;
653        }
654 
655        /**
656         * Returns a Reporter to produce a report about this Res.
657         * 
658         * @return desmoj.report.Reporter : The Reporter for the queue inside this
659         *         Res.
660         */
661        public desmoj.core.report.Reporter createReporter() {
662                return new desmoj.core.advancedModellingFeatures.report.ResourceReporter(
663                                this);
664        }
665 
666        /**
667         * Turns the deadlock check off. So whenever a sim-process can not get the
668         * resources desired, there won't be checked if a deadlock situation might
669         * have occured.
670         */
671        public void deadlockCheckOff() {
672 
673                _deadlockCheck = false; // that's all
674 
675                // send a warning if the resource pool has been used already
676                if (_limit != _minimum || _users != 0) // if Res is already used
677                {
678                        sendWarning(
679                                        "The deadlock check for the resource pool: "
680                                                        + this.getName() + " is turned off!",
681                                        "Res: " + this.getName()
682                                                        + " Method: void deadlockCheckOff()",
683                                        "The deadlock check for this resource pool is turned off, but "
684                                                        + "some resources are already in use.",
685                                        "Make sure, that you really want to turn the deadlock check off "
686                                                        + " even after some resources have been used already.");
687                }
688 
689                // for debugging purposes
690                if (currentlySendDebugNotes()) {
691                        sendDebugNote("The deadlock check for '" + getName()
692                                        + "' is turned " + "off now.");
693                }
694        }
695 
696        /**
697         * Turns the deadlock check on. So whenever a sim-process can not get the
698         * resources desired, it will be checked if a deadlock situation might
699         * occur.
700         */
701        public void deadlockCheckOn() {
702 
703                _deadlockCheck = true; // that's all
704 
705                // send a warning if the resource pool has been used already
706                if (_limit != _minimum || _users != 0) // if Res is already used
707                {
708                        sendWarning(
709                                        "The deadlock check for the resource pool: "
710                                                        + this.getName()
711                                                        + " is turned on. But some resources have been "
712                                                        + "used already!",
713                                        "Res: " + this.getName()
714                                                        + " Method: void deadlockCheckOn()",
715                                        "The deadlock check for this resource pool is turned on again, "
716                                                        + "but some resources are already in use. So the deadlock check can "
717                                                        + "not be performed correctly!",
718                                        "Make sure to turn the deadlock check on before the resources will "
719                                                        + "be used.");
720                }
721 
722                // for debugging purposes
723                if (currentlySendDebugNotes()) {
724                        sendDebugNote("The deadlock check for '" + getName()
725                                        + "' is turned " + "on again from now on.");
726                }
727        }
728 
729        /**
730         * Takes a number of n resources from the Res pool and delivers this array
731         * of resources to the Simprocess to use them. Is called from the method
732         * <code>provide (int n)</code>.
733         * 
734         * @param n
735         *            int : The number of resources the resourcepool will <code>
736         * deliver()</code>
737         *            to the sim-process.
738         * @return Resource[] : the array of resources which will be delivered to
739         *         the sim-process.
740         */
741        private Resource[] deliver(int n) {
742                SimProcess currentProcess = currentSimProcess();
743 
744                // get the resources from the unused resources pool
745                Resource[] resArray = new Resource[n]; // make the array of resources
746 
747                // fill the array of resources
748                for (int i = 0; i < n; i++) {
749                        // put first res in array
750                        resArray[i] = _unUsedResources.firstElement();
751                        // delete first res
752                        _unUsedResources.removeElement(_unUsedResources.firstElement());
753                }
754 
755                // note which SimProcess is holding how many Resources
756                updateProvidedRes(currentProcess, resArray);
757 
758                // for debugging purposes
759                if (currentlySendDebugNotes()) {
760                        // make a string including all elements of the array of provided
761                        // res.
762                        StringBuilder s = new StringBuilder();
763                        s.append("delivers to SimProcess '" + currentProcess.getName() + "': ");
764 
765                        for (int j = 0; j < n; j++) {
766                                s.append("<br>" + resArray[j].getName());
767                        }
768 
769                        sendDebugNote(s.toString());
770 
771                        // make a string including all the resource that are left in the Res
772                        StringBuilder t = new StringBuilder();
773                        t.append("In this Res pool are left: ");
774 
775                        if (_unUsedResources.isEmpty()) // anything left ?
776                        {
777                                t.append("<br>none");
778                        }
779 
780                        for (Enumeration<Resource> e = _unUsedResources.elements(); e
781                                        .hasMoreElements();) {
782                                t.append("<br>" + e.nextElement().getName());
783                        }
784 
785                        sendDebugNote(t.toString());
786                }
787 
788                return resArray; // return the array of resources
789        }
790 
791        /**
792         * Returns the number of resources available in the pool at the moment.
793         * 
794         * @return int : The number of resources available at the moment.
795         */
796        public int getAvail() {
797                return this._avail;
798        }
799 
800        /**
801         * Returns if the deadlock check is enabled (<code>true</code>) or not (
802         * <code>false</code>).
803         * 
804         * @return boolean :<code>true</code> if the deadlock check is enabled,
805         *         <code>false</code> if the deadlock check is not enabled
806         */
807        public boolean getDeadlockCheck() {
808 
809                return _deadlockCheck; // that's all
810        }
811 
812        /**
813         * Returns the ID number of this <code>Res</code> object.
814         * 
815         * @return long : The ID number of this <code>Res</code> object.
816         */
817        public long getidNumber() {
818                return _idNumber;
819        }
820 
821        /**
822         * Returns the initial number of resources in the Res pool.
823         * 
824         * @return int : The initial number of resources in the Res pool at the
825         *         beginning.
826         */
827        public int getLimit() {
828                return this._limit;
829        }
830 
831        /**
832         * Returns the minimum number of resources in the Res.
833         * 
834         * @return int : The minimum number of resources in the Res.
835         */
836        public int getMinimum() {
837                return this._minimum;
838        }
839 
840        /**
841         * Returns whether entities can pass by other entities which are enqueued
842         * before them in the queue.
843         * 
844         * @return boolean : Indicates whether entities can pass by other entities
845         *         which are enqueued before them in the queue.
846         */
847        public boolean getPassBy() {
848                return _passBy;
849        }
850 
851        /**
852         * Returns the <code>QueueList</code> actually storing the
853         * <code>SimProcesses</code> waiting for resources.
854         * 
855         * @return desmoj.QueueList : the queue actually storing the
856         *         <code>SimProcesses</code> waiting for resources.
857         */
858        public QueueList<SimProcess> getQueue() {
859 
860                return _queue; // that's it
861        }
862 
863        /**
864         * Returns the implemented queueing discipline of the underlying queue as a
865         * String, so it can be displayed in the report.
866         * 
867         * @return String : The String indicating the queueing discipline.
868         */
869        public String getQueueStrategy() {
870 
871                return _queue.getAbbreviation(); // that's it
872 
873        }
874 
875        /**
876         * Returns the number of entities refused to be enqueued in the queue,
877         * because the capacity limit is reached.
878         * 
879         * @return long : The number of entities refused to be enqueued in the
880         *         queue.
881         */
882        public long getRefused() {
883 
884                return _refused; // that's it
885        }
886 
887        /**
888         * Returns the number of users.
889         * 
890         * @return long : The number of Users. That are processes having acquired
891         *         and released resources.
892         */
893        public long getUsers() {
894                return this._users;
895        }
896 
897        /**
898         * Returns the number of resources held by the given SimProcess at this
899         * time.
900         * 
901         * @return int : The number of resources held by the given SimProcess at
902         *         this time.
903         * @param sProc
904         *            SimProcess : The sim-process which is expected to hold some
905         *            Resources.
906         */
907        protected int heldResources(SimProcess sProc) {
908                int j = 0; // to count the resources held
909 
910                for (int i = 0; i < _arrayOfUsedResources.size(); i++) {
911                        // get hold of the UsedResources pair (SimProcess/number of
912                        // resources)
913                        UsedResources procHoldRes = _arrayOfUsedResources.elementAt(i);
914 
915                        if (procHoldRes.getProcess() == sProc) {
916                                j += procHoldRes.getOccupiedResources().size();
917                        } // end if
918                } // end for
919 
920                return j; // all the resources the sim-process holds at the moment
921        }
922 
923        /**
924         * Returns <code>true</code> if a deadlock is detected, <code>false</code>
925         * otherwise.
926         * 
927         * @return boolean : is <code>true</code> if a deadlock is detected,
928         *         <code>false</code> otherwise.
929         */
930        public boolean isDeadlockDetected() {
931 
932                return _deadlockDetected; // that's it
933        }
934 
935        /**
936         * Gets a number of n resources from the Res pool and provides them to the
937         * Sim-process to use them. Hint for developers: calls the private method
938         * <code>deliver()</code>. As not enough resources are available at the
939         * moment the sim-process has to wait in a queue until enough products are
940         * available again.
941         * 
942         * @return boolean : Is <code>true</code> if the specified number of
943         *         resources have been provided successfully, <code>false</code>
944         *         otherwise (i.e. capacity limit of the queue is reached).
945         * @param n
946         *            int : The number of resources the resourcepool will <code>
947         * provide()</code>
948         *            to the sim-process.
949         */
950        public boolean provide(int n) {
951                _where = " boolean provide (int n)";
952 
953                SimProcess currentProcess = currentSimProcess();
954 
955                if (!checkProcess(currentProcess, _where)) // if the current process
956                {
957                        return false;
958                } // is not valid: return
959 
960                if (n <= 0) // trying to provide nothing or less
961                {
962                        sendWarning(
963                                        "Attempt from a Res to provide nothing or a negative "
964                                                        + "number of resources . The attempted action is ignored!",
965                                        "Res: " + getName() + " Method: provide (int n)",
966                                        "It does not make sense to provide nothing or a negative number "
967                                                        + "of resources. The statistic will be corrupted with negative numbers!",
968                                        "Make sure to provide at least one resource from the Res.");
969 
970                        return false; // ignore that rubbish
971                }
972 
973                // total of resources acquired and already held by the current
974                // SimProcess
975                int total = n + heldResources(currentProcess);
976 
977                if (total > _limit) // trying to provide (in total) more than the
978                { // capacity of the Res
979                        sendWarning(
980                                        "Attempt from a Res to provide more resources than its "
981                                                        + "capacity holds. The attempted action is ignored!",
982                                        "Res: " + getName() + " Method: provide (int n)",
983                                        "The requested resources [" + total
984                                                        + "] could never be provided by the Res"
985                                                        + ", because the capacity of this Res [" + _limit
986                                                        + "] is not that big. <br>"
987                                                        + "Therefore the process '"
988                                                        + currentProcess.getName() + "' might be blocked "
989                                                        + "for ever.",
990                                        "Make sure never to let the Res provide more resources than its "
991                                                        + "capacity.");
992 
993                        return false; // ignore that rubbish
994                }
995 
996                if (queueLimit <= length()) // check if capac. limit of queue is reached
997                {
998                        if (currentlySendDebugNotes()) {
999                                sendDebugNote("refuses to insert "
1000                                                + currentProcess.getQuotedName()
1001                                                + " in waiting-queue, because the capacity limit is reached. ");
1002                        }
1003 
1004                        if (currentlySendTraceNotes()) {
1005                                sendTraceNote("is refused to be enqueued in "
1006                                                + this.getQuotedName() + "because the capacity limit ("
1007                                                + getQueueLimit() + ") of the " + "queue is reached");
1008                        }
1009 
1010                        _refused++; // count the refused ones
1011 
1012                        return false; // capacity limit is reached
1013                }
1014 
1015                // insert every process in the queue for statistical reasons
1016                _queue.insert(currentProcess);
1017 
1018                // is it possible for this process to pass by?
1019                if (_passBy == false) {
1020                        // see if the sim-process can be satisfied or has to wait in the
1021                        // queue
1022                        if (n > _avail || // not enough resources available OR
1023                                        currentProcess != _queue.first()) // other process is
1024                        // first
1025                        // in the q
1026                        {
1027                                // tell in the trace what the process is waiting for
1028                                if (currentlySendTraceNotes()) {
1029                                        sendTraceNote("awaits " + n + " of ' " + this.getName()
1030                                                        + " '");
1031                                }
1032 
1033                                // tell in the debug output what the process is waiting for
1034                                if (currentlySendDebugNotes()) {
1035                                        sendDebugNote("has not enough resources left to provide "
1036                                                        + n + " unit(s) to '" + currentProcess.getName()
1037                                                        + "'");
1038                                }
1039 
1040                                // check for deadlock?
1041                                if (getDeadlockCheck()) {
1042                                        // update the resourceDB: this SimProcess is requesting
1043                                        // resources
1044                                        _resourceDB.noteResourceRequest(currentProcess, this, n);
1045 
1046                                        // check if this unsatisfied resource request has caused a
1047                                        // deadlock
1048                                        _deadlockDetected = _resourceDB
1049                                                        .checkForDeadlock(currentProcess);
1050                                }
1051 
1052                                // the process is caught in this do-while loop as long as ...see
1053                                // while
1054                                do {
1055                                        currentProcess.setBlocked(true); // block the process
1056                                        currentProcess.skipTraceNote(); // don't tell the user, that
1057                                        // we ...
1058                                        currentProcess.passivate(); // passivate the current process
1059                                } while (n > _avail || // not enough resources available OR
1060                                                currentProcess != _queue.first()); // other process is
1061                                // first
1062 
1063                                // check for deadlock?
1064                                if (getDeadlockCheck()) {
1065                                        // delete the request of the resources in the resourceDB
1066                                        _resourceDB.deleteResRequest(currentProcess, this, n);
1067                                }
1068 
1069                        } // end if
1070                } else // the process can pass by other processes in the queue, passBy
1071                // =
1072                // true
1073                {
1074                        if (n > _avail || // not enough resources available OR
1075                                        currentProcess != _queue.first()) // other process is
1076                        // first
1077                        // in the q
1078                        {
1079                                // is the current process the first in the queue?
1080                                if (currentProcess != _queue.first()) // no it's not the first
1081                                {
1082                                        // we have to make sure that no other process in front of
1083                                        // this current
1084                                        // process in the wait queue could be satisfied, so activate
1085                                        // the first Process in the queue to see what he can do. He
1086                                        // will pass
1087                                        // the activation on to his successors until this process
1088                                        // will be
1089                                        // activated again to get his products. (hopefully)
1090                                        activateFirst();
1091                                }
1092 
1093                                // only if not enough units are available the process has to
1094                                // wait
1095                                if (n > _avail) {
1096                                        // tell in the trace what the process is waiting for
1097                                        if (currentlySendTraceNotes()) {
1098                                                sendTraceNote("awaits " + n + " of ' " + this.getName()
1099                                                                + " '");
1100                                        }
1101 
1102                                        // tell in the debug output what the process is waiting for
1103                                        if (currentlySendDebugNotes()) {
1104                                                sendDebugNote("has not enough resources left to provide "
1105                                                                + n
1106                                                                + " unit(s) to '"
1107                                                                + currentProcess.getName() + "'");
1108                                        }
1109                                } // end if not enough units are available
1110 
1111                                // check for deadlock?
1112                                if (getDeadlockCheck()) {
1113                                        // update the resourceDB: this SimProcess is requesting
1114                                        // resources
1115                                        _resourceDB.noteResourceRequest(currentProcess, this, n);
1116 
1117                                        // check if this unsatisfied resource request has caused a
1118                                        // deadlock
1119                                        _deadlockDetected = _resourceDB
1120                                                        .checkForDeadlock(currentProcess);
1121                                }
1122 
1123                                // the process is caught in this do-while loop as long as ...see
1124                                // while
1125                                do {
1126                                        currentProcess.setBlocked(true); // block the process
1127                                        currentProcess.skipTraceNote(); // don't tell the user, that
1128                                        // we ...
1129                                        currentProcess.passivate(); // passivate the current process
1130 
1131                                        // activate the next process in the queue to see what he can
1132                                        // do
1133                                        activateAsNext(_queue.succ(currentProcess));
1134                                } while (n > _avail); // not enough resources available
1135 
1136                                // check for deadlock?
1137                                if (getDeadlockCheck()) {
1138                                        // delete the request of the resources in the resourceDB
1139                                        _resourceDB.deleteResRequest(currentProcess, this, n);
1140                                }
1141 
1142                        }
1143                } // end else (passBy = true)
1144 
1145                // the current process has got the resources he wanted ...
1146 
1147                // the Res provides all the resources the sim-process wants
1148                _queue.remove(currentProcess); // get the process out of the queue
1149                currentProcess.setBlocked(false); // we are not blocked (anymore),
1150                // yeah!
1151 
1152                // give the new first process in the queue a chance
1153                activateFirst();
1154 
1155                // hand the resources over to the sim-process
1156                currentProcess.obtainResources(deliver(n));
1157 
1158                updateStatistics(-n); // statistics will be updated
1159 
1160                // check for deadlock?
1161                if (getDeadlockCheck()) {
1162                        // update the resourceDB: resources are assigned to the sim-process
1163                        // now
1164                        _resourceDB.noteResourceAllocation(this, currentProcess, n);
1165                }
1166 
1167                if (currentlySendTraceNotes()) {
1168                        sendTraceNote("seizes " + n + " from " + this.getQuotedName());
1169                } // tell in the trace what the process is taking from the resources
1170 
1171                // a debug message is generated in the method deliver(), see some lines
1172                // above
1173 
1174                return true;
1175        }
1176 
1177        /**
1178         * Resets the statistics of this Res. The number of available resources at
1179         * this moment and the processes waiting in the queue are not changed. But
1180         * all statistic counters are reset. The parent <code>QueueBased</code> is
1181         * also reset.
1182         */
1183        public void reset() {
1184                super.reset(); // reset the QueueBased also
1185 
1186                _minimum = _limit; // not quite correct, but needed for changeLimit()
1187                _users = 0;
1188                _wSumAvail = 0.0;
1189                _refused = 0;
1190                _lastUsage = presentTime();
1191        }
1192 
1193        /**
1194         * Sets the boolean field <code>deadlockDetected</code> to the given value.
1195         * If a deadlock for this <code>Res</code> is detected when an unsuccessfull
1196         * seize statement for a resource has taken place, then the value of
1197         * <code>deadlockDetected</code> will be set to <code>true</code>. The value
1198         * will also been shown in the report of this <code>Res</code>.
1199         * 
1200         * @param dlDetected
1201         *            boolean : the new value for the field
1202         *            <code>deadlockDetected</code>. Should be <code>true</code> if
1203         *            this <code>Res</code> is involved in a deadlock.
1204         */
1205        public void setDeadlockDetected(boolean dlDetected) {
1206 
1207                _deadlockDetected = dlDetected; // that's all
1208        }
1209 
1210        /**
1211         * Sets the flag passBy to a new value. PassBy is indicating whether
1212         * entities can pass by other entities which are enqueued before them in the
1213         * queue.
1214         * 
1215         * @param newPassBy
1216         *            boolean : The new value of passBy. Set it to <code>true</code>
1217         *            if you want entities to pass by other entities which are
1218         *            enqueued before them in the queue. Set it to
1219         *            <code>false</code> if you don't want entities to overtake
1220         *            other entities in the queue.
1221         */
1222        public void setPassBy(boolean newPassBy) {
1223                this._passBy = newPassBy; // that's all!
1224        }
1225 
1226        /**
1227         * A process is using this method to put resources it has used back in the
1228         * Res pool. The process can not put more resources back than it has
1229         * acquired once. The array of returning resources can be provided by the
1230         * method <code>returnResources()</code> of the class
1231         * <code>SimProcess</code>.
1232         * 
1233         * @param returnedRes
1234         *            Resource[] : The array of resources a process is returning to
1235         *            the resource pool. Can't be more resources than it once has
1236         *            acquired!
1237         */
1238        public void takeBack(Resource[] returnedRes) {
1239                _where = "void takeBack (Resource[] returnedRes)        ";
1240 
1241                SimProcess currentProcess = currentSimProcess();
1242 
1243                if (!checkProcess(currentProcess, _where)) // check the current process
1244                {
1245                        return;
1246                } // if it is not valid just return
1247 
1248                if (returnedRes.length <= 0) // if the process is releasing nothing
1249                {
1250                        sendWarning(
1251                                        "The array of returned resources is empty! "
1252                                                        + "The attempted action is ignored!",
1253                                        "Res: " + this.getName()
1254                                                        + " Method: void takeBack (Resource[] "
1255                                                        + "returnedRes)",
1256                                        "It makes no sense to take back an empty array of resources.",
1257                                        "Make sure to return at least one resource to the Res pool.");
1258 
1259                        return; // go to where you came from
1260                }
1261 
1262                // the process is trying to release more resources than it holds
1263                if (returnedRes.length > heldResources(currentProcess)) {
1264                        sendWarning(
1265                                        "Attempt to make the Res take back more resources than "
1266                                                        + "the process is holding at the moment. The attempted action is "
1267                                                        + "ignored!", "Res: " + this.getName()
1268                                                        + " Method: void takeBack (Resource[] "
1269                                                        + "returnedRes)",
1270                                        "A process can not release more resources than it holds.",
1271                                        "Make sure not to take back more resources than the process is holding.");
1272 
1273                        return; // go to where you came from
1274                }
1275 
1276                // put the used resources back in the unused resources pool
1277                for (int i = 0; i < returnedRes.length; i++) {
1278                        _unUsedResources.addElement(returnedRes[i]);
1279                }
1280 
1281                // update which SimProcess is holding which Resources
1282                updateTakenBackRes(currentProcess, returnedRes);
1283 
1284                updateStatistics(returnedRes.length); // statistics will be updated
1285                _users++; // update users
1286 
1287                // update the resource database / check for deadlock?
1288                if (getDeadlockCheck()) {
1289                        _resourceDB.deleteResAllocation(this, currentProcess,
1290                                        returnedRes.length);
1291                }
1292 
1293                // tell in the trace what the process is returning to the Res pool
1294                if (currentlySendTraceNotes()) {
1295                        sendTraceNote("releases " + returnedRes.length + " to "
1296                                        + this.getQuotedName());
1297                }
1298 
1299                // for debugging purposes
1300                if (currentlySendDebugNotes()) {
1301                        // make a string including all elements of the array of returned
1302                        // res.
1303                        StringBuilder s = new StringBuilder();
1304                        s.append("SimProcess '" + currentProcess.getName() + "' <b>returns</b>: ");
1305 
1306                        for (int j = 0; j < returnedRes.length; j++) {
1307                                s.append("<br>" + returnedRes[j].getName());
1308                        }
1309 
1310                        sendDebugNote(s.toString());
1311                }
1312 
1313                activateFirst(); // give the new first process in the queue a chance
1314        }
1315 
1316        /**
1317         * A process is using this method to put resources it has used back in the
1318         * Res pool. The process can not put more resources back than it has
1319         * acquired once. This method can be used as an alternative to the method
1320         * <code>takeBack(Resource[] returnedRes)</code> in cases that the user does
1321         * not want to provide an array of returning resources. This method is also
1322         * compatible with older DESMO-J Versions.
1323         * 
1324         * @param n
1325         *            int : The number of resources which should be returned to the
1326         *            Res pool. Can't be more than once were acquired!
1327         */
1328        public void takeBack(int n) {
1329                _where = "void takeBack (int n) ";
1330 
1331                SimProcess currentProcess = currentSimProcess();
1332 
1333                if (!checkProcess(currentProcess, _where)) // check the current process
1334                {
1335                        return;
1336                } // if it is not valid just return
1337 
1338                if (n <= 0) // if the process is releasing nothing
1339                {
1340                        sendWarning(
1341                                        "The number of returned resources is negative or zero! "
1342                                                        + "The attempted action is ignored!",
1343                                        "Res: " + this.getName() + " Method: void takeBack (int n)",
1344                                        "It makes no sense to take back nothing or a negative number of "
1345                                                        + "resources.",
1346                                        "Make sure to return at least one resource to the Res pool.");
1347 
1348                        return; // go to where you came from
1349                }
1350 
1351                // the process is trying to release more resources than it holds
1352                if (n > heldResources(currentProcess)) {
1353                        sendWarning("Attempt to make the Res take back more resources ["
1354                                        + n + "] than the process '" + currentProcess.getName()
1355                                        + "' is holding at the " + "moment ["
1356                                        + heldResources(currentProcess) + "]. <br>"
1357                                        + "The attempted action is ignored!", "Res: "
1358                                        + this.getName() + " Method: void takeBack (int n)",
1359                                        "A process can not release more resources than it holds.",
1360                                        "Make sure not to bring back more resources than the process is holding.");
1361 
1362                        return; // go to where you came from
1363                }
1364 
1365                // get the array of returned resources from the sim-process
1366                Resource[] returnedRes = currentProcess.returnResources(this, n);
1367 
1368                // put the used resources back in the unused resources pool
1369                for (int i = 0; i < n; i++) {
1370                        _unUsedResources.addElement(returnedRes[i]);
1371                }
1372 
1373                // update which SimProcess is holding which Resources
1374                updateTakenBackRes(currentProcess, returnedRes);
1375 
1376                updateStatistics(n); // statistics will be updated
1377                _users++; // update users
1378 
1379                // update the resource database / check for deadlock?
1380                if (getDeadlockCheck()) {
1381                        _resourceDB.deleteResAllocation(this, currentProcess, n);
1382                }
1383 
1384                // tell in the trace what the process is returning to the Res pool
1385                if (currentlySendTraceNotes()) {
1386                        sendTraceNote("releases " + n + " to " + this.getQuotedName());
1387                }
1388 
1389                // for debugging purposes
1390                if (currentlySendDebugNotes()) {
1391                        // make a string including all elements of the array of returned
1392                        // res.
1393                    StringBuilder s = new StringBuilder();
1394                        s.append("SimProcess '" + currentProcess.getName() + "' <b>returns</b>: ");
1395 
1396                        for (int j = 0; j < returnedRes.length; j++) {
1397                            s.append("<br>" + returnedRes[j].getName());
1398                        }
1399 
1400                        sendDebugNote(s.toString());
1401                }
1402 
1403                activateFirst(); // give the new first process in the queue a chance
1404        }
1405 
1406        /**
1407         * 
1408         * Muss durch eine andere Methode in SimProcess ersetzt werden ???
1409         * 
1410         * Soenke ????
1411         * 
1412         * 
1413         * A process is using this method to return all the resources it holds to
1414         * the Res pool. The process can not put more resources back than it has
1415         * acquired once. This method can be used if a Process is about to be
1416         * terminated.
1417         * 
1418         * public void takeBackAll () { where = "void takeBackAll ()";
1419         * 
1420         * int n = 0; // how many resources will be taken back
1421         * 
1422         * Sim-process currentProcess = currentSimProcess();
1423         * 
1424         * if (!checkProcess(currentProcess, where)) //check the current process {
1425         * return; } // if it is not valid just return // delete the entry of the
1426         * currentSimProcess in the arrayOfUsedResources // search the whole vector
1427         * for ( int i = 0; i < arrayOfUsedResources.size(); i++) { // get hold of
1428         * the UsedResources pair (SimProcess/number of resources) UsedResources
1429         * procHoldRes = (UsedResources)arrayOfUsedResources.elementAt(i);
1430         * 
1431         * if (procHoldRes.getProcess() == currentProcess) { // number of resources
1432         * held by the currentProcess n = procHoldRes.getOccupiedResources ();
1433         * 
1434         * arrayOfUsedResources.removeElementAt(i); // delete the entry } } // end
1435         * for
1436         * 
1437         * updateStatistics ( n ); // statistics will be updated
1438         * 
1439         * users++; // update users // tell in the trace that the process is
1440         * releasing all its resources if ( traceIsOn() ) { sendTraceNote (
1441         * "releases all its " + n + " " + this.getName() ); }
1442         * 
1443         * activateNext(); // give waiting process in the queue a chance }
1444         */
1445 
1446        /**
1447         * Updates the arrayOfUsedResources for this Res whenever resources are
1448         * <code>provided</code>.
1449         * 
1450         * @param crntProcess
1451         *            SimProcess : The current SimProcess acquiring resources.
1452         * @param providedRes
1453         *            Resource[] : The array of resources the Res is providing to
1454         *            the current SimProcess.
1455         */
1456        protected void updateProvidedRes(SimProcess crntProcess,
1457                        Resource[] providedRes) {
1458                // is the sim-process already holding resources?
1459                boolean holdsResources = false; // not yet
1460 
1461                // search the whole vector
1462                for (int i = 0; i < _arrayOfUsedResources.size(); i++) {
1463                        // get hold of the UsedResources pair (SimProcess/number of
1464                        // resources)
1465                        UsedResources procHoldRes = _arrayOfUsedResources.elementAt(i);
1466 
1467                        // is the sim-process already holding resources?
1468                        if (procHoldRes.getProcess() == crntProcess) {
1469                                // update the held resources of the current SimProcess
1470                                for (int j = 0; j < providedRes.length; j++) {
1471                                        procHoldRes.getOccupiedResources().addElement(
1472                                                        providedRes[j]);
1473                                }
1474 
1475                                holdsResources = true; // the sim-process already holds
1476                                // resources
1477                        } // end if
1478                } // end for
1479 
1480                if (!holdsResources) // the process does not hold any resources yet
1481                {
1482                        // make a new Vector
1483                        Vector<Resource> occupiedRes = new Vector<Resource>();
1484 
1485                        // copy all elements of the array to the Vector
1486                        for (int i = 0; i < providedRes.length; i++) {
1487                                occupiedRes.addElement(providedRes[i]);
1488                        }
1489 
1490                        // construct a new UsedResources object with the Vector
1491                        UsedResources ur = new UsedResources(crntProcess, occupiedRes);
1492 
1493                        // put ur in the arrayOfUsedResources
1494                        _arrayOfUsedResources.addElement(ur);
1495                }
1496        }
1497 
1498        /**
1499         * Updates the statistics for the Res whenever resources are
1500         * <code>provided</code> or <code>"takenBack"</code>.
1501         * 
1502         * @param n
1503         *            int : Is positive when the Res <code>takeBack()</code>
1504         *            resources and negative when the Res <code>provides()</code>
1505         *            resources.
1506         */
1507        protected void updateStatistics(int n) {
1508                TimeInstant now = presentTime();
1509 
1510                _wSumAvail = _wSumAvail
1511                                + ((double) _avail * TimeOperations.diff(now, _lastUsage)
1512                                                .getTimeInEpsilon());
1513                _lastUsage = now;
1514 
1515                _avail += n; // n can be positive or negative (remember ?!)
1516 
1517                if (_avail < _minimum) // update minimum, if necessary
1518                {
1519                        _minimum = _avail;
1520                }
1521        }
1522 
1523        /**
1524         * Updates the arrayOfUsedResources for this Res whenever resources are
1525         * taken back.
1526         * 
1527         * @param crntProcess
1528         *            SimProcess : The current SimProcess releasing resources.
1529         * @param returnedRes
1530         *            Resource[] : The array of resources the Res will take back
1531         *            from the current SimProcess.
1532         */
1533        protected void updateTakenBackRes(SimProcess crntProcess,
1534                        Resource[] returnedRes) {
1535                // search the whole vector
1536                for (int i = 0; i < _arrayOfUsedResources.size(); i++) {
1537                        // get hold of the UsedResources pair (SimProcess/number of
1538                        // resources)
1539                        UsedResources procHoldRes = _arrayOfUsedResources.elementAt(i);
1540 
1541                        if (procHoldRes.getProcess() == crntProcess) {
1542                                // remove the resources from the Vector of used resources
1543                                for (int j = 0; j < returnedRes.length; j++) {
1544                                        procHoldRes.getOccupiedResources().removeElement(
1545                                                        returnedRes[j]);
1546                                }
1547 
1548                                // are all resources from this SimProcess taken back
1549                                if (procHoldRes.getOccupiedResources().isEmpty()) {
1550                                        _arrayOfUsedResources.removeElementAt(i);
1551                                }
1552                        } // end if
1553                } // end for
1554        }
1555} // end class Res

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