Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: desmoj/Res.java


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