On this page:
7.1 The resource Structure
resource
make-resource
7.1.1 Shortcuts to Resource Set Variables
resource-queue-variable-n
resource-satisfied-variable-n
7.2 Requesting and Relinquishing Resources
7.2.1 Requesting Resources
request
resource-request
7.2.2 Relinquishing Resources
relinquish
resource-relinquish
7.2.3 The with-resource Macro
with-resource
7.3 Example—Resources

7 Resources

    7.1 The resource Structure

      7.1.1 Shortcuts to Resource Set Variables

    7.2 Requesting and Relinquishing Resources

      7.2.1 Requesting Resources

      7.2.2 Relinquishing Resources

      7.2.3 The with-resource Macro

    7.3 Example—Resources

In a simulation model, a resource represents an entity (or entities) that is/are shared among processes. Each resource has a quantity associated with it that represents the number of (indivisible) units for the resource.

7.1 The resource Structure

(struct resource (units
    units-available
    units-allocated
    satisfied
    queue)
  #:mutable)
  units : exact-positive-integer?
  units-available : exact-nonnegative-integer?
  units-allocated : exact-nonnegative-integer?
  satisfied : set?
  queue : set?
Represents a resource, possibly with multiple allocatable units, in a resource model. When there are insufficient units available to fulfull a resource request, the request is queues until the number of units requested are available. The queued request may include a priority and the process may reneg on the request based on time or the occurance of a specific event.
  • unitsthe total number of units of the resource.

  • units-availablethe number of units of the resource that are currently available, that is, are not currently allocated.

  • units-allocatedthe number of units of the resource that are currently allocated.

  • satisfieda set of resource allocations that are currently satisfied.

  • queuea set of resource allocations yet to be satisfied.

(make-resource [units])  resource?
  units : exact-positive-integer? = 1
Returns a newly created resource instance with the specified number of units. If units is not specified, 1 is used. The units-available field is set to units, the units-allocated field is set to 0, and the satisfied and queue sets are empty.

7.1.1 Shortcuts to Resource Set Variables

The resource structure includes two sets to implement the queues of satisfied allocations, the satisfied field, and the waiting allocatons, the queue field. The following functions provide access to the n field of the respective sets to facilitate data collection. See Chapter 9, Sets for more details.

(resource-queue-variable-n resource)  variable?
  resource : resource?
Returns the variable from the n field of the set in the queue field of resource.

(resource-satisfied-variable-n resource)  variable?
  resource : resource?
Returns the variable from the n field of the set in the satisfied field of resource.

7.2 Requesting and Relinquishing Resources

7.2.1 Requesting Resources

(request resource #:units (units 1)
                  #:priority (priority 100))
(request resource #:units (units 1)
                  #:priority (priority 100)
                  #:leave #:now)
(request resource #:units (units 1)
                  #:priority (priority 100)
                  #:leave #:at time)
(request resource #:units (units 1)
                  #:priority (priority 100)
                  #:leave #:in delta)
(request resource #:units (units 1)
                  #:priority (priority 100)
                  #:leave #:when event)
(request resource #:units (units 1)
                  #:priority (priority 100)
                  #:leave time)
Requests the specified number of units of resource. If the requested number of units are not available, the request is places in the queue of waiting allocations, in the queue field, with the specified priority. The process requesting the resource(s) will delay until the resource(s) are available and allocated to the process. It is an error ro request more units of a resource than exist.

The process may reneg on the request by using the #:leave keyword. The options for the #:leave keyword are the same as for the schedule macro. Note that specifying #:leave #:in 0.0 will reneg at the current time, but will allow all now events to be executed, which may relinquish the resource(s) required. This is not the same as specifying #:leave #:now, which will reneg immediately, and may be more appropriate than checking the units-available field.

(resource-request resource    
  [units    
  priority    
  reneg])  any
  resource : resource?
  units : exact-positive-integer? = 1
  priority : real? = 0
  reneg : any/c = #f
Functional equivalent to the request macro, which should be used instead. This is used in legacy code to request resources.

7.2.2 Relinquishing Resources

(relinquish resource #:units units)
(relinquish resource)
Relinquishes the specified number of units of resource. If the number of units to relinquish is not specified, then all of the units allocated to the process are released. It is an error to attempt to relinquish more units that the process has allocated.

(resource-relinquish resource units)  any
  resource : resource?
  units : exact-positive-integer?
(resource-relinquish resource)  any
  resource : resource?
Functional equivalent to the relinquish macro, which should be used instead. This is used in legacy code to request resources.

7.2.3 The with-resource Macro

(with-resource (resource units)
   body ...+)
(with-resource (resource)
   body ...+)
Evaluates the body expressions with the specified number of units of resource.

Since the sequence

(request resource #:units units)
...
(relinquish resource)

is by far the most frequent usage of request and relinquish, the with-resource macro is provided to simplify this common usage.

7.3 Example—Resources

This example extends the simple simulation model of Chapters 5 and 6 by adding attendents to the system. Each customer must interact with an attendant. The two attendants are modeled using a single resource with two units. This means there is a single queue for the two attendants. Again, the output is a simple trace of customer arrivals, attendant acquisitions, and departures.

#lang racket/base
; Example 2 - Resources
 
(require (planet williams/simulation/simulation))
 
(define n-attendants 2)
(define attendant #f)
 
(define (generator n)
  (for ((i (in-range n)))
    (wait (random-exponential 4.0))
    (schedule #:now (customer i))))
 
(define-process (customer i)
  (printf "~a: customer ~a enters~n" (current-simulation-time) i)
  (request attendant)
  (printf "~a: customer ~a gets an attendant~n" (current-simulation-time) i)
  (work (random-flat 2.0 10.0))
  (relinquish attendant)
  (printf "~a: customer ~a leaves~n" (current-simulation-time) i))
 
(define (run-simulation n)
  (with-new-simulation-environment
   (set! attendant (make-resource n-attendants))
   (schedule #:at 0.0 (generator n))
   (start-simulation)))
 
(run-simulation 10)

Produces the following output.

0.6153910608822503: customer 0 enters

0.6153910608822503: customer 0 gets an attendant

5.599485116393393: customer 1 enters

5.599485116393393: customer 1 gets an attendant

6.411843645405005: customer 2 enters

8.48917994426752: customer 0 leaves

8.48917994426752: customer 2 gets an attendant

10.275428842274628: customer 1 leaves

16.82673428503317: customer 2 leaves

23.525886616767437: customer 3 enters

23.525886616767437: customer 3 gets an attendant

27.18604340910279: customer 3 leaves

32.1644631797164: customer 4 enters

32.1644631797164: customer 4 gets an attendant

33.14558760001698: customer 5 enters

33.14558760001698: customer 5 gets an attendant

39.67682614849173: customer 4 leaves

40.486553934113665: customer 6 enters

40.486553934113665: customer 6 gets an attendant

41.168084930967424: customer 5 leaves

45.72670063299798: customer 6 leaves

46.747675912143016: customer 7 enters

46.747675912143016: customer 7 gets an attendant

49.212327970772435: customer 8 enters

49.212327970772435: customer 8 gets an attendant

50.556538752352886: customer 9 enters

51.46738784004611: customer 8 leaves

51.46738784004611: customer 9 gets an attendant

52.514846525674855: customer 7 leaves

57.02720211166597: customer 9 leaves

The attendant is declared as a global variable. The actual resource is created (and assigned to the global variable) in run-simulation. The actual usage, the request and relinquish calls, are in the customer process.

A few things to note at this point are: