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

8. Mailboxes

A mailbox allows for the synchronous exchange of data between CSIM processes. Any process may send a message to any mailbox, and any process may attempt to receive a message from any mailbox.

A mailbox is comprised of two FIFO queues: a queue of unreceived messages and a queue of waiting processes. At least one of the queues will be empty at any time. When a process sends a message, the message is given to a waiting process (if one exists) or it is placed in the message queue. When a process attempts to receive a message, it is either given a message from the message queue (if one exists) or it is added to the queue of waiting processes.

A message can be either a single long integer or a pointer to some other data object. If a process sends a pointer, it is the responsibility of that process to maintain the integrity of the referenced data until it is received and processed.

8.1. Declaring and Initializing a Mailbox

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

Dynamic Example: mailbox *md;

Before a dynamic mailbox can be used, it must be initialized by invoking the new mailbox constructor.

Prototype: mailbox::mailbox(char*name)
Static Example: mailbox ms("request");
Dynamic Example: md = new mailbox("requests");

A newly created mailbox contains no messages. The mailbox name is used only to identify the mailbox in output reports and trace messages.

A mailbox that is initialized in the first CSIM process (sim) exists during the entire simulation run and is called a global mailbox. A mailbox initialized in any other process is called a local mailbox. A local mailbox is deleted when the process in which it was constructed terminates.

8.2. Sending a Message

A process sends a message by calling the send function.

Prototype: void mailbox::send(long message)
Dynamic Example: md->send((long) buffer);

If one or more processes are waiting on this mailbox, the process at the head of the process queue will resume execution and will be given this message. If no processes are waiting, this message will be appended to the tail of the message queue. No simulation time passes during this method call.

8.3. Receiving a Message

A process receives a message by calling the receive function.

Prototype: void mailbox::receive(long* message)
Dynamic Example: md->receive((long*) &ptr);

If one or more messages are queued at this mailbox, the calling process is given the message at the head of the queue and continues executing. If no messages are queued, the process is suspended from further execution and is added to the tail of the process queue for this mailbox.

8.4. Receiving a Message with a Time-out

Sometimes a process must not wait indefinitely to receive a message. If a process calls the timed_receive function, it will be suspended until either a message is received or the specified amount of time has passed.

Prototype: long mailbox::timed_receive(long*
message, double timeout)

Example: result = md->timed_receive((long*)&ptr,
100.0);

if (result ! = TIMED_OUT) ...

The calling process can 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 a message was received; if the value TIMED_OUT is returned, the specified amount of time passed without the process being activated by the receipt of a message.

8.5. Synchronous_send

A process can also send a message with a synchronous send operation (as opposed to a normal send operation as described above). With a synchronous send, the send process waits until the sent message has been received by another process.

Prototype: void mailbox::synchronous_send(long message)
Dynamic Example: mb->synchronous_send(msg,);

8.6. Synchronous_send with a Time-out

A process can also do a synchronous_send operation with a time-out interval:

Prototype: long mailbox::timed_synchronous_send(long
message, double timeout)

Dynamic Example: result = mb->timed_synchronous_send(msg,
100.0);
if (result ! = TIMED_OUT)

The calling process can 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 a message was received; if the value TIMED_OUT is returned, the specified amount of time passed without the process being activated by the receipt of a message by another process.

8.7. Collecting and Reporting Statistics for Mailboxes

A set of statistics on the usage can be collected for specified mailboxes. Statistics collection for a mailbox is initiated by executing the mailbox_monitor statement.

Prototype: void mailbox::monitor()
Dynamic Example: mb->mailbox_monitor();

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

MAILBOX SUMMARY
mailbox name number of proc visits process qlength rpocess repTime number of messages mesage qlength message rspTime
mb 100 0.18737 0.32295 100 1.03091 1.79461

A separate report for all monitored mailboxes is produced by the report_mailboxes() procedure:

Prototype: void report_mailboxes()
Example: report_mailboxes();

8.8. Resetting a Mailbox

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

Prototype: void reset_mailbox(MBOX mb)
Example: reset_mailbox(mb);

Executing this statement does not affect the state of the mailbox. The "reset" and the reset_mailboxes statements each call reset_mailbox() for all mailboxes in the model.

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

Prototype: void mailbox_set_monitor(MBOX mbs[])
Example: mailbox_set_monitor(mbs);

8.9. Mailbox Sets

A mailbox set is an array of related mailboxes for which some special operations are provided. A mailbox set is declared using the C array construct.

Example: MBOX mb_set[10];

All mailboxes in a mailbox set are initialized with a single call to the mailbox_set function.

Prototype: void mailbox_set(MBOX mb_set[], char *name,
long number_of_mailboxes)

Example: mailbox_set(mb_set, "mboxes", 10);

As with any C array, the mailboxes in an mailbox set are indexed from 0 to num_mailboxes - 1. Individual mailboxes in the mailbox set can be manipulated using any of normal mailbox functions (e.g., send, and receive).

Example: send(mb_set[3], 1);

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

Prototype: long receive_any(MBOX mb_set[], (long*) msg)
Example: mb_index = receive_any(mb_set, &m);

This function returns the index of the mailboxthat caused the calling process to proceed. If multiple mailboxes in the set have received messages, the lowest numbered mailbox is the one recognized by the calling process.
A process can also do a timed_receive_any() operation at an mailbox_set.

Prototype: long timed_receive_any(MBOX mb_set[], (long*)&ptr)
Example: result = time_receive_any(mb_set, &m);
if(result != TIMED_OUT) . . .

If the result is not equal to TIMED_OUT, then it is the index of the mailbox which received the message and caused the process to continue.

An entire mailbox set is deleted by calling the delete_mailbox_set function.

Prototype: void delete_mailbox_set(MBOX mb_set[])
Example: delete_mailbox_set(mb_set);

The delete_mailbox function must not be called on individual members of an mailbox set.

8.10. Renaming a Mailbox

The name of a mailbox can be changed at any time using the set_name_mailbox function.

Prototype: void mailbox::set_name(char *new_name)
Static Example: ms.set_name("responses");

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

8.11. Deleting a Mailbox

When a dynamic mailbox is no longer needed, its storage can be reclaimed as follows:

Example: delete md;

If a mailbox is local, only the process that created the mailbox can delete it. Once a mailbox has been deleted, it must not be further referenced. Deleting a mailbox causes any unreceived messages to be lost. It is an error to attempt to delete a mailbox on which processes are waiting.

8.12. Inspector Methods

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

Prototype: Functional value:
char *mailbox::name() pointer to name of mailbox
long mailbox::msg_cnt() if positive, number of unreceived messages
if negative, magnitude is number of waiting
processes

long mailbox::queue_cnt
number of processes queued at mailbox
long mailbox_set::num_msgs number of messages in a mailbox set
double mailbox::proc_sum sum of process queue lengths
long mailbox::proc_delay_count number of processes delayed
long mailbox::proc_count number of process receiving messages
double mailbox::proc_length average process queue length
double mailbox::proc_time average process delay time
double mailbox::msg_sum sum of message queue lengths
long mailbox::msg_delay_count number of messages delayed
long mailbox::msg_count number of messages sent
double mailbox::msg_length average message queue length
double mailbox::msg_time
average message delay time

8.13. Status Report

The status_mailboxes function prints a report of the status of all mailboxes in the model.

Prototype: void status_mailboxes(void)
Example: status_mailboxes();

For each mailbox, the report includes the number of unreceived messages, the number of waiting processes, and the name and id of all waiting processes. The report is written to the default output stream or the stream specified in the last call to set_output_file.

Next Section

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