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 : Mailboxes

8. Mailboxes

A mailbox allows for the asynchronous 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 mailbox is declared in a CSIM program using the built-in type MBOX.

Example: MBOX m;

Before a mailbox can be used, it must be initialized by calling the mailbox function.

Prototype: MBOX mailbox(char* name)
Example: m = 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 initialized terminates.

8.2. Sending a Message

A process sends a message by calling the send function.

Prototype: void send(MBOX m, long message)
Example: send(m, (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 function call.

A process can also send a message and then suspend until the message is received by another process; this is called a synchronous_send operation:

Prototype: void synchronous_send(MBOX m, long message)
Example: synchronous_send(m, (long) buffer);

8.3. Receiving a Message

A process receives a message by calling the receive function.

Prototype: void receive(MBOX m, long* message)
Example: receive(m,(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 timed_receive(MBOX m, long* message,
double timeout)

Example: result = timed_receive(m,(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 synchronous_send(MBOX mb,
long message)

Example: synchronous_send(mb, 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 timed_synchronous_send(MBOX mb,
long message, double timeout)

Example: result = timed_synchronous_send (mb, 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(MBOX mb)
Example: mailbox_monitor(mb);

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 process visits process qlength process respTime number of messages message qlength message rspTime
               
mb 100 0.18737 0.32295 100 1.03091 1.79461  

A report for all of the monitored mailboxes can be generated as follows:

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 a 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 recieve_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 set_name_mailbox(MBOX m, char *new_name)
Example: set_name_mailbox(m, "responses");

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

8.11. Deleting a Mailbox

When a mailbox is no longer needed, its storage can be reclaimed using the delete_mailbox function.

Prototype: void delete_mailbox(MBOX m)
Example: delete_mailbox(m);

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 Functions

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

Prototype: Functional value:
char* mailbox_name (MBOX m) pointer to name of mailbox
long msg_cnt (MBOX m) 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.

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