Mesquite Software

Home
Products and FAQ
Customers
To Order
Contact Us
Site Map
Documentation
News & Events

Purchase & Download
Or, log in here to
access your account.
 
Documentation

7. Events

Events are used to synchronize the operations of CSIM processes. An event exists in one of two states: occurred or not occurred. A process can change the state of an event or it can suspend its execution until an event has occurred. When a process is suspended it can join a set of processes, all of which will be resumed when the event occurs. Or, it can join an ordered queue from which only one process is resumed for each occurrence of the event. An event is automatically reset to the not occurred state when all of the suspended processes that can proceed have done so.

Advanced features of events include the ability to create sets of events for which processes can wait and the ability for a process to bound its waiting time by specifying a time-out. Events can also be used to construct other synchronization mechanisms such as semaphores.

7.1. Declaring and Initializing an Event

A pointer to a dynamic event is declared in a CSIM program as follows:

Dynamic Example: event *ed;

Before a dyanmic event can be used, it must be initialized by invoking the
new event constructor.

Prototype: event::event(char *name)
Static Example: event es("done");
Dynamic Example: ed = new event("done");

An event is initialized in the not occurred state. The event name is used only to identify the event in output reports and trace messages.
An event that is initialized in the first CSIM process (sim) exists during the entire simulation run and is called a global event. An event initialized in any other process is called a local event. A local event is deleted when the process in which it was initialized terminates. To make such an event exist for the entire run, it must be initialized by calling the
global_event function.

Prototype: global event::global_event (char *name)
Static Example: global_event es("done");
Dynamic Example: ed = new global_event("done");

7.2. Waiting for an Event to Occur

A process waits for an event to occur by calling the wait function.

Prototype: void event::wait(void)
Dynamic Example: e->wait();

If the event is in the occurred state, control returns from the wait function immediately and the event is changed to the not occurred state. If the event is in the not occurred state, the calling process is suspended from further execution and control will not return from the wait function until some other process sets this event. When the event is set, all waiting processes will be resumed and the event will be placed in the not occurred state.

7.3. Waiting with a Time-Out

Sometimes a process must not be suspended indefinitely waiting for an event to occur. If a process calls the timed_wait function, it will be suspended until either the event is set or the specified amount of time has passed.

Prototype: long event::timed_wait(double timeout)
Dynamic Example: result = ed->timed_wait(100.0);
if (result ! = TIMED_OUT)

The calling process should check the functional value to determine the circumstances under which it was resumed. If the value EVENT_OCCURRED is returned, the process was activated because the event has occurred; if the value TIMED_OUT is returned, the specified amount of time passed without the event being set.

7.4. Queueing for an Event to Occur

A process joins the ordered queue for an event by calling the queue function.

Prototype: void event::queue(void)
Dynamic Example: ed->queue();

This function behaves similarly to the wait function, except that each time the event is set only one queued process is resumed. The queue is maintained in order of process priority, with processes having the same priority being ordered by time of insertion into the queue.

7.5. Queueing with a Time-out

If a process calls the timed_queue function, it will be suspended until either the event is set a sufficient number of times for the process to be activated or the specified amount of time has passed.

Prototype: long event::timed_queue(double timeout)
Dynamic Example: result = ed->timed_queue(100.0);
if (result ! = TIMED_OUT) ...

The calling process should check the functional value to determine the circumstances under which it was resumed. If the value EVENT_OCCURRED is returned, the process was activated because the event occurred; if the value TIMED_OUT is returned, the specified amount of time passed without the process being activated by the event being set.

7.6. Setting an Event

A process can put an event into the occurred state by calling the set function.

Prototype: void event::set(void)
Dynamic Example: ed->set();

Calling this function causes all waiting processes and one queued process to be resumed. If there are no waiting or queued processes, the event will be in the occurred state upon return from the set function. If there are waiting or queued processes, the event will be in the not occurred state upon return. No simulation time passes during these activities. Setting an event that is already in the occurred state has no effect.

7.7. Clearing an Event

A process can put an event into the not occurred state by calling the clear function.

Prototype: void event::clear(void)
Dynamic Example: ed->clear();

Clearing an event happens in zero simulation time and no processes are in any way affected. Clearing an event that is already in the not occurred state has no effect.

7.8. Renaming an Event

The name of an event can be changed at any time using the set_name_event function.

Prototype: void event::set_name(char *new_name)
Dynamic Example: es->set_name_event("finished");

Only the first ten characters of the event's name are stored.

7.9. Deleting an Event

When a dynamic event is no longer needed, its storage can be reclaimed using the delete function.

Dynamic Example: delete ed;

If an event is local, only the process that created the event can delete it. Once an event has been deleted, it must not be further referenced. It is an error to attempt to delete an event on which processes are waiting or queued.

7.10. Collecting and Reporting Statistics for Events

A set of statistics on the usage can be collected for specified events. Statistics collection for an event is initiated by executing the monitor() method.

