 |
Message Passing
|
AMX operates a fast, efficient message courier service using two types of message receptacles: mailboxes and message exchanges. A mailbox has a single message queue. A message exchange has four distinct message queues, one for each of four possible message priorities. Hence, messages sent to a message exchange can be ordered by priority; messages sent to a mailbox cannot.
Messages can be sent from any task, Timer Procedure or Interrupt Service Procedure to any mailbox or message exchange in the system. Messages sent to a message exchange are delivered to the message queue which matches the message priority. Within any message queue, messages are sorted chronologically according to the times at which messages were sent.
A message is a user defined structure (12 bytes minimum). Hence, one message could contain two 8-bit characters, one 16-bit integer and two 32-bit pointers. The content of a message is completely user defined.
AMX maintains a private set of envelopes for message passing. The number of envelopes is defined by the user when the AMX system is initialized. When a task, Timer Procedure or Interrupt Service Procedure calls AMX to send a message to a task, AMX copies the sender's message into an envelope. The envelope is then attached to the end of the message queue of the mailbox or message exchange to which the message is destined. Recall that for a message exchange, the particular message queue is selected according to the priority specified by the message sender.
Any task, Timer Procedure or Interrupt Service Procedure can acquire a message from a mailbox or message exchange. When a task asks for a message, it will be given the first available message. In the case of a message exchange, that will be the highest priority available message. If no message is available, the task has two options. It can continue execution and request a message again later. Alternatively, it can wait for a message to arrive. Obviously, Timer Procedures and Interrupt Service Procedures cannot wait for messages.
When a task chooses to wait for a message to arrive at the mailbox or message exchange, it can specify an optional timeout interval. If no message arrives within that interval, the task will resume execution with an error indication to that effect.
If more than one task waits at a mailbox or message exchange, the tasks are ordered in a wait queue according to the wait priority specified by each task. When a message arrives, it will be given to the task at the head of the wait queue. Separate wait queues are provided for each mailbox and message exchange.
The task's wait priority is not to be confused with the message exchange message priority. The message priority determines the priority ordering of messages in the message exchange when no task is waiting for a message. The task's wait priority determines the order of tasks in the wait queue when more than one task is waiting for a message to arrive at an empty mailbox or message exchange.
To satisfy those rare occasions in which a task must examine a mailbox or message exchange, AMX provides a status request. Included in the status is a count of the number of messages outstanding in each message queue. If no messages are present in the mailbox or message exchange, the status indicates the number of tasks, if any, waiting for the arrival of a message.
AMX also allows a task to flush a mailbox or message exchange. Any messages present in the mailbox or message exchange are removed; the message envelopes are reclaimed by AMX. Any task waiting for a message to arrive at the mailbox or message exchange are forced to resume execution with an error indication that they were flushed without receiving a message.
Tasks can easily be synchronized using a mailbox or message exchange. A task sends a message to a mailbox (or message exchange) and tells AMX that it wishes to wait for an answer back from the task which eventually receives the message. The task which receives the message acknowledges its receipt with a call to cjtkmsgack() in which it provides an answer-back status for return by AMX to the task which sent the message. The receiving task does not even have to know who the sender is.
Designers can define their own mailboxes and message exchanges and decide who is allowed to send messages to them and acquire messages from them. Such designs permit one or more message senders (producers) to asynchronously deliver messages to one or more receivers (consumers) whose identity is unknown to the producer.
The flexibility of a mailbox or message exchange comes from the fact that any number of consumers and producers can rendezvous without explicit knowledge of each other. Each consumer and producer only needs to know which mailbox or message exchange to use. No consumer or producer owns the mailbox or message exchange.
 |
|
Mailbox and Message Exchange Managers |
| Function |
Service |
| cjmbcreate |
Create a mailbox |
| cjmbdelete |
Delete a mailbox |
| cjmbsend |
Send a message to a mailbox
Optionally wait for acknowledgement of receipt of the message |
| cjmbwait |
Wait for a message (options: no wait or timeout after specified interval) |
| cjmbflush |
Flush all messages or waiting tasks from a mailbox |
| cjmbstatus |
Fetch status of a mailbox |
| |
| cjmxcreate |
Create a message exchange |
| cjmxdelete |
Delete a message exchange |
| cjmxsend |
Send a message at one of four message priorities
(0 = highest; 3 = lowest)
Optionally wait for acknowledgement of receipt of the message |
| cjmxwait |
Wait for a message (options: no wait or timeout after specified interval) |
| cjmxflush |
Flush all messages or waiting tasks from a message exchange |
| cjmxstatus |
Fetch status of a message exchange |
|
|