Threads exchange information by sending messages to and receiving messages from mailboxes. A message can contain either an object handle or a data stream.
You can create two kinds of mailboxes:
Sending and receiving data uses different system calls than sending and receiving object handles.
When you create a low-level mailbox, you can reserve one slot in the mailbox message queue for a high priority message. This enables the mailbox to accommodate at least one high priority message even if the queue is full.
You use an object mailbox to pass an object handle to another thread. The most common objects to pass are RT handles for other exchanges (mailboxes or semaphores) or RT handles for shared memory sections. (See Memory management) An object mailbox can only pass valid objects.
Use data mailboxes to pass small (up to 128 bytes) amounts of information. Data mailboxes are simple to use and consume less resource (memory, GDT entries, and so on).
When you create a mailbox using CreateRtMailbox, the INtime kernel takes resources that it needs from the thread's process. You must specify these parameters when creating a mailbox:
Create mailboxes with knCreateRtMailbox. To create a mailbox specify:
Each mailbox has two queues: a thread queue and a message queue. At any given time, at least one queue is empty because the INtime kernel ensures that waiting threads receive messages as soon as they are available.
By specifying a high-performance queue large enough to contain all objects queued during normal operations, you improve the performance of SendRtHandle and ReceiveRtHandle calls when these calls get or place objects in the queue. The INtime kernel permanently allocates memory for a high-performance queue even if no objects are stored in it, so memory does not have to be allocated dynamically.
The INtime kernel automatically handles overflow. When more objects arrive than the high-performance queue can hold, the INtime kernel creates a temporary overflow queue that holds up to four messages. The overflow queue is not deleted until it empties. Because the overflow queue is created once for every additional four messages, performance is only affected when a SendRtHandle system call causes the allocation of an overflow queue. The allocation then requires extra time.
Data mailboxes have a default queue size of three messages, 128 bytes each. When more messages arrive than the queue can hold, the INtime kernel creates a temporary overflow queue that holds up to 400 bytes. The overflow queue is not deleted until the queue empties.
When you create a low-level Data Mailbox using knCreateRtMailbox, you may reserve one of the slots in the mailbox message queue for a high priority message. This enables the mailbox to accommodate at least one high priority message even if the queue is full.
If a mailbox contains its maximum number of messages when a message is sent, the Kernel returns an exception stating that the mailbox limit was exceeded. The mailbox enforces flow control by rejecting messages when the queue is full. Depending on your application, there are several ways to handle mailbox overflow:
If you reserved a slot for a high priority message, mailbox overflow may be indicated when sending an ordinary message, even though the mailbox can still accept a high priority message.
When you delete a mailbox using DeleteRtMailbox or knDeleteRtMailbox, the INtime kernel:
The next figure shows a server thread that does similar services for several client threads in different processes. The server and clients have their own mailboxes. The server should catalog its mailbox in the root process's object directory. Each client sends the handle for its mailbox to the server in the data message so the server knows where to reply.
Send ordinary messages to a mailbox with knSendRtData. If a thread is waiting at the mailbox, it receives the message. Otherwise, the message is queued. If the mailbox is full, an exception returns.
Send high priority messages with knSendRtPriorityData. If a thread is waiting at the mailbox, it receives the message. Otherwise, the message is placed at the head of the queue. If the mailbox is full, an exception returns.
Specify the actual message size, which must be less than or equal to the maximum message size for the mailbox. The maximum message size is the size you specified when creating the mailbox. The knSendRtData and knSendRtPriorityData system calls return a status value indicating either that the message was accepted or the mailbox was full.
Receive data from a mailbox with knWaitForRtData. If the mailbox contains at least one message, the message at the head of the queue is returned to the caller. This is either the oldest message or the latest high-priority message. You must provide a message area equal to the maximum message size of the mailbox for the thread.
The call returns the actual size of the received message and a status value indicating:
If no messages are available and the thread is willing to wait, the thread is put to sleep in the thread queue.
This lists common operations on mailboxes and the mailbox system calls that do the operations:
To . . . | Use this system call . . . |
---|---|
Create a mailbox | ntxCreateRtMailbox CreateRtMailbox knCreateRtMailbox |
Delete a mailbox | ntxDeleteRtMailbox DeleteRtMailbox knDeleteRtMailbox |
Send data | |
Send priority data | knSendRtPriorityData |
Receive data | ntxReceiveRtData ReceiveRtData knWaitForRtData |
Send a handle | ntxSendRtHandle SendRtHandle |
Receive a handle | ntxReceiveRtHandle ReceiveRtHandle |
This shows the order to make queue system calls and lists calls that queues frequently use:
These are the rules for queues:
Note: If you try to pass information with the wrong system call, for example sending an object with SendRtData, the INtime kernel issues an E_TYPE status code. Use the SendRtData and ReceiveRtData system calls with data mailboxes. Use the SendRtHandle and ReceiveRtHandle with object mailboxes.