Processes represent the active entities
in a CSIM model. For example, in a model
of a bank, customers might be modeled
as processes (and tellers as facilities).
In CSIM, a process is a C procedure
which executes a create
statement. A CSIM process should not
be confused with a UNIX process (which
is an entirely different thing). The
create statement is similar to a UNIX
"fork" statement. A process
can be invoked with input arguments,
but it cannot return a value to the
invoking process.
There can be several simultaneously
"active" instances of the
same process. Each of these instances
appears to be executing in parallel
(in simulated time) even though they
are in fact executing sequentially on
a single processor. The CSIM runtime
package guarantees that each instance
of every process has its own runtime
environment. This environment includes
local (automatic) variables and input
arguments. All processes have access
to the global variables of a program.
A CSIM process, just like a real process,
can be in one of four states:
-
Actively computing
-
Ready to begin
computing
-
Holding (allowing
simulated time to pass)
-
Waiting for an
event to happen (or a facility to
become available, etc.)
When an instance of
a process terminates, either explicitly
or via a procedure exit, it is deleted
from the CSIM system. Each process has
a unique process id and each has a priority
associated with it.
In CSIM, a process is a procedure which
executes a create statement; a process
is initiated (invoked, started,
)
by executing a standard procedure call:
Prototype:
void proc(arg1, ..., argn);
Example:
my_proc(a, 64,
"label");
In some cases, the process initiator requires
the id of the initiated process. In these
cases, the prototype and example appear
as follows:
Prototype:
long proc(arg1,
. . ., argn);
Example: proc_id
= my_proc(a, 32, "label");
Caution:
It is bad practice to pass the address
of a local variable to a CSIM process
as an input argument.
Caution:
A process cannot return a function value.
Caution:
A create statement (see below) must appear
in the initiated process.
As stated above, a CSIM process is a procedure
which executes the create
statement:
Prototype:
void create(char*
name)
Example:
create("customer");
The name of a process is just a character
string which is used to identify the process
in event traces and reports generated
by CSIM. Typically, the create
statement is executed at the beginning
of a process. Each instance of a process
is given a unique process id (process
id's are not reused). Processes can invoke
procedures and functions in any manner.
Processes can also initiate other processes.
When a procedure executes its create
statement, the following actions take
place:
-
The process executing
the create
statement (the called process) is
established and is made "ready
to execute" at the statement
following the create statement, and
-
The calling process
continues its execution (i.e.,
it remains the actively computing
process) at the statement after the
procedure call to the called process.
The calling process continues as the
active process until it suspends itself.
No simulated time passes during the
execution of a create statement.
Note:
process id's are 32 bit integers; if
231-1 id's are used, the
sequence of id's is reset to 2.
Processes appear to operate simultaneously
with other active processes at the same
points in simulated time. The CSIM process
manager creates this illusion by starting
and suspending processes as time advances
and as events occur. Processes execute
until they "'suspend" themselves
by doing one of the following actions:
-
execute a hold
statement (delay for a specified interval
of time),
-
execute a statement
which causes the processes to be placed
in a queue, or
-
csim_terminate.
Processes are restarted when the time
specified in a hold
statement elapses or when a delay in
a queue ends. It should be noted that
simulated time passes only by the execution
of hold
statements. While a process is actively
computing, no simulated time passes.
The process manager preserves the correct
context for each instance of every process.
In particular, separate versions of
all local variables (variables resident
in the runtime stack frame) and input
arguments for a process are maintained.
CSIM accomplishes this by saving and
restoring process contexts (segments
of the runtime stack) as processes suspend
themselves and as processes are "resumed"
(restored). A consequence of this kind
of operation is that if one processes
passes an address of a local variable
to another process, it is likely that
when this address is referenced, the
reference will be invalid. The reason
is that when a process is not actually
computing (using the real CPU), its
stack frame with the local variables
will not be physically located in the
correct place in memory. This is not
a major obstacle to writing efficient
and useful models; it is a detail which
must be remembered as CSIM models are
developed.
A process terminates when it either
does a normal procedure exit or when
it executes a terminate
statement.
Prototype:
void csim_terminate(void)
Example:
csim_terminate();
The normal case is for a process to
do a normal procedure exit or return.
The terminate
statement is provided when this normal
case is not appropriate.
The initial priority of a process is
inherited from the initiator of that
process. For the sim (main) process,
the default priority is 1 (low priority).
Prototype:
void set_priority(long
new_priority)
Example:
set_priority(5);
This statement must appear after the
create statement in a process. Lower
values represent lower priorities (i.e.
priority 1 processes will run later
than priority 2 processes when priority
is a consideration in order of execution
(see
section 4.11, "Changing the
Service Discipline at a Facility").
These functions each return some information
to the process issuing the statement.
The type of the returned value for each
of these functions is as indicated.
| Prototype: |
Functional
Value: |
| char* process_name(void) |
retrieves pointer
to name of process
issuing inquiry |
| long identity(void) |
retrieves the
identifier (process
number) of process issuing the
inquiry |
| long priority(void) |
retrieves the
priority of process
issuing inquiry |
To print the status of each active process
in a model:
Prototype:
void status_processes(void)
Example:
status_processes();
To print the status of processes with
pending state changes (the "next
event list"):
Prototype:
void status_next_event_list(void)
Example:
status_next_event_list();
These reports will be written to the
default output location or to that specified
by set_output_file
(see
section 21.6, "Output
File Selection").
Next Section
|
|