SysLink API Reference
2.21.03.11
|
MessageQ Manager.
============================================================================
The MessageQ module supports the structured sending and receiving of variable length messages. This module can be used for homogeneous (DSP to DSP) or heterogeneous (Arm to DSP) multi-processor messaging.
MessageQ provides more sophisticated messaging than other modules. It is typically used for complex situations such as multi-processor messaging.
The following are key features of the MessageQ module:
Messages are sent and received by being placed on and removed from a message queue. A reader is a thread that gets (reads) messages from a message queue. A writer is a thread that puts (writes) a message to a message queue. Each message queue has one reader and can have many writers. A thread may read from or write to multiple message queues.
Conceptually, the reader thread owns a message queue. The reader thread creates a message queue. The writer threads open a created message queue to get access to them.
Message queues are identified by a system-wide unique name. Internally, MessageQ uses the NameServer module for managing these names. The names are used for opening a message queue.
Messages must be allocated from the MessageQ module. Once a message is allocated, it can be sent to any message queue. Once a message is sent, the writer loses ownership of the message and should not attempt to modify the message. Once the reader receives the message, it owns the message. It may either free the message or re-use the message.
Messages in a message queue can be of variable length. The only requirement is that the first field in the definition of a message must be a MessageQ_MsgHeader structure. For example:
The MessageQ API uses the MessageQ_MsgHeader internally. Your application should not modify or directly access the fields in the MessageQ_MsgHeader.
All messages sent via the MessageQ module must be allocated from a heap. The heap can also be used for other memory allocation not related to MessageQ.
An application can use multiple heaps. The purpose of having multiple heaps is to allow an application to regulate its message usage. For example, an application can allocate critical messages from one heap of fast on-chip memory and non-critical messages from another heap of slower external memory.
The MessageQ_registerHeap() API is used to assign a MessageQ heapId to a heap. When allocating a message, the heapId is used, not the heap handle. This heapId is actually placed into the message (part of the MessageQ_MsgHeader). Care must be taken when assigning heapIds. Refer to the MessageQ_registerHeap() API description for more details.
MessageQ also supports the usage of messages that are not allocated via the MessageQ_alloc() function. Please refer to the MessageQ_staticMsgInit() function description for more details.
MessageQ supports reads/writes of different thread models. This is accomplished by having the creator of the message queue specify a synchronizer via the MessageQ_Params::synchronizer configuration parameter. The synchronizer is signaled whenever the MessageQ_put() is called. The synchronizer waits if MessageQ_get() is called and there are no messages.
Since ISyncs are binary, the reader must drain the message queue of all messages before waiting for another signal. For example, if the reader was a SYSBIOS Swi, the synchronizer instance could be a SyncSwi. If a MessageQ_put was called, the Swi_post() would be called. The Swi would run and it must call MessageQ_get until no messages are returned.
The MessageQ header should be included in an application as follows:
============================================================================
#include <ti/ipc/MultiProc.h>
Go to the source code of this file.
Data Structures | |
struct | MessageQ_Params |
Structure defining parameters for the MessageQ module. More... | |
struct | MessageQ_MsgHeader |
Required first field in every message. More... |
Macros | |
#define | MessageQ_S_BUSY 2 |
The resource is still in use. | |
#define | MessageQ_S_ALREADYSETUP 1 |
The module has been already setup. | |
#define | MessageQ_S_SUCCESS 0 |
Operation is successful. | |
#define | MessageQ_E_FAIL -1 |
Operation is not successful. | |
#define | MessageQ_E_INVALIDARG -2 |
There is an invalid argument. | |
#define | MessageQ_E_MEMORY -3 |
Operation resulted in memory failure. | |
#define | MessageQ_E_ALREADYEXISTS -4 |
The specified entity already exists. | |
#define | MessageQ_E_NOTFOUND -5 |
Unable to find the specified entity. | |
#define | MessageQ_E_TIMEOUT -6 |
Operation timed out. | |
#define | MessageQ_E_INVALIDSTATE -7 |
Module is not initialized. | |
#define | MessageQ_E_OSFAILURE -8 |
A failure occurred in an OS-specific call. | |
#define | MessageQ_E_RESOURCE -9 |
Specified resource is not available. | |
#define | MessageQ_E_RESTART -10 |
Operation was interrupted. Please restart the operation. | |
#define | MessageQ_E_INVALIDMSG -11 |
An invalid message was encountered. | |
#define | MessageQ_E_NOTOWNER -12 |
Not the owner. | |
#define | MessageQ_E_REMOTEACTIVE -13 |
Operation resulted in error. | |
#define | MessageQ_E_INVALIDHEAPID -14 |
An invalid heap id was encountered. | |
#define | MessageQ_E_INVALIDPROCID -15 |
An invalid MultiProc id was encountered. | |
#define | MessageQ_E_MAXREACHED -16 |
The max has been reached. | |
#define | MessageQ_E_UNREGISTEREDHEAPID -17 |
Attempting to use an unregistered heap id. | |
#define | MessageQ_E_CANNOTFREESTATICMSG -18 |
Trying to free a statically initialized message. | |
#define | MessageQ_E_UNBLOCKED -19 |
MessageQ was unblocked. | |
#define | MessageQ_FOREVER ~(0) |
Used as the timeout value to specify wait forever. | |
#define | MessageQ_INVALIDMSGID 0xffff |
Invalid message id. | |
#define | MessageQ_INVALIDMESSAGEQ 0xffff |
Invalid message queue. | |
#define | MessageQ_PRIORITYMASK 0x3 |
Mask to extract priority setting. | |
#define | MessageQ_getDstQueue(msg) |
Extract the destination queue ID from a message. | |
#define | MessageQ_getMsgId(msg) (((MessageQ_Msg) (msg))->msgId) |
Retrieves the message ID of a message. | |
#define | MessageQ_getMsgSize(msg) (((MessageQ_Msg) (msg))->msgSize) |
Returns the size of the specified message. This function is helpful when re-using a message. | |
#define | MessageQ_getMsgPri(msg) ((((MessageQ_Msg) (msg))->flags & MessageQ_PRIORITYMASK)) |
Gets the message priority of a message. | |
#define | MessageQ_getProcId(queueId) ((UInt16)((queueId) >> 16)) |
Returns the MultiProc processor id on which the queue resides. | |
#define | MessageQ_getReplyQueue(msg) |
Retrieves the message queue ID from a message. | |
#define | MessageQ_setMsgId(msg, id) ((MessageQ_Msg) (msg))->msgId = (id) |
Sets the message id in a message. | |
#define | MessageQ_setMsgPri(msg, priority) (((MessageQ_Msg) (msg))->flags = ((priority) & MessageQ_PRIORITYMASK)) |
Sets the message priority of a message. |
Typedefs | |
typedef UInt32 | MessageQ_QueueId |
A 32-bit value that uniquely identifies a message queue. | |
typedef UInt16 | MessageQ_QueueIndex |
Local queue index. | |
typedef struct MessageQ_Object * | MessageQ_Handle |
MessageQ_Handle type. | |
typedef MessageQ_MsgHeader * | MessageQ_Msg |
Typedef for ease of use. |
Enumerations | |
enum | MessageQ_Priority { MessageQ_NORMALPRI = 0, MessageQ_HIGHPRI = 1, MessageQ_RESERVEDPRI = 2, MessageQ_URGENTPRI = 3 } |
Message priority. More... |
Functions | |
Void | MessageQ_Params_init (MessageQ_Params *params) |
Initialize MessageQ_Params. | |
MessageQ_Handle | MessageQ_create (String name, const MessageQ_Params *params) |
Create a MessageQ instance. | |
Int | MessageQ_delete (MessageQ_Handle *handlePtr) |
Delete a created MessageQ instance. | |
Int | MessageQ_open (String name, MessageQ_QueueId *queueId) |
Open a message queue. | |
Int | MessageQ_close (MessageQ_QueueId *queueId) |
Close the opened handle. | |
MessageQ_Msg | MessageQ_alloc (UInt16 heapId, UInt32 size) |
Allocates a message from the heap. | |
Int | MessageQ_free (MessageQ_Msg msg) |
Frees a message back to the heap. | |
Int | MessageQ_registerHeap (Ptr heap, UInt16 heapId) |
Register a heap with MessageQ. | |
Int | MessageQ_unregisterHeap (UInt16 heapId) |
Unregister a heap with MessageQ. | |
Void | MessageQ_setMsgTrace (MessageQ_Msg msg, Bool traceFlag) |
Sets the message tracing flag on a given message. | |
Void | MessageQ_staticMsgInit (MessageQ_Msg msg, UInt32 size) |
Initializes a message not obtained from MessageQ_alloc() | |
Int | MessageQ_get (MessageQ_Handle handle, MessageQ_Msg *msg, UInt timeout) |
Gets a message from the message queue. | |
Int | MessageQ_put (MessageQ_QueueId queueId, MessageQ_Msg msg) |
Place a message onto a message queue. | |
Int | MessageQ_count (MessageQ_Handle handle) |
Returns the number of messages in a message queue. | |
UInt32 | MessageQ_getQueueId (MessageQ_Handle handle) |
Returns the QueueId associated with the handle. | |
Void | MessageQ_setReplyQueue (MessageQ_Handle handle, MessageQ_Msg msg) |
Embeds a source message queue into a message. | |
Void | MessageQ_unblock (MessageQ_Handle handle) |
Unblocks a MessageQ. |
#define MessageQ_S_BUSY 2 |
The resource is still in use.
#define MessageQ_S_ALREADYSETUP 1 |
The module has been already setup.
#define MessageQ_S_SUCCESS 0 |
Operation is successful.
#define MessageQ_E_FAIL -1 |
Operation is not successful.
#define MessageQ_E_INVALIDARG -2 |
There is an invalid argument.
#define MessageQ_E_MEMORY -3 |
Operation resulted in memory failure.
#define MessageQ_E_ALREADYEXISTS -4 |
The specified entity already exists.
#define MessageQ_E_NOTFOUND -5 |
Unable to find the specified entity.
#define MessageQ_E_TIMEOUT -6 |
Operation timed out.
#define MessageQ_E_INVALIDSTATE -7 |
Module is not initialized.
#define MessageQ_E_OSFAILURE -8 |
A failure occurred in an OS-specific call.
#define MessageQ_E_RESOURCE -9 |
Specified resource is not available.
#define MessageQ_E_RESTART -10 |
Operation was interrupted. Please restart the operation.
#define MessageQ_E_INVALIDMSG -11 |
An invalid message was encountered.
#define MessageQ_E_NOTOWNER -12 |
Not the owner.
#define MessageQ_E_REMOTEACTIVE -13 |
Operation resulted in error.
#define MessageQ_E_INVALIDHEAPID -14 |
An invalid heap id was encountered.
#define MessageQ_E_INVALIDPROCID -15 |
An invalid MultiProc id was encountered.
#define MessageQ_E_MAXREACHED -16 |
The max has been reached.
#define MessageQ_E_UNREGISTEREDHEAPID -17 |
Attempting to use an unregistered heap id.
#define MessageQ_E_CANNOTFREESTATICMSG -18 |
Trying to free a statically initialized message.
#define MessageQ_E_UNBLOCKED -19 |
MessageQ was unblocked.
#define MessageQ_FOREVER ~(0) |
Used as the timeout value to specify wait forever.
#define MessageQ_INVALIDMSGID 0xffff |
Invalid message id.
#define MessageQ_INVALIDMESSAGEQ 0xffff |
Invalid message queue.
#define MessageQ_PRIORITYMASK 0x3 |
Mask to extract priority setting.
#define MessageQ_getDstQueue | ( | msg | ) |
Extract the destination queue ID from a message.
Can only be used on the same processor where the destination queue resides. This function should only be used by Message Queue Transport writers.
[in] | msg | Message of type MessageQ_Msg |
queueId | Destination message queue ID of type MessageQ_QueueId |
#define MessageQ_getMsgId | ( | msg | ) | (((MessageQ_Msg) (msg))->msgId) |
Retrieves the message ID of a message.
This function retrieves the message ID from the message. The MessageQ_setMsgId() function is used to insert the message ID.
The message id is part of the MessageQ_MsgHeader header and is in every MessageQ message. All message ids are initialized to MessageQ_INVALIDMSGID in the MessageQ_alloc() and MessageQ_staticMsgInit() calls.
[in] | msg | Message of type MessageQ_Msg |
msgId | 16-bit message ID from the message |
#define MessageQ_getMsgSize | ( | msg | ) | (((MessageQ_Msg) (msg))->msgSize) |
Returns the size of the specified message. This function is helpful when re-using a message.
[in] | msg | Message of type MessageQ_Msg |
size | Size of the message |
#define MessageQ_getMsgPri | ( | msg | ) | ((((MessageQ_Msg) (msg))->flags & MessageQ_PRIORITYMASK)) |
Gets the message priority of a message.
[in] | msg | Message of type MessageQ_Msg |
priority | Priority of the message |
#define MessageQ_getProcId | ( | queueId | ) | ((UInt16)((queueId) >> 16)) |
Returns the MultiProc processor id on which the queue resides.
Message queues reside on the processor that created them. This function allows the caller to determined on which processor the queue resides.
[in] | queueId | Unique MessageQ_QueueId that identifies the queue |
procId | The MultiProc id on which the queue resides |
#define MessageQ_getReplyQueue | ( | msg | ) |
Retrieves the message queue ID from a message.
This function along with the MessageQ_setReplyQueue() function can be used instead of the open function. The sender of a message can embed a messageQ into the message with the MessageQ_setReplyQueue() function. The receiver of the message can extract the message queue ID with this function.
This method is particularing useful in a client/server relationship where the server does not want to know who the clients are. The clients can embed their message queue into the message to the server and the server extracts it and uses it to reply.
[in] | msg | Message of type MessageQ_Msg |
queueId | Message queue ID of type MessageQ_QueueId |
#define MessageQ_setMsgId | ( | msg, | |
id | |||
) | ((MessageQ_Msg) (msg))->msgId = (id) |
Sets the message id in a message.
This function sets the message ID in the message. The MessageQ_getMsgId() function is used to retrieve the message ID. The message id is part of the MessageQ_MsgHeader header and is in every MessageQ message. All message ids are initialized to MessageQ_INVALIDMSGID in the MessageQ_alloc() and MessageQ_staticMsgInit() calls.
[in] | msg | Message of type MessageQ_Msg |
[in] | id | 16-bit value |
#define MessageQ_setMsgPri | ( | msg, | |
priority | |||
) | (((MessageQ_Msg) (msg))->flags = ((priority) & MessageQ_PRIORITYMASK)) |
Sets the message priority of a message.
[in] | msg | Message of type MessageQ_Msg |
[in] | priority | Priority of message to be set. |
typedef UInt32 MessageQ_QueueId |
A 32-bit value that uniquely identifies a message queue.
typedef UInt16 MessageQ_QueueIndex |
Local queue index.
typedef struct MessageQ_Object* MessageQ_Handle |
MessageQ_Handle type.
typedef MessageQ_MsgHeader* MessageQ_Msg |
Typedef for ease of use.
enum MessageQ_Priority |
Void MessageQ_Params_init | ( | MessageQ_Params * | params | ) |
Initialize MessageQ_Params.
[in] | params | Parameters required to create a MessageQ |
MessageQ_Handle MessageQ_create | ( | String | name, |
const MessageQ_Params * | params | ||
) |
Create a MessageQ instance.
The name supplied here does not have to be in persistent memory. The maximum length of the string supplied here, including the '\0' terminator is '32' by default.
There are no verifications to ensure that the name supplied in MessageQ_create() is unique across all processors. Caution must be exercised to ensure that each processor uses a unique name.
[in] | name | Name of the queue |
[in] | params | Initialized MessageQ parameters |
Int MessageQ_delete | ( | MessageQ_Handle * | handlePtr | ) |
Delete a created MessageQ instance.
This function deletes a created message queue instance. If the message queue is non-empty, any messages remaining in the queue will not be freed and will be lost.
[in,out] | handlePtr | Pointer to handle to delete. |
Int MessageQ_open | ( | String | name, |
MessageQ_QueueId * | queueId | ||
) |
Open a message queue.
MessageQ_open() is used to retrieve the queue id for a queue that has been created either locally or remotely. Note that the queueId is simply a 32 bit value that uniquely identifies a queue. Therefore, it is also possible to put a message on a queue whose queueId has been retrieved using any other method.
[in] | name | Name of queue to open |
[out] | queueId | QueueId that can be used in MessageQ_put() |
Int MessageQ_close | ( | MessageQ_QueueId * | queueId | ) |
Close the opened handle.
Only close a queueId that was returned from MessageQ_open().
[in] | queueId | Pointer to queueId to close |
MessageQ_Msg MessageQ_alloc | ( | UInt16 | heapId, |
UInt32 | size | ||
) |
Allocates a message from the heap.
This function allocates a message from the heap associated with the heapId. The first field of the message must be a MessageQ_MsgHeader structure. For example:
[in] | heapId | heapId |
[in] | size | size of requested message (including the MessageQ_MsgHeader). |
size
must be at least large enough to hold a MessageQ_MsgHeaderInt MessageQ_free | ( | MessageQ_Msg | msg | ) |
Frees a message back to the heap.
Frees the message back to the heap that was used to allocate it.
[in] | msg | Message to free. |
Register a heap with MessageQ.
This function registers a heap with MessageQ. The user selects a unique heapId associated with this heap. When a message is allocated via MessageQ_alloc(), the heapId is specified. Internally, MessageQ uses the heapId to access the heap.
Care must be taken when assigning heapIds. Internally MessageQ stores the heapId into the message. When the message is freed (via MessageQ_free()), the heapId is used to determine which heap to use. On systems with shared memory the heapIds must match on corresponding processors. For example, assume there is a heap called myHeap which acts on shared memory and processors 0 and 1 both use this heap. When you register the heap with MessageQ, the same heapId must be used on both processor 0 and 1.
If a heap is already registered for the specified heapId, no action is taken and MessageQ_E_ALREADYEXISTS is returned.
[in] | heap | Heap to register |
[in] | heapId | heapId associated with the heap |
Unregister a heap with MessageQ.
This function unregisters the heap associated with the heapId. Care must be taken to ensure that there are no outstanding messages allocated from this heap. If there are outstanding messages, an attempt to free the message will result in non-deterministic results.
[in] | heapId | Heap to unregister |
Void MessageQ_setMsgTrace | ( | MessageQ_Msg | msg, |
Bool | traceFlag | ||
) |
Sets the message tracing flag on a given message.
This function enables message tracing for a message. Tracing is offered in the form of Log messages that are output during operations on the message (i.e. MessageQ_free(), MessageQ_put(), etc).
msg | Message |
traceFlag | Message trace flag (TRUE = tracing enabled) |
Void MessageQ_staticMsgInit | ( | MessageQ_Msg | msg, |
UInt32 | size | ||
) |
Initializes a message not obtained from MessageQ_alloc()
There are several fields in the MessageQ_MsgHeader that are initialized by the MessageQ_alloc() function. MessageQ_staticMsgInit() can be used to initialize these fields for messages that are not allocated from MessageQ.
There is one strict constraint with using messages not allocated from MessageQ. The message cannot be freed via MessageQ_free(). This includes
msg | Message to initialize | |
[in] | size | Size of the message in MAUs |
size
must be at least large enough to hold a MessageQ_MsgHeader Int MessageQ_get | ( | MessageQ_Handle | handle, |
MessageQ_Msg * | msg, | ||
UInt | timeout | ||
) |
Gets a message from the message queue.
This function returns a status. It also returns a message in msg. If no message is available, it blocks on the synchronizer object until the synchronizer is signaled or a timeout occurs. The synchronizer is signaled, when Message_put is called on the MessageQ handle. If a timeout occurs, the msg is set to NULL and the status is MessageQ_E_TIMEOUT. If a timeout of zero is specified, the function returns immediately and if no message is available, the msg is set to NULL and the status is MessageQ_E_TIMEOUT. The MessageQ_E_UNBLOCKED status is return, if MessageQ_unblock is called on the MessageQ handle. If a message is successfully retrieved, the msg is set to the message and a MessageQ_S_SUCCESS status is returned.
[in] | handle | MessageQ handle |
[out] | msg | Pointer to the message |
[in] | timeout | Maximum duration to wait for a message in microseconds. |
Int MessageQ_put | ( | MessageQ_QueueId | queueId, |
MessageQ_Msg | msg | ||
) |
Place a message onto a message queue.
This call places the message onto the specified message queue. The message queue could be local or remote. The MessageQ module manages the delivery.
In the case where the queue is remote, MessageQ does not guarantee that the message is actually delivered before the MessageQ_put() call returns
The queue id must have been returned from one of the following functions:
After the message is placed onto the final destination, the queue's MessageQ_Params::synchronizer signal function is called.
The application loses ownership of the message once MessageQ_put() is called.
[in] | queueId | Destination MessageQ |
[in] | msg | Message to be sent. |
Int MessageQ_count | ( | MessageQ_Handle | handle | ) |
Returns the number of messages in a message queue.
This function returns the number of messages in a message queue.
[in] | handle | MessageQ handle |
UInt32 MessageQ_getQueueId | ( | MessageQ_Handle | handle | ) |
Returns the QueueId associated with the handle.
Since the MessageQ_put() function takes a QueueId, the creator of a message queue cannot send a message to itself without retrieving the QueueId. This function extracts the QueueId from the object.
[in] | handle | MessageQ handle |
Void MessageQ_setReplyQueue | ( | MessageQ_Handle | handle, |
MessageQ_Msg | msg | ||
) |
Embeds a source message queue into a message.
This function along with MessageQ_getReplyQueue() can be used instead of MessageQ_open(). The sender of a message can embed a messageQ into the message with this function. The receiver of the message can extract the message queue id with the MessageQ_getReplyQueue() function.
This method is particularly useful in a client/server relationship where the server does not want to know who the clients are. The clients can embed their message queue into the message to the server and the server extracts it and uses it to reply.
handle | MessageQ handle |
msg | Message to embed queue into |
Void MessageQ_unblock | ( | MessageQ_Handle | handle | ) |
Unblocks a MessageQ.
Unblocks a reader thread that is blocked on a MessageQ_get(). The MessageQ_get() call will return with status MessageQ_E_UNBLOCKED indicating that it returned due to a MessageQ_unblock() rather than a timeout or a received message. This call should only be used during a shutdown sequence in order to ensure that there is no blocked reader on a queue before deleting the queue. A queue may not be used after it has been unblocked.
MessageQ_unblock() works by raising a flag in the queue indicating that it is unblocked and then signaling the synchronizer that is configured with the target queue. If MessageQ_unblock() is called upon a queue that has no blocked listeners, then any subsequent MessageQ_get will not block and will immediately return MessageQ_E_UNBLOCKED regardless of whether there is a message on the queue.
Restrictions:
[in] | handle | MessageQ handle |