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).