|
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
- 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 csim_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 csim_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
|