doc: Edit microkerenel_mailboxes for ReST syntax, content
flow, readability Add some :dfn: syntax, spelling fixes, and minor edits Change-Id: Ia37406ccccde677150dbff5da95d53c3917b1efb Signed-off-by: L.S. Cook <leonax.cook@intel.com>
This commit is contained in:
parent
7f14e706ec
commit
5e46cfd2d0
1 changed files with 65 additions and 65 deletions
|
@ -6,14 +6,14 @@ Mailboxes
|
||||||
Concepts
|
Concepts
|
||||||
********
|
********
|
||||||
|
|
||||||
The microkernel's mailbox object type is an implementation of a traditional
|
The microkernel's :dfn:`mailbox` object type is an implementation of a
|
||||||
message queue.
|
traditional message queue.
|
||||||
|
|
||||||
A mailbox allows tasks to exchange messages. A task that sends a message
|
A mailbox allows tasks to exchange messages. A task that sends a message is
|
||||||
is known as the *sending task*, while a task that receives the message
|
known as the *sending task*, while a task that receives the message is known
|
||||||
is known as the *receiving task*. Messages may not be sent or received
|
as the *receiving task*. Messages may not be sent or received by fibers or
|
||||||
by fibers or ISRs, nor may a given message be received by more than one task
|
ISRs, nor may a given message be received by more than one task;
|
||||||
(i.e. point-to-multipoint messaging is not supported).
|
point-to-multipoint messaging is not supported.
|
||||||
|
|
||||||
A mailbox has a queue of messages that have been sent, but not yet received.
|
A mailbox has a queue of messages that have been sent, but not yet received.
|
||||||
The messages in the queue are sorted by priority, allowing a higher priority
|
The messages in the queue are sorted by priority, allowing a higher priority
|
||||||
|
@ -21,45 +21,45 @@ message to be received before a lower priority message that was sent earlier.
|
||||||
Messages of equal priority are handled in a first in, first out manner.
|
Messages of equal priority are handled in a first in, first out manner.
|
||||||
|
|
||||||
Any number of mailboxes can be defined in a microkernel system. Each mailbox
|
Any number of mailboxes can be defined in a microkernel system. Each mailbox
|
||||||
has a name that uniquely identifies it. A mailbox does not limit the number
|
needs a **name** that uniquely identifies it. A mailbox does not limit the
|
||||||
of messages it can queue, nor does it place limits on the size of the messages
|
number of messages it can queue, nor does it place limits on the size of the
|
||||||
it handles.
|
message it handles.
|
||||||
|
|
||||||
The content of a message is stored in an array of bytes, called the
|
The content of a message is stored in an array of bytes, called the
|
||||||
*message data*. The size and format of the message data is application-defined,
|
*message data*. The size and format of the message data is application-defined,
|
||||||
and can vary from one message to the next. Message data may be stored
|
and can vary from one message to the next. Message data may be stored in a
|
||||||
in a buffer provided by the task that sends or receives the message,
|
buffer provided by the task that sends or receives the message, or in a memory
|
||||||
or in a memory pool block. The message data portion of a message is optional;
|
pool block. The message data portion of a message is optional; a message without
|
||||||
a message without any message data is called an *empty message*.
|
any message data is called an *empty message*.
|
||||||
|
|
||||||
The lifecycle of a message is fairly simple. A message is created when it
|
The life cycle of a message is fairly simple. A message is created when it
|
||||||
is given to a mailbox by the sending task. The message is then owned
|
is given to a mailbox by the sending task. The message is then owned
|
||||||
by the mailbox until it is given to a receiving task. The receiving task may
|
by the mailbox until it is given to a receiving task. The receiving task may
|
||||||
retrieve the message data when it receives the message from the mailbox,
|
retrieve the message data when it receives the message from the mailbox,
|
||||||
or it may perform data retrieval during a second, subsequent mailbox operation.
|
or it may perform data retrieval during a second, subsequent mailbox operation.
|
||||||
Only when data retrieval has been performed is the message deleted
|
Only when data retrieval has been performed is the message deleted by the
|
||||||
by the mailbox.
|
mailbox.
|
||||||
|
|
||||||
Messages can be exchanged non-anonymously or anonymously. A sending task
|
A message can be exchanged non-anonymously or anonymously between a :dfn:`sending`
|
||||||
can specify the name of the task to which the message is being sent,
|
and :dfn:`receiving` task. A sending task can specify the name of the task to which
|
||||||
or it can specify that any task may receive the message. Likewise, a receiving
|
the message is being sent, or it can specify that any task may receive the message.
|
||||||
task can specify the name of the task it wishes to receive a message from,
|
Likewise, a receiving task can specify the name of the task from which it wishes to
|
||||||
or it can specify that it is willing to receive a message from any task.
|
receive a message, or it can specify that it is willing to receive a message from
|
||||||
A message is exchanged only if the requirements of both the sending task and
|
any task. A message is exchanged only when the requirements for both the sending task
|
||||||
receiving task can both be satisfied; such tasks are said to be *compatible*.
|
and receiving task are satisfied; such tasks are said to be *compatible*.
|
||||||
|
|
||||||
For example, if task A sends a message to task B it will be received by task B
|
For example, task A sends a message to task B, but it will be received by task B
|
||||||
if the latter tries to receive a message from task A (or from any task), but
|
only if the latter tries to receive a message from task A (or from any task). The
|
||||||
not if task B tries to receive a message from task C. The message can never
|
exchange will not occur if task B tries to receive a message from task C. The message
|
||||||
be received by task C, even if it is trying to receive a message from task A
|
can never be received by task C, even if it is trying to receive a message from task
|
||||||
(or from any task).
|
A (or from any task).
|
||||||
|
|
||||||
Messages can be exchanged sychronously or asynchronously. In a synchronous
|
Messages can be exchanged :dfn:`synchronously` or :dfn:`asynchronously`. In a
|
||||||
exchange the sending task blocks until the message has been fully processed
|
synchronous exchange, the sending task blocks until the message has been fully
|
||||||
by the receiving task. In an asynchronous exchange the sending task does not
|
processed by the receiving task. In an asynchronous exchange, the sending task
|
||||||
wait until the message has been received by another task before continuing,
|
does not wait until the message has been received by another task before continuing;
|
||||||
thereby allowing the task to do other work (such as gathering data that will be
|
this allows the task to do other work (such as gather data that will be used
|
||||||
used in the next message) before the message is given to a receiving task and
|
in the next message) *before* the message is given to a receiving task and
|
||||||
fully processed. The technique used for a given message exchange is determined
|
fully processed. The technique used for a given message exchange is determined
|
||||||
by the sending task.
|
by the sending task.
|
||||||
|
|
||||||
|
@ -72,12 +72,12 @@ if a previously sent message still exists before sending a subsequent message.
|
||||||
Message Descriptor
|
Message Descriptor
|
||||||
==================
|
==================
|
||||||
|
|
||||||
A message descriptor is a data structure that specifies where a message's data
|
A :dfn:`message descriptor` is a data structure that specifies where a message's
|
||||||
is located and how the message is to be handled by the mailbox. Both the
|
data is located, and how the message is to be handled by the mailbox. Both the
|
||||||
sending task and the receiving task pass a message descriptor to the mailbox
|
sending task and the receiving task pass a message descriptor to the mailbox
|
||||||
when accessing a mailbox. The mailbox uses both message descriptors to perform
|
when accessing a mailbox. The mailbox uses both message descriptors to perform
|
||||||
a message exchange between compatible sending and receiving tasks. The mailbox
|
a message exchange between compatible sending and receiving tasks. The mailbox
|
||||||
also updates some fields of the descriptors during the exchange to allow both
|
also updates some fields of the descriptors during the exchange, allowing both
|
||||||
tasks to know what occurred.
|
tasks to know what occurred.
|
||||||
|
|
||||||
A message descriptor is a structure of type :c:type:`struct k_msg`. The fields
|
A message descriptor is a structure of type :c:type:`struct k_msg`. The fields
|
||||||
|
@ -85,7 +85,7 @@ listed below are available for application use; all other fields are for
|
||||||
kernel use only.
|
kernel use only.
|
||||||
|
|
||||||
:c:option:`info`
|
:c:option:`info`
|
||||||
A 32 bit value that is exchanged by the message sender and receiver,
|
A 32-bit value that is exchanged by the message sender and receiver,
|
||||||
and whose meaning is defined by the application. This exchange is
|
and whose meaning is defined by the application. This exchange is
|
||||||
bi-directional, allowing the sender to pass a value to the receiver
|
bi-directional, allowing the sender to pass a value to the receiver
|
||||||
during any message exchange, and allowing the receiver to pass a value
|
during any message exchange, and allowing the receiver to pass a value
|
||||||
|
@ -129,27 +129,27 @@ Sending a Message
|
||||||
=================
|
=================
|
||||||
|
|
||||||
A task sends a message by first creating the message data to be sent (if any).
|
A task sends a message by first creating the message data to be sent (if any).
|
||||||
The data may be placed in a message buffer---such as an array or structure
|
The data may be placed in a message buffer -- such as an array or structure
|
||||||
variable---whose contents are copied to an area supplied by the receiving task
|
variable -- whose contents are copied to an area supplied by the receiving task
|
||||||
during the message exchange. Alternatively, the data may be placed in a block
|
during the message exchange. Alternatively, the data may be placed in a block
|
||||||
allocated from a memory pool, which is handed off to the receiving task
|
allocated from a memory pool, which gets handed off to the receiving task
|
||||||
during the exchange. A message buffer is typically used when the amount of
|
during the exchange. A message buffer is typically used when the data volume
|
||||||
data involved is small, and the cost of copying the data is less than the cost
|
flowing through is small, and the cost of copying the data is less than the
|
||||||
of allocating and freeing a memory pool block. A memory pool block *must*
|
cost of allocating and freeing a memory pool block. A memory pool block *must*
|
||||||
be used when a non-empty message is sent asynchronously.
|
be used when a non-empty message is sent asynchronously.
|
||||||
|
|
||||||
Next, the task creates a message descriptor that characterizes the message
|
Next, the task creates a message descriptor that characterizes the message
|
||||||
to be sent, as described in the previous section.
|
to be sent, as described in the previous section.
|
||||||
|
|
||||||
Finally, the task calls one of the mailbox send APIs to initiate the message
|
Finally, the task calls one of the mailbox send APIs to initiate the
|
||||||
exchange. The message is immediately given to a compatible receiving task,
|
message exchange. The message is immediately given to a compatible receiving
|
||||||
if one is currently waiting for a message. Otherwise, the message is added
|
task, if one is currently waiting for a message. Otherwise, the message is added
|
||||||
to the mailbox's queue of messages, according to the priority specified by
|
to the mailbox's queue of messages, according to the priority specified by
|
||||||
the sending task. Typically, a sending task sets the message priority to
|
the sending task. Typically, a sending task sets the message priority to
|
||||||
its own task priority level, allowing messages sent by higher priority tasks
|
its own task priority level, allowing messages sent by higher priority tasks
|
||||||
to take precedence over those sent by lower priority tasks.
|
to take precedence over those sent by lower priority tasks.
|
||||||
|
|
||||||
For a synchronous send operation the operation normally completes when a
|
For a synchronous send operation, the operation normally completes when a
|
||||||
receiving task has both received the message and retrieved the message data.
|
receiving task has both received the message and retrieved the message data.
|
||||||
If the message is not received before the waiting period specified by the
|
If the message is not received before the waiting period specified by the
|
||||||
sending task is reached, the message is removed from the mailbox's queue
|
sending task is reached, the message is removed from the mailbox's queue
|
||||||
|
@ -159,18 +159,18 @@ which task received the message and how much data was exchanged, as well as
|
||||||
the application-defined info value supplied by the receiving task.
|
the application-defined info value supplied by the receiving task.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
A synchronous send operation may block the sending task indefinitely---even
|
A synchronous send operation may block the sending task indefinitely -- even
|
||||||
when the task specifies a maximum waiting period---since the waiting period
|
when the task specifies a maximum waiting period -- since the waiting period
|
||||||
only limits how long the mailbox waits before the message is received
|
only limits how long the mailbox waits before the message is received
|
||||||
by another task. Once a message is received there is no limit to the time
|
by another task. Once a message is received there is no limit to the time
|
||||||
the receiving task may take to retrieve the message data and unblock
|
the receiving task may take to retrieve the message data and unblock
|
||||||
the sending task.
|
the sending task.
|
||||||
|
|
||||||
For an asynchronous send operation the operation always completes immediately.
|
For an asynchronous send operation, the operation always completes immediately.
|
||||||
This allows the sending task to continue processing regardless of whether the
|
This allows the sending task to continue processing regardless of whether the
|
||||||
message is immediately given to a receiving task or is queued by the mailbox.
|
message is immediately given to a receiving task or is queued by the mailbox.
|
||||||
The sending task may optionally specify a semaphore that the mailbox gives
|
The sending task may optionally specify a semaphore that the mailbox gives
|
||||||
when the message is deleted by the mailbox (i.e. when the message has been
|
when the message is deleted by the mailbox (for example, when the message has been
|
||||||
received and its data retrieved by a receiving task). The use of a semaphore
|
received and its data retrieved by a receiving task). The use of a semaphore
|
||||||
allows the sending task to easily implement a flow control mechanism that
|
allows the sending task to easily implement a flow control mechanism that
|
||||||
ensures that the mailbox holds no more than an application-specified number
|
ensures that the mailbox holds no more than an application-specified number
|
||||||
|
@ -192,12 +192,12 @@ successfully the receiving task can examine the message descriptor
|
||||||
to determine which task sent the message, how much data was exchanged,
|
to determine which task sent the message, how much data was exchanged,
|
||||||
and the application-defined info value supplied by the sending task.
|
and the application-defined info value supplied by the sending task.
|
||||||
|
|
||||||
The receiving task controls both the amount of data it retrieves from an
|
The receiving task controls both the quantity of data it retrieves from an
|
||||||
incoming message and where the data ends up. The task may choose to take
|
incoming message and where the data ends up. The task may choose to take
|
||||||
all of the data in the message, to take only the initial part of the data,
|
all of the data in the message, to take only the initial part of the data,
|
||||||
or to take no data at all. Similarly, the task may choose to have the data
|
or to take no data at all. Similarly, the task may choose to have the data
|
||||||
copied into a buffer area of its choice or to have it placed in a memory
|
copied into a buffer area of its choice or to have it placed in a memory
|
||||||
pool block. A message buffer is typically used when the amount of data
|
pool block. A message buffer is typically used when the volume of data
|
||||||
involved is small, and the cost of copying the data is less than the cost
|
involved is small, and the cost of copying the data is less than the cost
|
||||||
of allocating and freeing a memory pool block.
|
of allocating and freeing a memory pool block.
|
||||||
|
|
||||||
|
@ -363,7 +363,7 @@ For example, the following code defines a private mailbox named ``PRIV_MBX``.
|
||||||
The mailbox ``PRIV_MBX`` can be used in the same style as those
|
The mailbox ``PRIV_MBX`` can be used in the same style as those
|
||||||
defined in the MDEF.
|
defined in the MDEF.
|
||||||
|
|
||||||
To utilize this mailbox from a different source file use the following syntax:
|
To use this mailbox from a different source file use the following syntax:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
|
@ -536,10 +536,10 @@ Example: Sending an Asynchronous Mailbox Message
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
This code uses a mailbox to send asynchronous messages using memory blocks
|
This code uses a mailbox to send asynchronous messages using memory blocks
|
||||||
obtained from TXPOOL, thereby eliminating unneeded data copying when exchanging
|
obtained from ``TXPOOL``, thereby eliminating unneeded data copying when
|
||||||
large messages. The optional semaphore capability is used to hold off
|
exchanging large messages. The optional semaphore capability is used to hold off
|
||||||
the sending of a new message until the previous message has been consumed,
|
the sending of a new message until the previous message has been consumed,
|
||||||
so that a backlog of messages doesn't build up if the consuming task is unable
|
so that a backlog of messages doesn't build up when the consuming task is unable
|
||||||
to keep up.
|
to keep up.
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
@ -620,7 +620,7 @@ a large message.
|
||||||
.. note::
|
.. note::
|
||||||
An incoming message that was sent synchronously is also processed correctly
|
An incoming message that was sent synchronously is also processed correctly
|
||||||
by this algorithm, since the mailbox automatically creates a memory block
|
by this algorithm, since the mailbox automatically creates a memory block
|
||||||
containing the message data using RXPOOL. However, the performance benefit
|
containing the message data using ``RXPOOL``. However, the performance benefit
|
||||||
of using the asynchronous approach is lost.
|
of using the asynchronous approach is lost.
|
||||||
|
|
||||||
APIs
|
APIs
|
||||||
|
@ -629,16 +629,16 @@ APIs
|
||||||
The following APIs for mailbox operations are provided by the kernel:
|
The following APIs for mailbox operations are provided by the kernel:
|
||||||
|
|
||||||
:c:func:`task_mbox_put()`
|
:c:func:`task_mbox_put()`
|
||||||
Sends synchronous message to a receiving task, with time limited waiting.
|
Send synchronous message to a receiving task, with time limited waiting.
|
||||||
|
|
||||||
:c:func:`task_mbox_block_put()`
|
:c:func:`task_mbox_block_put()`
|
||||||
Sends asynchrnonous message to a receiving task, or to a mailbox queue.
|
Send asynchronous message to a receiving task, or to a mailbox queue.
|
||||||
|
|
||||||
:c:func:`task_mbox_get()`
|
:c:func:`task_mbox_get()`
|
||||||
Gets message from a mailbox, with time limited waiting.
|
Get message from a mailbox, with time limited waiting.
|
||||||
|
|
||||||
:c:func:`task_mbox_data_get()`
|
:c:func:`task_mbox_data_get()`
|
||||||
Retrieves message data into a buffer.
|
Retrieve message data into a buffer.
|
||||||
|
|
||||||
:c:func:`task_mbox_data_block_get()`
|
:c:func:`task_mbox_data_block_get()`
|
||||||
Retrieves message data into a block, with time limited waiting.
|
Retrieve message data into a block, with time limited waiting.
|
Loading…
Add table
Add a link
Reference in a new issue