FACILITIES
A facility is normally used to model a resource (something a process requests service from) in a simulated
system. For example, in a model of a computer system, a CPU and a disk drive might both be modeled by
CSIM facilities. A simple facility consists of a single server and a single queue (for processes waiting to gain
access to the server). Only one process at a time can be using a server. A multi-server facility contains a
single queue and multiple servers. All of the waiting processes are placed in a queue until one of the servers
becomes available. A facility set is an array of simple facilities; in essence, a facility set consists of multiple
single server facilities, each with its own queue.
Normally, processes are ordered in a facility queue by their priority (a higher priority process is ahead of a
lower priority process). In cases of ties in priorities, the order is first-come, first-served (fcfs). An fcfs facility
can be designated as a synchronous facility. Each synchronous facility has its own clock with a period and a
phase and all reserve operations are delayed until the onset of the next clock cycle. Service disciplines other
than priority order can be established for a server. These are described in “
Service Disciplines” on page 9.
A set of usage and queueing statistics is automatically maintained for each facility in a model. The statistics for
all facilities which have been used are "printed" when either a report or a report_facilities is executed (see
“CSIM Report Output” on page 45 for details about the reports that are generated). In addition, there is a set of
functions that can be used to extract individual statistics for each facility.
Declaring and Initializing Facilities
Facilities should be declared with global variables and initialized in the sim (main) process prior to the
beginning of the simulation part of the model. Unless changed by a set_servicefunc statement (see “
Service Disciplines” on page 9), the scheduling policy of the facility will be first-come, first served (fcfs).
To declare a facility:
FACILITY f;
FACILITY array[n];
Where:
f - is the variable name representing the facility (type FACILITY)
array - is the variable name representing the set of facilities (array of type FACILITY)
n - is the number of facilities in the facility set (type long). Only single server facilities can be in a facility
set.
Notes:
A facility must be initialized via the facility, facility_ms, or facility_set statement before it can be used in any
other statement.
To initialize a single server facility or a set of single server facilities:
f = facility("name");
facility_set(array, "name", n);
Where:
f - is the variable name representing the single server facility (type FACILITY)
array - is the variable name representing the set of single service facilities (array of type FACILITY)
name - is the name of the single server facility or set of single server facilities (quoted string or type char*)
n - is the number of facilities in the facility set (type long)
Notes:
The i-th facility in a facility set is named "name[i]".
The pointer to the i-th facility is stored at array[i].
The facilities in the set are indexed 0 through n-1.MBR>
name is used only for output (reports, status, traces).
To initialize a multi-server facility:
f = facility_ms("name", num_servers);
Where:
f - is the variable name representing the multi-server facility (type FACILITY)
name - is the name of the multi-server facility (quoted string or type char*)
num_servers - is the number of servers (type long)
Notes:
name is used only for output (reports, status, traces).
To change the name of a facility:
set_name_facility(f,” name”);
Where:
f - is the facility or facility set whose name is to be changed (type FACILITY)
Notes:
name is used only for output (reports, status, traces).
Collecting Facility Information
Information about usage of a facility can be collected for all facilities or for a specific facility.
To collect usage information for a specific facility:
collect_class_facility(f);
Where:
f - is the facility for which information is to be collected
Notes:
Usage of this facility by all process classes (see ”PROCESS CLASSES” on page 34) to be reported in the
facilities report.
It is an error to change the maximum number of classes allowed after this statement has been executed.
To collect usage information for all facilities:
collect_class_facility_all();
Notes:
This applies to all of the facilities in existence when this statement is executed.
Usage of the facilities by all process classes (see ”PROCESS CLASSES” on page 34) will be reported in
the facilities report.
It is an error to change the maximum number of classes allowed after this statement has been executed.
Deleting Facilities
To delete a facility or a facility set:
delete_facility(f);
delete_facility_set(array);
Where:
f - is the facility to be deleted (type FACILITY)
array - is the facility set to be deleted (array of type FACILITY)
Notes:
Deleting a facility or facility set is an extreme action and should be done only when really needed.
Using Facilities
To reserve a facility:
server_num = reserve(f);
Where:
f - is the facility at which a server is to be reserved (type FACILITY)
server_num - is the index of the server assigned
Notes:
Operation of reserve:
- If a server at the facility f is available, it is reserved for this process. The process then continues
execution.
- If all servers at the facility are already reserved by other processes, this process is suspended until a
server at the facility is released.
Suspended processes are granted access to the facility one-at-a-time in the order dictated by the
priorities. In case of a tie in priorities, the most recent process goes behind processes which arrived
earlier, making first-come, first-served the "default" scheduling rule
If the facility has more than one server, then the first available (free) server is assigned to the highest
priority process.
Reserve only works with the process selection mechanism described above. To use another service
discipline, use the use statement (see below).
To reserve a facility with a limit on the length of time the process is willing to wait for the
facility:
server_num = timed_reserve(f, time);
Where:
f - is the facility at which a server is to be reserved (type FACILITY)
time - is the maximum time that the process will wait to obtain the facility (type double)
server_num - is the index of the server assigned or a value of TIMED_OUT if the facility could not be
obtained within the specified time (type long)
Notes:
The process must check the returned value (server_num) to determine whether the facility was obtained.
To release a facility that has been reserved (and in use) by a process, but is no longer
needed:
release(f);
Where:
f - is the facility to be released (type FACILITY)
Notes:
Operation of release:
If there are processes waiting for access to the facility, the process of highest priority is given access to
the facility and then restarted.
The process which reserved this facility must also be the process doing the release.
To release a specific server at a facility:
release_server(f, server_num);
Where:
f - is the facility to be released (type FACILITY)
server_num - is the index of the server to be released (type long). This is the number that was returned by
the reserve statement.
Notes:
This operates in the same way as the release statement.
In contrast to the release statement, the ownership of the server is not checked, so a process which did not
reserve the facility may release it using the release_server statement with a server index.
To use a facility for a specified time interval:
use(f, time);
Where:
f - is the facility to be used (type FACILITY)
time - is the length of time that the process will use the facility (type double)
Notes:
A use statement is similar to a reserve, followed by a hold and a release, in that it acquires a server, allows
simulated time to pass and then releases the server. The differences are that with use:
These all become one atomic operation
Any service discipline can be used (see the set_servicefunc statement in “
Service Disciplines” on page 9)
Service Disciplines
The service discipline for a facility determines the order in which processes at the facility are given access to
that facility. If not otherwise specified, the service discipline for a facility is fcfs:
Where the priorities differ, processes gain access in priority order (higher priority processes before lower
priority processes)
Within processes with the same priority, the processes gain access in the order of their arrival
at the facility (first come, first served)
To change the service discipline:
set_servicefunc(f, discipline);
Where:
f - is the facility whose service discipline is to be set (type FACILITY)
func - is the function which is invoked when the use statement (described above) references this facility.
func can be any of the following pre-defined service discipline functions:
- fcfs - first come, first served
This is the default service discipline and is described in the introduction to this section. If the
synchronous_facility statement (see below) is used for this facility, this will behave like a fcfs_sy (clock
synchronized fcfs) facility. In other words, there are two ways for a facility to become synchronized:
specifying the service discipline of fcfs_sy or specifying (or defaulting) fcfs for the service discipline and
using the synchronous_facility statement.
- fcfs_sy - first come, first served, clock synchronized
This is the same as fcfs except that requests can be satisfied only at the beginning of a clock cycle. If
not otherwise specified (via synchronous_facility below), the clock phase (time to onset of first clock
cycle) will be 0.0, and the period (length of a clock cycle) will be 1.0.
- inf_srv - infinite servers
There is no queueing delay at all since there is always a server available at the facility.
- lcfs_pr - last come, first served, preempt
Arriving processes are always serviced immediately, preempting a process that is currently being
served if necessary. Priority is not a consideration with this service discipline.
- prc_shr - processor sharing
This is load-dependent processor sharing. Service times for each process are determined based on
the number of processes at the facility. If not otherwise specified (see set_loaddep below), it will be
assumed that the rate that applies when there are n processes at the facility is n (in other words, if
there are n processes at the facility, the service time will be multiplied by n). The altered service times
are recomputed as tasks arrive at and leave the facility. There is no queueing delay with processor
sharing since the assumption is that the server works faster and faster as necessary to service all
processes that request it.
There can be a maximum of 100 processes sharing a prc_shr facility.
- pre_res - preempt resume
Higher priority processes will preempt lower priority processes, so that the highest priority process at
the facility will always finish using it first. Where the priorities are the same, processes will be served
on a first come, first served basis.
- rnd_pri - round robin with priority
Higher priority processes will be served first. When there is are multiple processes with the same
priority, they will be serviced on a round robin basis, with each getting the amount of time specified in
set_timeslice (see below) before being preempted by the next process of the same priority.
- rnd_rob - round robin
Processes will be serviced on a round robin basis, with each getting the amount of time specified in
set_timeslice (see below) before being preempted by the next process requiring service.
Notes:
The use statement (as opposed to the reserve) statement must be used for most service disciplines to be
effective. Only fcfs and fcfs_sy will operate properly with reserve.
This statement allows the modeling of different service disciplines which govern use of the facility.
To set the clock information for the fcfs or fcfs_sy (see above) service discipline:
synchronous_facility(f, phase, period);
Where:
f - is the facility to which this clock information applies (type FACILITY)
phase - is the time to the onset of the first clock cycle. (type double)
period - is the length of each clock cycle (type double)
Notes:
A clock-synchronized facility allows requests to be satisfied only at the beginning of a clock cycle.
To set the load dependent service rate for the prc_shr (see above) service discipline:
set_loaddep(f, rate, n);
Where:
f - is the facility to which this clock information applies (type FACILITY)
rate - is an array of rates based on the number of processes at the facility (type double*). rate[i] is the
amount by which the service time is multiplied when there are i processes at the facility
n is the number of entries in the rate array
Notes:
If n is less than the 100 (the maximum number of processes allowed to share a prc_shr facility), then the
value of the last specified rate is replicated until 100 values are available.
If n is greater than 99, only 100 values will be used.
The altered service times are recomputed as tasks arrive at and leave the facility.
To set the time slice for the round robin service disciplines, rnd_pri and rnd_rob (see above):
set_timeslice(f, time);
Where:
f - is the facility to which this time slice information applies (type FACILITY)
time - is the amount of time in each time slice (type double)
Retrieving Facility-Related Information
These functions each return a statistic which describes some aspect of the usage of the specified facility. The
type of the returned value for each of these functions is as indicated. The syntax conventions for these
statements are as follows:
f - is the facility about which information is requested. It must be type FACILITY.
i - is the server of the facility about which information is requested. It must be type long.
c - is the process class about which information for the facility is requested. It must be type CLASS. For
more information about process classes, see “PROCESS CLASSES” on page 34.
a - is a returned value of type char*.
n is a returned value of type long.
x - is a returned value of type double.
Retrieving Static Facility Information
Statement Returned Value
a = facility_name(f); pointer to name of facility f
n = num_servers(f); number of servers at facility f
a = service_disp(f); pointer to name of service discipline at facility f
x = timeslice(f) time in each time slice for facility f (which has a round robin protocol)
Retrieving Facility Status Information
Statement Returned Value
n = num_busy(f) number of servers currently busy at facility f
n = qlength(f) number of processes currently waiting at facility f
n = status(f) current status of facility f:
BUSY if all servers are in use
FREE if at least one server is not in use
Notes:
num_busy(f) + qlength(f) = the number of processes currently at facility f
Retrieving Facility Summary Information
Statement Returned Value
n = completions(f); number of completions at facility f
n = preempts(f); number of preempted requests at facility f
x = qlen(f); mean queue length at facility f
x = resp(f); mean response time at facility f
x = serv(f); mean service time at facility f
x = tput(f); mean throughput rate at facility f
x = util(f); utilization (% of time busy) at facility f
Retrieving Server Summary Information
Statement Returned Value
n = server_completions(f, i); number of completions for server i at facility f
x = server_serv(f, i); mean service time for server i at facility f
x = server_tput(f, i); mean throughput rate for server i at facility f
x = server_util(f, i); utilization for server i at facility f
Retrieving Facility Summary Information by Process Class
Statement Returned Value
n = class_completions(f, c); number of completions for class c at facility f
x = class_qlen(f, c); mean queue length for class c at facility f
x = class_resp(f, c); mean response time for class c at facility f
x = class_serv(f, c); mean service time for class c at facility f
x = class_tput(f, c); mean throughput rate for class c at facility f
x = class_util(f, c); utilization for class c at facility f
Reporting Facility Status
To print the status of each facility in the model:
status_facilities();
Notes:
This report lists each facility along with:
The number of servers
The number of servers which are busy
The number of processes waiting
The name and id of each process at a server
The name and id of each process in the queue
The report will be written to the default output location or to that specified by set_output_file