SIMC - EVENT FUNCTIONS

Event-Scheduling

Definitions

     int (* EventRoutine)( Pointer Data);    /* C/C++ */

     An EventRoutine() is a C/C++ function prototype-d to accept
     a pointer as argument and to return an integer.  The
     function is otherwise a normal C/C++ function.  To behave
     as an event, it should be scheduled using the EvSchedule()
     function.  It could also be called as a normal C function.

     Pointer is typedef-ed as void*.


     int (SimC::* EventRoutine)( Pointer Data);   /* C++ */

     For a member function of a class to be schedule-able, the
     class must inherit the base class SimC eg

     Entity_Class : public SimC
     {
     // ...
     }

     Pointer is typedef-ed as SimC*.


Create( D, T);

     A descriptive macro for intended for allocating memory to
     data pointers, the effect being analogous to creating an
     entity.

     D = ( T *) malloc( sizeof( T))     /* C */

     D = new T                          /* C++ */


long EvBreak( Ev_ID Event_ID);          /* C/C++ */

     Breaks the Event associated with Event_ID, removing it from
     the simulation Agenda.  The remaining time to activation
     will be used as the Delay when the Event is Continued. 
     Returns the position of Event in the Agenda.


double EvClock( void);                  /* C/C++ */

     Returns the current event Clock.


long EvClearPriority( void);            /* C/C++ */

     Clears any previously set- Priority, returns the number of
     setting cleared.


long EvClear( void);                    /* C/C++ */

     Clears the event Agenda, returns the number of Events
     cleared.


long EvContinue( Ev_ID Event);          /* C/C++ */

     Continues the Event associated with Event_ID that was
     previously Break-ed, the Delay used will be the remaining
     time to activation when the Event was Break-ed.  Returns
     the position of Event in the Agenda.


long EvKill( Ev_ID Event);              /* C/C++ */

     Kills the Event associated with Event_ID, removing it from
     the simulation Agenda or, if it was earlier Break-ed, the
     Holding Set.


long EvList( void);                     /* C/C++ */

     Print to stderr in C, clog in C++:, the activation time and
     name of all Events in the Agenda.  Returns the number of
     Events in the Agenda.


Ev_ID EvSchedule( int ( *EventRoutine)( Pointer),
                  Pointer Data, double Delay);    /* C/C++ */

Ev_ID EvScheduleC( SimC*, int ( SimC::*EventRoutine)( Pointer),
                   Pointer Data, double Delay);   /* C++ */

     Places in the simulation Agenda, an Event header containing
     the EventRoutine, Data, and an activation time computed
     from the sum of current event Clock and the Delay.  The
     EventRoutine will be called at the activation time, with
     the Data pointer passed as parameter.  It returns an Ev_ID
     which must be used to Break or Continue the associated
     EventRoutine.


double EvSetClock( double Time);        /* C/C++ */

     Sets the event Clock to Time, if positive, returns the new
     value of the event Clock.


long EvSetPriority( int ( *Routine)(), long Priority);
     /* C/C++ */

long EvSetPriority( int ( SimC::*Routine)(), long Priority);
     /* C++ */

     Sets the Priority of the Routine.  When 2 different
     Routines are scheduled at the same activation time, the
     Routine with the higher Priority will be called first.  If
     2 Routines with the same Priority are scheduled with the 
     same activation time, the one scheduled first will be
     called first.  The default Priority is zero.


void EvSimulate( void);                 /* C/C++ */

     Repeatedly advance the event Clock to the most imminent
     Event activation time and call the associated Routine
     passing the associated Data as parameter, until there are
     no more Event in the simulation Agenda.


Process Functions

Definitions

     A Server must be declared as Svr_ID

     Svr_ID Server;                     /* C/C++ */

     and, in C only, initialised with

     Server = SvrCreate( N);            /* C */

     where N is the capacity of the server.  The Server may then
     be Request()-ed and Release()-ed in a process function.


     int (SimC::*ProcessRoutine)( Pointer Data)   /* C++ */

     int (*ProcessRoutine)( Pointer Data)         /* C/C++ */

     {
       ProcessBegin;
       /*                                     */
       /* C statements/functions              */
       /* update states, schedule events, etc */
       /* Process- macros                     */
       /*                                     */
       /* avoid switch()                      */
       /* avoid local variables               */
       /*                                     */
       ProcessEnd;
     }

     A ProcessRoutine() is prototype-d to accept a pointer as
     argument and return an integer.  It requires the macros
     ProcessBegin and ProcessEnd as the first and last
     executable statements.  

     It should only be activated using the EvSchedule() or
     EvScheduleC() function.  If a process function is called
     directly, the results is unpredictable.  

     The ProcessBegin and ProcessEnd macros have embedded
     switch(){case : } to emulate returning to the next line of
     codes after a -Break, -Wait, or Request macro.  Other
     switch() functions within a ProcessRoutine may interfere
     with the desired behaviour.  Use of if(){}else{} or calling
     a separate function is recommended.

     A ProcessRoutine() returns after a -Break, -Wait or Request
     macro.  Local variables will not retain their values after
     any call to those macros.

     A ProcessRoutine() is otherwise a normal C function, and
     may use various Process- macros described below.


