Mailbox

Jan. 21, 2024 || Item:4.2.Mailbox

A mailbox is a communication mechanism that allows messages to be exchanged between processes. Data can be sent to a mailbox by one process and retrieved by another.

Mailboxes are created as having either a bounded or unbounded queue size. A bounded mailbox becomes full when it contains the bounded number of messages. A process that attempts to place a message into a full mailbox shall be suspended until enough room becomes available in the mailbox queue. Unbounded mailboxes never suspend a thread in a send operation.

There are two types of mailboxes: type-less mailbox and parameterized mailbox.

- Type-less mailbox: the default mailbox is type-less, that is, a single mailbox can send and receive any type of data. This is a very powerful mechanism that, unfortunately, can also result in run-time errors due to type mismatches between a message and the type of the variable used to retrieve the message. Frequently, a mailbox is used to transfer a particular message type, and, in that case, it is useful to detect type mismatches at compile time.

mailbox mailbox_name;

- Parameterized mailbox: parameterized mailboxes use the same parameter mechanism as parameterized classes, modules, and interfaces.

mailbox #(type = dynamic_type) mailbox_name;

1. Mailbox methods

Mailbox is a built-in class that provides the following methods:

- new(): create a mailbox

- put(): place a message in a mailbox

- try_put(): try to place a message in a mailbox without blocking

- get()/peek(): retrieve a message from a mailbox

Accellera Extensions to Verilog-2001

- try_get()/try_peek(): try to retrieve a message from a mailbox without blocking

- num(): retrieve the number of messages in the mailbox

1.1. new()

Create a new mailbox.

function new(int bound = 0);

It returns the mailbox handle, or null if the mailboxes cannot be created. If the bound argument is zero then the mailbox is unbounded (the default) and a put() operation shall never block. If bound is non-zero, it represents the size of the mailbox queue.

The bound must be positive. Negative bounds are illegal and can result in indeterminate behavior, but implementations can issue a warning.

1.2. num()

Returns the number of messages currently in the mailbox.

function int num();

The returned value should be used with care, since it is valid only until the next get() or put() is executed on the mailbox. These mailbox operations can be from different processes than the one executing the num() method. Therefore, the validity of the returned value shall depend on the time that the other methods start and finish.

1.3. put()

Places a message in a mailbox.

task put( singular message);

The message is any singular expression, including object handles.

A message is stored in the mailbox in strict FIFO order. If the mailbox was created with a bounded queue the process shall be suspended until there is enough room in the queue.

1.4. try_put()

Attempts to place a message in a mailbox.

function int try_put( singular message);

The message is any singular expression, including object handles.

This method is meaningful only for bounded mailboxes. If the mailbox is not full then the specified message is placed in the mailbox and the function returns 1. If the mailbox is full, the method returns 0.

1.5. get()

Retrieves a message from a mailbox.

task get( ref singular message );

The message can be any singular expression, and it must be a valid left-hand side expression.

The get() method retrieves one message from the mailbox, that is, removes one message from the mailbox queue. If the mailbox is empty then the current process blocks until a message is placed in the mailbox. If there is a type mismatch between the message variable and the message in the mailbox, a runtime error is generated.

Non-parameterized mailboxes are type-less, that is, a single mailbox can send and receive different types of data. Thus, in addition to the data being sent (i.e., the message queue), a mailbox implementation must maintain the message data type placed by put(). This is required in order to enable the runtime type checking.

The mailbox waiting queue is FIFO. This does not guarantee the order in which processes arrive at the queue, only that their arrival order shall be preserved by the mailbox.

1.6. try_get()

Attempts to retrieves a message from a mailbox WITHOUT blocking.

function int try_get( ref singular message );

If the mailbox is empty, then the method returns 0. If there is a type mismatch between the message variable and the message in the mailbox, the method returns –1. If a message is available and the message type matches the type of the message variable, the message is retrieved and the method returns 1.

1.7. peek()

Copies a message from a mailbox WITHOUT REMOVING the message from the queue.

task peek( ref singular message );

If the mailbox is empty then the current process blocks until a message is placed in the mailbox. If there is a type mismatch between the message variable and the message in the mailbox, a runtime error is generated.

1.8 try_peek()

Attempts to copy a message from a mailbox WITHOUT blocking.

function int try_peek( ref singular message );

If the mailbox is empty, then the method returns 0. If there is a type mismatch between the message variable and the message in the mailbox, the method returns –1. If a message is available and the mes- sage type matches, the type of the message variable, the message is copied and the method returns 1.



Comments:

Leave a comment: