#include <ssim.h>
Static Public Member Functions | |
static ProcessId | create_process (Process *) throw () |
creates a new process | |
static int | stop_process (ProcessId) throw () |
stops the execution of a given process | |
static void | stop_process () throw () |
stops the execution of the current process | |
static void | clear () throw () |
clears out internal data structures | |
static void | self_signal_event (const Event *e) throw () |
signal an event to the current process immediately | |
static void | self_signal_event (const Event *e, Time delay) throw () |
signal an event to the current process at the given time | |
static void | signal_event (ProcessId p, const Event *e) throw () |
signal an event to the given process immediately | |
static void | signal_event (ProcessId p, const Event *e, Time d) throw () |
signal an event to the given process at the given time | |
static void | advance_delay (Time) throw () |
advance the execution time of the current process. | |
static ProcessId | this_process () throw () |
returns the current process | |
static Time | clock () throw () |
returns the current virtual time for the current process | |
static void | run_simulation () |
starts execution of the simulation | |
static void | stop_simulation () throw () |
stops execution of the simulation | |
static void | set_stop_time (Time t=INIT_TIME) throw () |
stops the execution of the simulation at the given time | |
static void | set_error_handler (SimErrorHandler *) throw () |
registers a handler for simulation errors. |
This class implements a generic discrete-event sequential simulator. Sim maintains and executes a time-ordered schedule of actions (or discrete events).
Notice that this class is designed to have only static members. It should therefore be seen and used more as a module than a class. In practice, this means that Sim does not define simulation objects, but rather a single, static simulator. This design is based on practical considerations: a simulation object would allow one to handle multiple simulations within the same program at the same time, however that situation is neither common nor desirable. Simulations tend to use a lot of memory and therefore having many of them is probably a bad idea. Also, having multiple simulation objects would require every process object to maintain a reference to the corresponding simulation context (object), so that processes can access the virtual clock of their own simulation, their scheduler, etc. This is both a waste of memory, for the many aditional references, and of CPU time for all the indirect calls to the simulation methods.
|
advance the execution time of the current process. This method can be used to specify the duration of certain actions, or certain steps within the same action. For example:
class SomeProcess : public Process { //... virtual void process_event(const Event * e) { // // suppose this response is called at (virtual) time X // ...do something here... // the above actions have a default duration of 0, // therefore the following event is scheduled at time X + 5 // signal_event(e, p, 5); advance_delay(10); // ...do something else here... // advance_delay(10) specifies a duration of 10, therefore // the following (NULL) event is scheduled at time X + 15; // signal_event(NULL, 5); } }; Notice that a simulation process correspond to a single logical thread. This means that Process::process_event() and TProcess::main() are intended to process one event at a time. Because of this chosen semantics, the use of advance_delay(Time) may result in the current process missing some events. Referring to the above example, the overall duration of the execution step defined by SimpleProcess::process_event() is 15 time units. Therefore, a SimpleProcess executing its process_event at time X would miss every event scheduled for it between time X and X + 15. A semantically identical situation would occur for a sequential process. For example:
class SomeTProcess : public TProcess { //... virtual void main() { // ... const Event * e; e = wait_for_event(); // now suppose wait_for_event() returns a signal at time X // and we do something with this signal... // and this "something" costs us 20 time units advance_delay(20); // now, our virtual clock is X + 20, so we have missed // all the signals between X and X + 20 e = wait_for_signal(); } }; In this example, the process misses all the events signaled within 20 time units after the first event. This is because the process is busy working on the first event. The application may program a handler for missed events by programming and registering a SimErrorHandler object. This method must be used within the simulation. The effect of using this method outside the simulation is undefined.
|
|
clears out internal data structures Resets the simulator making it available for a completely new simulation. All scheduled actions are deleted together with the associated events. All process identifiers returned by previoius invocations of create_process are invalidated by this operation. Notice however that it is the responsibility of the simulation programmer to delete process objects used in the simulation. |
|
returns the current virtual time for the current process Current virtual time. Example: void LoopProcess::process_event(const Event * e) { cout << "Here I am at time:" << Sim::clock() << endl; self_signal_event(NULL, 20) cout << "I just scheduled myself again for time: " << Sim::clock() + 20 << endl; }
|
|
creates a new process Creates a new process with the given Process object. This method schedules the execution of the init method for the given object. This method can be used safely within the simulation as well as outside the simulation.
|
|
signal an event to the current process at the given time Signal a delayed event to the current process. The response is scheduled with the given delay. This method must be used within the simulation. The effect of using this method outside the simulation is undefined.
|
|
signal an event to the current process immediately Signal an event to this process. The response is scheduled immediately (i.e., at the current time). This method must be used within the simulation. The effect of using this method outside the simulation is undefined.
|
|
registers a handler for simulation errors. An error handler is a callback object that handles all simulation errors.
|
|
stops the execution of the simulation at the given time This method sets the absolute (virtual) time at which the simulation will terminate. This method can be used to limit the duration of a simulation even in the presence of schedulable actions. When called with the (default) INIT_TIME, the simulation is set for normal termination, that is, the simulation terminates in the absence of schedulable actions.
|
|
signal an event to the given process at the given time Signal a delayed event to the current process. The response is scheduled with the given delay. This method must be used within the simulation. The effect of using this method outside the simulation is undefined.
|
|
signal an event to the given process immediately Signal an event to the given process. The response is scheduled immediately (i.e., at the current time). This method must be used within the simulation. The effect of using this method outside the simulation is undefined.
|
|
returns the current process Process id of the process that is currently scheduled by the simulation. This method can be used by a Process in process_event or by a TProcess in main to figure out its own process id. Example: class SimpleProcess : public Process { void SimpleProcess::process_event(const Event *) { cout << "My process id is: " << Sim::this_pocess() << endl; } };
|