ProcessBegin; and ProcessEnd;           /* C/C++ */

     Macros that must be placed as the first and last executable
     statements of process routines.  Process macros - 
     ProcessBreak, ProcessWait( Delay), Request( Number,
     Server), and Release( Number, Server) - may only be used
     within process routines ie between -Begin and -End macros.


ProcessBreak;                           /* C/C++ */

     Causes a process routine to Break execution.  When the
     process routine is Continued, execution will resume at the
     statement immediately following it. It can only be used in
     process routines ie between -Begin and -End macros.


ProcessWait( double Delay);             /* C/C++ */

     Causes a process routine to Wait for the specified Delay. 
     Execution will resume at the statement immediately
     following it.  It can only be used in process routines.


Wait( double Delay);                    /* C/C++ */

     Wait( T) is a shorter macro for ProcessWait( Delay).


RequestP( int Number, Svr_ID Server, int Priority);
     /* C/C++ */

     Checks if the Number of units of the Server is available. 
     If it is, the Number is subtracted from the available
     units.  If it isn't, the process routine will be suspended
     and placed in the Server's Queue.  Members of the Queue are
     ranked by the Priority, the process routine with higher
     Priority will be placed in front and served earlier.  If 2
     process routines with the same Priority are in the queue,
     the one placed earlier will be in front ie served earlier. 
     It can only be used in process routines.


Request( long Number, Svr_ID Server);   /* C/C++ */

     Request( N, S) is a shorter macro for RequestP( N, S, 0).


Release( long Number, Svr_ID Server);   /* C/C++ */

     Releases the Number of units of the Server, making them
     available to subsequent or Queued process routines.  It
     should only be used in process routines.


Svr_ID SvrCreate( long Capacity);       /* C */
Svr_ID::Svr_ID( long Capacity);         /* C++ */

     Creates a Server and initialised it with the specified
     Capacity.  It returns a Svr_ID which is needed as a
     parameter to Svr-functions and the Request/Release
     functions.


long SvrCapacity( Svr_ID Server);       /* C/C++ */
long Svr_ID::Capacity( void);           /* C++ */

     Returns the Capacity of the specified Server.


long SvrAvailable( Svr_ID Server);      /* C/C++ */
long Svr_ID::Available( void);          /* C++ */

     Returns the Available number of units of Server.


long SvrQueueSize( Svr_ID Server);      /* C/C++ */
long Svr_ID::QueueSize( void);          /* C++ */

     Returns the Size of the Server's Queue.


long SvrUsed( Svr_ID Server);           /* C/C++ */
long Svr_ID::Used( void);               /* C/C++ */

     Returns the number of units of Server being Used.



CONTINUOUS SIMULATION

Definitions

     int ( *DV)( int N, double *V,
                        double *dV, double Time); /* C/C++ */

     A differential-equation routine, DV(), must be provided. 
     It should compute the rate-of-change of each of the N
     members of V at the specified Time, and return the values
     in dV.

     The integration technique used is the Kutta-Merson method. 
     When a ContinuousWait is called, the simulation mechanism
     calls the integration routine which in turn calls the
     differential-equation routine.  The routine computes the
     largest time-step dT between Min_dT and Max_dT that
     produces deviation in any of V[] smaller than Max_dV, and
     with the order of error smaller than Error_Bound.  The
     ContinuousRoutine will Wait() the computed dT.


EvSetMax_dT( double Value);             /* C/C++ */
EvSetMin_dT( double Value);             /* C/C++ */
EvSetMax_dV( double Value);             /* C/C++ */
EvSetError_Bound( double Value);        /* C/C++ */

     Sets the Max_dT, Min_dT, Max_dV, Error_Bound.  Control over
     the integration process is achieved by setting these
     parameters to the desired values.


ContinuousBegin; and ContinuousEnd;     /* C/C++ */

     Macros that must be placed as the first and last executable
     statements of continuous routines.  Within the routine, the
     continuous macro, ContinuousWait(), must be used.  Process
     macros such as ProcessBreak, ProcessWait( Delay), Request(
     Number, Server), and Release( Number, Server) may also be
     used.


ContinuousWait( int N, double *V, 
                int ( *DV)( int, double* , double*, double));
     /* C/C++ */

     Causes a ContinuousRoutine() to Wait() a Delay computed
     from the double array V of size N, with the DV() routine. 
     After the delay, execution will resume at the statement
     immediately following it.  It must and should only be used
     in ContinuousRoutine()s.

