Synchronization by Resources

by Lin Jensen, Bishop's University

written in Turbo Pascal 6.0 or 7.0

The simulation toolboxes provide processes in the
units: COPROC, PROC_MAN, (and MESSAGE)

This is the documentation for UNIT RESOURCE


A resource has a capacity, and can be acquired and released by processes. It reports on its utilization (like a "server"), and possesses a semaphore queue at which processes await its availability.

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.


These are the method declarations of particular interest:
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;

A resource is initialized with a particular capacity, so many units. It is then available to be acquired, and released by processes that have acquired it. If more than one unit is to be acquired, the process may keep waiting while other processes come along and keep the resource busy. This will model possible "starvation". You can guard against this, and make acquiring strictly FIFO by using an additional semaphore to allow only one process at a time to try to acquire.

Since a resource can become unavailable, there are two ways to acquire:

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}

Last updated 20 November 1996

Up to top of this document
Back to Simulation toolboxes.
Back to Simulation notes. home arrow

Comments, etc, send to

ljensenn at ubishops.ca