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
User Guide: C : Events

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

An event is declared in a CSIM program using the built-in type EVENT.

Example: EVENT e;

Before an event can be used, it must be initialized by calling the event function.

Prototype: EVENT event(char* name)
Example: e = 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: EVENT global_event(char* name)
Example: e = 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 wait(EVENT e)
Example: wait(e);

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 timed_wait(EVENT e, double timeout)
Example: result = timed_wait(e, 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 queue(EVENT e)
Example: queue(e);

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 timed_queue(EVENT e, double timeout)
Example: result = timed_queue(e, 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 set(EVENT e)
Example: set(e);

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 clear(EVENT e)
Example: clear(e);

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 set_name_event(EVENT e, char *new_name)
Example: set_name_event(e, "finished");

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

7.9. Deleting an Event

When an event is no longer needed, its storage can be reclaimed using the delete_event function.

Prototype: void delete_event(EVENT e)
Example: delete_event(e);

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 event_monitor statement.

Prototype: void event_monitor(EVENT e)
Example: event_monitor(e);

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 avg 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 report for all of the monitored events can be generated as follows:

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

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

Prototype: void event_set_monitor(EVENT es[])
Example: event_set_monitor(es);

7.11. Resetting an Event

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

Prototype: void reset_event(EVENT e)
Example: reset_event(e);

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. An event set is declared using the C array construct.

Example: EVENT e_set[10];

All events in an event set are initialized with a single call to the event_set function.

Prototype: void event_set(EVENT e_set[], char *name,
long number_of_events)

Example: event_set(e_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).

Example: set(e_set[3]);

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

Prototype: long wait_any(EVENT e_set[])
Example: event_index = wait_any(e_set);

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

Prototype: long queue_any(EVENT e_set[])
Example: event_index = queue_any(e_set);

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

An entire event set is deleted by calling the delete_event_set function.

Prototype: void delete_event_set(EVENT e_set[])
Example: delete_event_set(e_set);

The delete_event function must not be called on individual members of an event set.

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

Prototype: long timed_wait_any(EVENT e_set[], double to)
Example: result = time_wait_any(e_set, 1.0);
if(result != TIMED_OUT) . . .


If the result is not equal to TIMED_OUT, then it is the 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 timed_queue_any(EVENT e_set[], double to)
Example: result = time_queue_any(e_set, 1.0);
if(result != TIMED_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 Functions

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

Prototype: Functional value:
char* event_name(EVENT e) pointer to name of event

long wait_cnt(EVENT e)
number of processes waiting for
event
long queue_cnt(EVENT e) number of processes queued of
event
long event_qlen(EVENT e) sum of wait_cnt and queue_cnt
long state(EVENT e) state of event: OCC if occurred or
NOT_OCC if not occurred
long num_events number of events in event_set
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
double event_queue_length average queue queue length
double event_wait_length average wait queue length
double event_queue_time average queue queue time
double event_wait_time average wait queue time
long event_queue_count number of queue operations
long event_wait_count number of wait operations

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: wait(event_list_empty);

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 section 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: wait(converged);

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