MISCELLANEOUS
Simulated Time
A simulation model keeps track of time that passes during execution of the model. Time, for simulation
purposes, is merely simulated, so CSIM keeps information about how much simulated time has passed and
what the current simulated time is.
To tell CSIM that a given amount of simulated time should pass:
hold(t);
Where:
t - is the amount of simulated time that must pass before the process will continue (type double)
Notes:
The process will be suspended for time t.
This statement and the use statement are the only ways to cause simulated time to pass.
To retrieve the amount of simulated time that has passed thus far in the execution of the
model:
t = clock;
t = simtime();
Where:
t - is the amount of simulated time that has passed (the current simulated time) (type TIME)
Notes:
The two statements are equivalent and yield identical results.
clock is declared in the “csim.h” include file.
TIME is defined in “csim.h”. It is of type double.
Real Time
Although, internally, the model only deals with simulated time, the running of the model takes place in real time.
To retrieve the current real time:
cur_time = time_of_day();
Where:
cur_time - is the actual time of day (type char*)
Notes:
The format of the returned string is:
day mm dd hh:mm:ss yyyy, for example, Sun Jun 05 13:22:43 1994 for Sunday, June 5, 1994 at 1:22:43
PM
To retrieve the amount of CPU time used by the model:
t = cputime();
Where:
t - is the amount of CPU time, in seconds, that has been consumed by the model thus far (type double)
Retrieving and Setting Limits
There is a maximum number of each kind of CSIM data object in a CSIM program. These maximums can be
interrogated and/or changed. The maximums serve as limits on the number of structures of a particular type
which exist simultaneously
To retrieve or change a CSIM maximum:
The syntax conventions for these statements are as follows:
i - is the returned maximum allowed value for the number of objects of the given type which may exist
simultaneously in the model. If this statement changed the value, i will contain the new value. It must be
type long.
n - is of type long. It is either:
Zero - in which case this is strictly an information retrieval request
Non-zero - in which case the maximum will be changed to n
Function name Default value Meaning
i = max_classes(n); 5 Maximum number of process classes
i = max_events(n); 100 Maximum number of events
i = max_facilities(n); 100 Maximum number of facilities
i = max_histograms(n); 10 Maximum number of histograms (*see notes)
i = max_mailboxes(n); 50 Maximum number of mailboxes
i = max_messages(n); 1000 Maximum number of messages (for mailboxes)
i = max_processes(n); 1000 Maximum number of processes
i = max_qtables(n); 10 Maximum number of qtables
i = max_servers(n); 200 Maximum number of servers (for facilities)
i = max_sizehist(n); 1000 Maximum size of a histogram
i = max_storages(n); 20 Maximum number of storage blocks
i = max_tables(n); 20 Maximum number of tables (*see notes)
Notes:
The maximums apply to objects which have been both declared and initialized (and not deleted).
Since a histogram creates table, the number of active histograms + active tables cannot exceed the limit
for tables.
Because each mailbox includes an event, the maximum number of events must include at least one event
per mailbox. Therefore, if the maximum number of mailboxes is increased, it is likely that the maximum
number of events must also be increased.
It is an error to change the maximum number of classes after a collect_class_... statement has been
executed.
Creating a CSIM Program
There are two distinct ways of writing CSIM programs:
Write a routine named sim() (the standard approach). This will cause CSIM to do the following:
Generate the main() routine “under the covers”
Perform necessary initialization
Process the command line
Call sim() with argc and argv repositioned to point to the non-CSIM arguments
Provide the main() routine yourself. This allows you to imbed the CSIM model in a surrounding tool. To do
this:
Call sim() (or any routine) which becomes the first (base) CSIM process when it executes a create
statement
Call proc_csim_args to process the CSIM command line arguments (if desired)
Call conclude_csim when the simulation model part of the program is complete
To process CSIM input parameters from a user-provided main() routine:
proc_csim_args(&argc, &argv);
Where:
argc and argv are the standard C arguments.
Notes:
On return, any CSIM arguments have been processed (currently the only CSIM argument is -T (to turn on
tracing) and argc and argv have been modified to point to any remaining arguments.
To cause CSIM to perform it necessary cleanup when using a user-provided main() routine:
conclude_csim();
Notes:
If a model is to be rerun, then the rerun statement should be executed.
Rerunning or Resetting a CSIM Model
It may be useful to run a model multiple times with different values, or run multiple models in the same
program.
To rerun a CSIM model:
rerun();
Notes:
rerun will cause the following to occur:
All non-permanent tables structures are cleared.
All processes are eliminated
All facilities, events, mailboxes, process classes, storage blocks, tables and qtables established before
the first create statement (the create for the first ("sim") process) are reinitialized
All remaining facilities, storage blocks, events, etc., are eliminated
The clock is set to zero
The following are NOT reset or cleared:
The random number generator (issue a reset_prob(1) to reset the random number stream)
Permanent tables structures
Special provisions are required for C++ programs with static objects which are constructed before the
program begins execution.
To clear statistics without rerunning the model:
reset();
Notes:
reset will cause the following to occur:
All statistics for facilities and storage blocks are cleared.
All non-permanent table structures are cleared
the global variable _start_tm is set to the current time and is used as the starting point for calculations
All remaining facilities, storage blocks, events, etc., are eliminated
The simulated time clock is set to zero
The variable clock is not altered.
Time intervals for facilities, storage blocks and qtables which began before the reset are tabulated in their
entirety if they end after the reset.
This feature can be used to eliminate the effects of start-up transients.
Tracing Model Execution
Model execution can be traced to provide detailed information about what is happening. For each “interesting”
occurrence, the trace shows:
The current simulated time
The process name, id, and priority of the process involved
The action being performed (e.g. “reserve facility”)
Tracing can be turned on either before the model starts executing via an argument to CSIM or during execution
via CSIM statements. Unless redirected via set_trace_file, the output will go to the standard output location.
To turn the trace on before the model starts execution:
In a UNIX environment, specify a.out -T on the command line before any user-defined arguments.
In a PC or Macintosh environment, specify -T in the window that allows run-time argument specification.
In either case, the trace option must be specified before any user-defined parameters being passed to the
model.
To turn the trace on or off during execution:
trace_on();
trace_off();
Notes:
trace_off will turn off the trace regardless of whether it had been turned on by trace_on or by the -T
parameter.
Using these statements, the user can choose to trace only the portions of the program of interest.
To insert a message into the trace, so that it appears as part of the trace output:
trace_msg(“str”);
Where:
str - is a string to be inserted into the trace (quoted string or type char*)
Notes:
The string is printed only if the trace is on (via trace_on or the -T parameter).
Error Handling
When CSIM detects an error, its default action is to send a message to the error file and then perform a
dump_status . If this is not satisfactory, the programmer can, instead, intercept CSIM errors,
and handle them as desired.
To request that CSIM call a user-specific error handler:
set_err_handler(func);
Where:
func - is the name of the function to be called when CSIM detects an error
Notes:
The function is called with one argument: the index of the error that was detected (see “Error Messages”
on page 60 for a list of errors and their indices).
To request that CSIM revert to the default method of handling errors:
clear_err_handler();
To print the error message corresponding to the index passed to the error handler:
print_csim_error(index);
Where:
index - is the error index for which the error message should be printed (type long)
Notes:
The error messages and their indices are listed in “Error Messages “ on page 60.
Output File Selection
CSIM allows the user to select where various types of output should be sent. The default file for all of these is
“stdout”. The following are the files that can be specified:
Output file - for reports and status dumps
Error file - for error messages
Trace file - for traces
To change the file to which a given type of output is sent:
set_error_file (fp);
set_output_file(fp);
set_trace_file(fp);
Where:
fp - is a file pointer of the file to which the indicated type of output will be sent (type FILE *)
Notes:
Type FILE is normally declared in the standard header file .
The user is responsible for opening and closing the file.
Compiling and Running CSIM Programs
A CSIM program has to be compiled referencing the CSIM library to process the required "csim.h" header file
(the "cpp.h" header file for C++ programs) and using the CSIM library (archive file) to satisfy calls
to the CSIM library routines.
UNIX Systems
The usual way to do this is to have a "csim" script file which "points" to the correct directory and
files. If the csim library is located in
/home/hds/csim/lib
then a command file, named csim, which looks like the following:
cc -I/home/hds/csim/lib $* /home/hds/csim/lib/csim.a
can be used to compile a csim program (e.g. located in file.c) via
csim file.c
To execute your program, just give the command:
a.out
assuming that the standard defaults were used. The command
a.out -T
will cause a CSIM debugging event trace to be generated (See”Tracing Model Execution” on page 54 for more
information on tracing). Either of these, as well as other command line arguments, can be used on the
command line. For information on how command line arguments are processed, see “Creating a CSIM
Program” on page 52.
Differences for C++:
For C++ programs, the csim file (call it csim.cpp) will look like:
CC -DCPP -I/home/hds/csim/lib $* /home/hds/lib/csim.cpp
The header file is "cpp.h"
PCs with Borland C/C++ for Windows (or Turbo C/C++ for Windows)
With Borland C, you must:
Create a project
Add the CSIM library (csim.lib) to that project
Set up the OPTIONS as follows (each entry tells you what to do next, so, for example, the first line says
“Choose the Compiler option from the Options menu, the Code Generation option from the Compiler menu,
and indicate Large and Never in the dialog box that appears.”):
Compiler -> Code Generation:
Compiler -> Advanced Code Generation: <80287>
Compiler -> Messages -> Display:
Directories: Append pointer to csim\lib directory to list of include directories (e.g. ;.\lib if the project is in
the csim directory)
Add your file(s) for the CSIM program to the project.
Differences for C++:
For CPP programs:
The header file must be "cpp.h"
The program files need a .cpp suffix (instead of a .c)
The library is csim.cpp
The OPTIONS need one additional item:
Compiler -> Code Generation:
Note: CSIM programs do not execute efficiently on systems without hardware support for floating point
operations (such as an 80387, 487 or a 486DX processor). A 486SX without a 487 will probably run slowly.
Macintoshes with Think C (5.0) or Think C/C++ (6.0)
With Think C (5.0 or 6.0) you must:
Create a project
Add two projects containing the CSIM routines, named csima.prj and csimb.prj
Set the following options using the OPTIONS selection under the EDIT menu bar item:
Language settings: deselect "enforce strict prototypes"
Compiler settings: select "generate 68881 instrs", "4 bytes ints" and "floating point native format"
Debugger settings: select "always generate stack frames".
Prefixes: #define MAC
Differences for C++:
For C++ in Think C/C++ (6.0):
The header file is "cpp.h"
The csim project files are csima++.prj and csimb++.pr
In the OPTIONS section, there is an addition:
Prefixes: #define MAC and #define CPP
The C++ program files have a ".cpp" suffix
The ANSI and UNIX files must be compiled so that they are compatible with C++ programs
Notes:
CSIM programs do not execute efficiently on systems without hardware support for floating point
operations.
With Think C, it is essential that the standard libraries such as ANSI be compiled to support floating point
numbers and four byte integers, as required by CSIM. To do this:
Go to the C libraries folder in the Think C folder
Make a copy of the ANSI project(call it ANSI flt pt)
Open ANSI flt pt, and change the options compiler settings to be as above
"Bring this up to date".
In the CSIM project file:
Add the ANSI flt pt project, the Unix project and the CSIM program being compiled
The csima.prj and csimb.prj files and the ANSI flt pt file all have to be in separate segments. To do this,
drag them down in the Think C menu which lists the files.
Reminders and Common Errors
When writing a CSIM program, the following things are important:
Be aware of the maximum allowed number of concurrently active processes. In the current version, there
is a limit of 1000 concurrently active processes (this can be changed by using the function
max_processes).
When a process (a procedure containing a create statement) is called with parameters, these should be
either parameters passed as values (the default in C) or addresses of variables in global (or static) storage.
Beware of local arrays and strings which are parameters for processes...they are likely to cause problems.
THIS IS VERY IMPORTANT!!
CSIM manages processes by copying the runtime stack to a save area when the process is suspended
and then back to the stack when the process resumes. Thus, if a process receives a parameter which is a
local address in the initiating process (i.e. in that process's stack frame), the address will not point to the
desired value when the called process is executing.
All entities (facilities, storage blocks, etc.) must be declared using variables of the correct type.
All entities (facilities, storage blocks, etc.) must be initialized before being referenced.
An array of length n is indexed 0,1,...,n-1 (standard C indexing).