This is the documentation for UNIT RESOURCE
A resource can be made "unavailable" by another process, which should be reflected in the usage report. This raises questions: What about processes which are currently using? What about waiting processes? ( GPSS allows several options, from orderly leaving to abruptly sending other transactions off.)
Availability is implemented for servers in QNETOBJ. There the only option is to allow services to finish, but allow no new starts after a MakeUnavailable request. The status of the server actually changes from "busy" to "unavailable" when the last service finishes. This is brought forward here to resources.
Two methods for acquiring (seizing) resources are implemented here. ACQUIRE doggedly waits for the resource. AcquireIfAvailable comes back with FALSE if the resource is unavailable or becomes so.
THIS IMPLEMENTATION (Nov. 19) looks in its queue for the first process that can acquire all its requested units. It is up to the programmer using resources to beware of "starvation" of processes that demand larger number of units, because smaller requests can keep the resource occupied.
aResource = object (aSimObject) constructor Init ( capacityP : INTEGER); procedure Acquire ( howMuch : INTEGER); {will wait even for unavailable res. Can test, or use the following:} function AcquireIfAvailable ( howMuch : INTEGER): BOOLEAN; {returns FALSE immediately if the resource is UNAVAILABLE (eg. broken)} procedure Release ( howMuch : INTEGER); {A broken machine or absent store clerk is UNAVAILABLE} procedure MakeUnAvailable; procedure MakeAvailable; function NotAvailable : boolean; {is it currently unavailable to seize?} function QueueLength : integer; {length of waitqueue, negative for available capacity} {irrespective of "availability", use function NotAvailable if necessary} end;
Since a resource can become unavailable, there are two ways to acquire:
bridge.acquire(1); Sleep_for (transitTime.Normal); bridge.release(1);
if Teller[shortest].AcquireIfAvailable (1) then begin Sleep_for (Service.NegExp + Service.NegExp); {2-Erlang} Teller[shortest].release (1); end else Frustrated.Update; {record frustrated customer}
Another process can make a resource unavailable. If the resource
is currently busy, services are allowed to finish, but no new
services will start. The resource becomes truely "Unavailable"
after all services have finished. Accordingly, the process
calling MakeUnavailable
will be suspended
until this happens. That is so it can properly schedule the time
it takes to restore service. For example, a drawbridge cannot be
opened until it is free of traffic, then it still takes a certain
amount of time to raise it and let a ship pass under. Example:
bridge.MakeUnavailable; {wait for it to clear} Sleep_for (shippassage.Normal); bridge.MakeAvailable; {cars can use again}
Up to top of this document
Back to Simulation toolboxes.
Back to Simulation notes.
Comments, etc, send to
ljensenn at ubishops.ca