Prototype: void event::monitor(void )
Dynamic Example: e->monitor();

The standard report function automatically proceeds to "print" a report for each monitored event. This report is as follows:

EVENT SUMMARY
event of name number of queue vst qvg que length avg time queued number of wait vsts avg wait length avg time waiting number set ops
ev 10 0.99010 1.00000 50 4.95050 1.00000 10

A separate for all of the monitored events is produced using the report_events() procedure, as follows:

Prototype: void report_events(void )
Example: report_events();

All of the events in an event_set (see below) can be monitored as well.

Prototype: void event_set::monitor(void)
Dynamic Example: es->monitor();

7.11. Resetting an Event

In some cases, it is necessary to reset the statistics counters for a specific event.

Prototype: void event::reset(void)
Example: e->reset();

Executing this statement does not affect the state of the event. The "reset" and the reset_events statements each call reset_event() for all events in the model.

7.12. Event Sets

An event set is an array of related events for which some special operations are provided. A pointer to a dynamic event set is declared as follows:

Example: event_set *ed_set;

All events in an event set are initialized by invoking the event_set constructor.

Prototype: event_set::event_set(char *name, long number_of_events)
Static Example: event_set es_set("events", 10);
Dynamic Example: ed_set = new event_set("events",10);

As with any C array, the events in an event set are indexed from 0 to num_events - 1. Individual events in the event set can be manipulated using any of normal event functions (e.g., set, clear, wait, queue).

Static Example: es_set[3].set();
Dynamic Example: (*ed_set)[3].set();

A process can wait for the occurrence of any event in an event set by calling the wait_any function.

Prototype: long event_set::wait_any(void)
Dynamic Example: event_index = ed_set->wait_any();

This function returns the index of the event that caused the calling process to proceed. If multiple events in the set are in the occurred state, the lowest numbered event is the one recognized by the calling process. All processes that have called wait_any are activated by the next event that occurs, and these processes all receive the same index value.

A process can join an ordered queue for an event set by calling the queue_any method.

Prototype: long event_set::queue_any(void)
Dynamic Example: event_index = ed_set->queue_any();

Each time any event in the event set occurs, one process in the queue is activated. The functional value is the same as that of the wait_any function. It is not currently possible to specify a time-out for the wait_any or queue_any methods.

An entire dynamic event set is deleted as follows:

Example: delete e_set;

It is an error to delete individual elements of an event set.

A process can also do a time_wait_any() operation at an event_set.

Prototype: long event_set::timed_wait_any(double time_out)
Dynamic Example: result = ed_set->time_wait_any(double time_out);

If the result is not equal to TIME_OUT, the it is index of the event which caused the process to continue.

A process can also do a timed_queue_any() operation at an event_set:

Prototype: long event_set::timed_queue_any(double time_out)
Dynamic Example: result = ed_set->time_queue_any(double time_out);

If the result is not equal to TIMED_OUT, then it is the index of the event which caused the process to continue.

7.13. Inspector Methods

The following methods return information about the specified event at the time they are called

Prototype: Functional value:
char *event::name() pointer to name of event
long event::wait_cnt() number of processes waiting for event
long event::queue_cnt() number of processes queued of event
long event::qlen() sum of wait_cnt and queue_cnt
long event::state() state of event:
OCC if occurred or
NOT_OCC if not occurred
long event::num_events() number of processes waiting for the event
long event::set_count() number of set operations
double event::queue_sum() sum of queue queue lengths
double event::wait_sum() sum of wait queue lengths
long event::queue_delay_count() number of queue delays
long event::wait_delay_count() number of wait delays
long event::queue_length() average queue queue length
long event::wait_length() average wait queue length
long event::queue_time() average queue queue time
long event::wait_time() average wait queue time
long event::queue_count() average queue queue count
long event::wait_count() average wait queue count

7.14. Status Report

The status_events function prints a report of the status of all events in the model.

Prototype: void status_events(void)
Example: status_events();

For each event, the report includes its state, the number of processes waiting for it, the number of processes queued for it, the name and id of all waiting processes, and the name and id of all queued processes. The report is written to the default output stream or the stream specified in the last call to set_output_file.

7.15. Built-In Events

A process can suspend itself until there are no other active processes by waiting on the built-in event event_list_empty.

Example: event_list_empty.wait();

This event is automatically set by CSIM when all processes have terminated or are waiting for something (e.g., a facility or storage). Modelers sometimes use this to force the initial (sim) process to wait until all work in the system being modeled has completed. Upon being reactivated, the initial process might then produce reports.

If run length control is involved for a table, qtable, meter or box, (see 14.3), a process can suspend itself until the run length control mechanism signals the end of a run. This is done by waiting for the built-in event converged.

Example: converged.wait()

Next Section

 
Home | Products/FAQ | Customers | To Order | Contact Us | Site Map | Documentation
© copyright 2005, Mesquite Software, all rights reserved.