1 /*
2 * Copyright (c) 2012-2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
33 /**
34 * @file ti/ipc/MessageQ.h
35 *
36 * @brief MessageQ Manager
37 *
38 * The MessageQ module supports the structured sending and receiving of
39 * variable length messages. This module can be used for homogeneous
40 * (e.g. DSP to DSP) or heterogeneous (e.g. ARM to DSP) multi-processor
41 * messaging.
42 *
43 * MessageQ provides more sophisticated messaging than other modules. It is
44 * typically used for complex situations such as multi-processor messaging.
45 *
46 * The following are key features of the MessageQ module:
47 * - Writers and readers can be relocated to another processor with no
48 * runtime code changes.
49 * - Timeouts are allowed when receiving messages.
50 * - Readers can determine the writer and reply back.
51 * - Receiving a message is deterministic when the timeout is zero.
52 * - Messages can reside on any message queue.
53 * - Supports zero-copy transfers.
54 * - Can send and receive from any type of thread.
55 * - Notification mechanism is specified by application.
56 * - Allows QoS (quality of service) on message buffer pools. For example,
57 * using specific buffer pools for specific message queues.
58 *
59 * Messages are sent and received by being placed on and removed from a
60 * message queue. A reader is a thread that gets (reads) messages from a
61 * message queue. A writer is a thread that puts (writes) a message to a
62 * message queue. Each message queue has one reader and can have many writers.
63 * A thread may read from or write to multiple message queues.
64 *
65 * Conceptually, the reader thread owns a message queue. The reader thread
66 * creates a message queue. The writer threads open a created message queue
67 * to get access to them.
68 *
69 * Message queues are identified by a system-wide unique name. Internally,
70 * MessageQ uses the NameServer module for managing
71 * these names. The names are used for opening a message queue.
72 *
73 * Messages must be allocated from the MessageQ module. Once a message is
74 * allocated, it can be sent to any message queue. Once a message is sent, the
75 * writer loses ownership of the message and should not attempt to modify the
76 * message. Once the reader receives the message, it owns the message. It
77 * may either free the message or re-use the message.
78 *
79 * Messages in a message queue can be of variable length. The only
80 * requirement is that the first field in the definition of a message must be a
81 * #MessageQ_MsgHeader structure. For example:
82 * @code
83 * typedef struct MyMsg {
84 * MessageQ_MsgHeader header;
85 * ...
86 * } MyMsg;
87 * @endcode
88 *
89 * The MessageQ API uses the MessageQ_MsgHeader internally. Your application
90 * should not modify or directly access the fields in the MessageQ_MsgHeader.
91 *
92 * All messages sent via the MessageQ module must be allocated from a
93 * heap. The heap can also be used for other memory allocation not related to
94 * MessageQ.
95 *
96 * An application can use multiple heaps. The purpose of having multiple
97 * heaps is to allow an application to regulate its message usage. For
98 * example, an application can allocate critical messages from one heap of fast
99 * on-chip memory and non-critical messages from another heap of slower
100 * external memory.
101 *
102 * The MessageQ_registerHeap() API is used to
103 * assign a MessageQ heapId to a heap. When allocating a message, the heapId
104 * is used, not the heap handle. This heapId is actually placed into the
105 * message (part of the #MessageQ_MsgHeader). Care must be taken when
106 * assigning heapIds. Refer to the MessageQ_registerHeap() API description for
107 * more details.
108 *
109 * MessageQ also supports the usage of messages that are not allocated via the
110 * MessageQ_alloc() function. Please refer to the MessageQ_staticMsgInit()
111 * function description for more details.
112 *
113 * MessageQ supports reads/writes of different thread models. This is
114 * accomplished by having the creator of the message queue specify a
115 * synchronizer via the #MessageQ_Params.synchronizer
116 * configuration parameter. The synchronizer is signaled whenever the
117 * MessageQ_put() is called. The synchronizer waits if MessageQ_get() is called
118 * and there are no messages.
119 *
120 * Since ISyncs are binary, the reader must drain the message queue of all
121 * messages before waiting for another signal. For example, if the reader
122 * was a SYS/BIOS Swi, the synchronizer instance could be a SyncSwi.
123 * If a MessageQ_put() was called, the Swi_post() would
124 * be called. The Swi would run and it must call MessageQ_get() until no
125 * messages are returned.
126 *
127 * The MessageQ header should be included in an application as follows:
128 * @code
129 * #include <ti/ipc/MessageQ.h>
130 * @endcode
131 */
133 #ifndef ti_ipc_MessageQ__include
134 #define ti_ipc_MessageQ__include
136 #include <ti/ipc/MultiProc.h>
138 #if defined (__cplusplus)
139 extern "C" {
140 #endif
142 /* =============================================================================
143 * All success and failure codes for the module
144 * =============================================================================
145 */
147 /*!
148 * @brief The resource is still in use
149 */
150 #define MessageQ_S_BUSY (2)
152 /*!
153 * @brief The module has been already setup
154 */
155 #define MessageQ_S_ALREADYSETUP (1)
157 /*!
158 * @brief Operation is successful.
159 */
160 #define MessageQ_S_SUCCESS (0)
162 /*!
163 * @brief Operation is not successful.
164 */
165 #define MessageQ_E_FAIL (-1)
167 /*!
168 * @brief There is an invalid argument.
169 */
170 #define MessageQ_E_INVALIDARG (-2)
172 /*!
173 * @brief Operation resulted in memory failure.
174 */
175 #define MessageQ_E_MEMORY (-3)
177 /*!
178 * @brief The specified entity already exists.
179 */
180 #define MessageQ_E_ALREADYEXISTS (-4)
182 /*!
183 * @brief Unable to find the specified entity.
184 */
185 #define MessageQ_E_NOTFOUND (-5)
187 /*!
188 * @brief Operation timed out.
189 */
190 #define MessageQ_E_TIMEOUT (-6)
192 /*!
193 * @brief Module is not initialized.
194 */
195 #define MessageQ_E_INVALIDSTATE (-7)
197 /*!
198 * @brief A failure occurred in an OS-specific call
199 */
200 #define MessageQ_E_OSFAILURE (-8)
202 /*!
203 * @brief Specified resource is not available
204 */
205 #define MessageQ_E_RESOURCE (-9)
207 /*!
208 * @brief Operation was interrupted. Please restart the operation
209 */
210 #define MessageQ_E_RESTART (-10)
212 /*!
213 * @brief An invalid message was encountered
214 */
215 #define MessageQ_E_INVALIDMSG (-11)
217 /*!
218 * @brief Not the owner
219 */
220 #define MessageQ_E_NOTOWNER (-12)
222 /*!
223 * @brief Operation resulted in error
224 */
225 #define MessageQ_E_REMOTEACTIVE (-13)
227 /*!
228 * @brief An invalid heap id was encountered
229 */
230 #define MessageQ_E_INVALIDHEAPID (-14)
232 /*!
233 * @brief An invalid MultiProc id was encountered
234 */
235 #define MessageQ_E_INVALIDPROCID (-15)
237 /*!
238 * @brief The max has been reached.
239 */
240 #define MessageQ_E_MAXREACHED (-16)
242 /*!
243 * @brief Attempting to use an unregistered heap id.
244 */
245 #define MessageQ_E_UNREGISTEREDHEAPID (-17)
247 /*!
248 * @brief Trying to free a statically initialized message
249 */
250 #define MessageQ_E_CANNOTFREESTATICMSG (-18)
252 /*!
253 * @brief MessageQ was unblocked
254 */
255 #define MessageQ_E_UNBLOCKED (-19)
257 /* =============================================================================
258 * Macros
259 * =============================================================================
260 */
262 /*!
263 * @brief Used as the timeout value to specify wait forever
264 */
265 #define MessageQ_FOREVER (~(0))
267 /*!
268 * @brief Invalid message id
269 */
270 #define MessageQ_INVALIDMSGID (0xffff)
272 /*!
273 * @brief Invalid message queue
274 */
275 #define MessageQ_INVALIDMESSAGEQ (0xffff)
277 /*!
278 * @brief Mask to extract priority setting
279 */
280 #define MessageQ_PRIORITYMASK (0x3)
282 /*!
283 * @brief Extract the destination queue ID from a message.
284 *
285 * Can only be used on the same processor where the destination queue resides.
286 * This function should only be used by Message Queue Transport writers.
287 *
288 * @param[in] msg Message of type #MessageQ_Msg
289 *
290 * @retval queueId Destination message queue ID of type #MessageQ_QueueId
291 */
292 #define MessageQ_getDstQueue(msg) \
293 ((msg)->dstId == (MessageQ_QueueIndex)MessageQ_INVALIDMESSAGEQ) ? \
294 (MessageQ_QueueId)MessageQ_INVALIDMESSAGEQ : \
295 (MessageQ_QueueId)(((MessageQ_QueueId)MultiProc_self() << 16u) \
296 | (((MessageQ_Msg)(msg))->dstId))
299 /*!
300 * @brief Retrieves the message ID of a message.
301 *
302 * This function retrieves the message ID from the message. The
303 * MessageQ_setMsgId() function is used to insert the message ID.
304 *
305 * The message id is part of the #MessageQ_MsgHeader header and is in every
306 * MessageQ message. All message ids are initialized to #MessageQ_INVALIDMSGID
307 * in the MessageQ_alloc() and MessageQ_staticMsgInit() calls.
308 *
309 * @param[in] msg Message of type #MessageQ_Msg
310 *
311 * @retval msgId 16-bit message ID from the message
312 */
313 #define MessageQ_getMsgId(msg) (((MessageQ_Msg) (msg))->msgId)
315 /*!
316 * @brief Returns the size of the specified message. This function is helpful
317 * when re-using a message.
318 *
319 * @param[in] msg Message of type #MessageQ_Msg
320 *
321 * @retval size Size of the message
322 */
323 #define MessageQ_getMsgSize(msg) (((MessageQ_Msg) (msg))->msgSize)
325 /*!
326 * @brief Gets the message priority of a message
327 *
328 * @param[in] msg Message of type #MessageQ_Msg
329 *
330 * @retval priority Priority of the message
331 */
332 #define MessageQ_getMsgPri(msg) \
333 ((((MessageQ_Msg) (msg))->flags & MessageQ_PRIORITYMASK))
335 /*!
336 * @brief Returns the MultiProc processor id on which the queue resides
337 *
338 * Message queues reside on the processor that created them. This function
339 * allows the caller to determined on which processor the queue resides.
340 *
341 * @param[in] queueId Unique #MessageQ_QueueId that identifies the queue
342 *
343 * @retval procId The MultiProc id on which the queue resides
344 */
345 #define MessageQ_getProcId(queueId) \
346 ((UInt16)((queueId) >> 16))
348 /*!
349 * @brief Retrieves the message queue ID from a message.
350 *
351 * This function along with the MessageQ_setReplyQueue() function can be used
352 * instead of the open function. The sender of a message can embed a messageQ
353 * into the message with the MessageQ_setReplyQueue() function. The receiver of
354 * the message can extract the message queue ID with this function.
355 *
356 * This method is particularly useful in a client/server relationship where
357 * the server does not want to know who the clients are. The clients can embed
358 * their message queue into the message to the server and the server extracts
359 * it and uses it to reply.
360 *
361 * @param[in] msg Message of type #MessageQ_Msg
362 *
363 * @retval queueId Message queue ID of type #MessageQ_QueueId
364 */
365 #define MessageQ_getReplyQueue(msg) \
366 (MessageQ_QueueId)((((MessageQ_Msg) (msg))->replyProc << 16u) \
367 | ((MessageQ_Msg)(msg))->replyId)
369 /*!
370 * @brief Sets the message id in a message.
371 *
372 * This function sets the message ID in the message. The MessageQ_getMsgId()
373 * function is used to retrieve the message ID. The message id is part of the
374 * #MessageQ_MsgHeader header and is in every MessageQ message. All message ids
375 * are initialized to #MessageQ_INVALIDMSGID in the MessageQ_alloc() and
376 * MessageQ_staticMsgInit() calls.
377 *
378 * @param[in] msg Message of type #MessageQ_Msg
379 * @param[in] id 16-bit value
380 */
381 #define MessageQ_setMsgId(msg, id) ((MessageQ_Msg) (msg))->msgId = (id)
383 /*!
384 * @brief Sets the message priority of a message
385 *
386 * @param[in] msg Message of type #MessageQ_Msg
387 * @param[in] priority Priority of message to be set.
388 */
389 #define MessageQ_setMsgPri(msg, priority) \
390 (((MessageQ_Msg) (msg))->flags = ((priority) & MessageQ_PRIORITYMASK))
392 /* =============================================================================
393 * Structures & Enums
394 * =============================================================================
395 */
397 /*!
398 * @brief A 32-bit value that uniquely identifies a message queue
399 */
400 typedef UInt32 MessageQ_QueueId;
402 /*!
403 * @brief Local queue index
404 */
405 typedef UInt16 MessageQ_QueueIndex;
407 /*!
408 * @brief MessageQ_Handle type
409 */
410 typedef struct MessageQ_Object *MessageQ_Handle;
412 /*!
413 * @brief Structure defining parameters for the MessageQ module.
414 */
415 typedef struct {
416 Void *synchronizer;
417 /*!< Synchronizer instance used to signal IO completion
418 *
419 * The synchronizer is used in MessageQ_put() and MessageQ_get().
420 * The synchronizer signal is called as part of MessageQ_put().
421 * The synchronizer waits in MessageQ_get() if there are no messages
422 * present.
423 */
425 } MessageQ_Params;
427 /*!
428 * @brief Required first field in every message
429 */
430 typedef struct {
431 Bits32 reserved0; /*!< reserved for List.elem->next */
432 Bits32 reserved1; /*!< reserved for List.elem->prev */
433 Bits32 msgSize; /*!< message size */
434 Bits16 flags; /*!< bitmask of different flags */
435 Bits16 msgId; /*!< message id */
436 Bits16 dstId; /*!< destination queue id */
437 Bits16 dstProc; /*!< destination processor id */
438 Bits16 replyId; /*!< reply id */
439 Bits16 replyProc; /*!< reply processor */
440 Bits16 srcProc; /*!< source processor */
441 Bits16 heapId; /*!< heap id */
442 Bits16 seqNum; /*!< sequence number */
443 Bits16 reserved; /*!< reserved */
444 } MessageQ_MsgHeader;
446 /*!
447 * @brief Typedef for ease of use
448 */
449 typedef MessageQ_MsgHeader *MessageQ_Msg;
451 /*!
452 * @brief Message priority
453 */
454 typedef enum {
455 MessageQ_NORMALPRI = 0, /*!< Normal Priority */
456 MessageQ_HIGHPRI = 1, /*!< High Priority */
457 MessageQ_RESERVEDPRI = 2, /*!< Reserved Priority */
458 MessageQ_URGENTPRI = 3 /*!< Urgent Priority */
459 } MessageQ_Priority;
462 /* =============================================================================
463 * MessageQ Module-wide Functions
464 * =============================================================================
465 */
467 /*!
468 * @brief Initialize MessageQ_Params
469 *
470 * @param[in] params Parameters required to create a MessageQ
471 */
472 Void MessageQ_Params_init(MessageQ_Params *params);
474 /*!
475 * @brief Create a MessageQ instance
476 *
477 * The name supplied here does not have to be in persistent memory. The
478 * maximum length of the string supplied here, including the '\\0' terminator
479 * is '32' by default.
480 *
481 * There are no verifications to ensure that the name supplied in
482 * MessageQ_create() is unique across all processors. Caution must be exercised
483 * to ensure that each processor uses a unique name.
484 *
485 * @param[in] name Name of the queue
486 * @param[in] params Initialized MessageQ parameters
487 *
488 * @return MessageQ Handle
489 */
490 MessageQ_Handle MessageQ_create(String name, const MessageQ_Params *params);
492 /*!
493 * @brief Delete a created MessageQ instance
494 *
495 * This function deletes a created message queue instance. If the
496 * message queue is non-empty, any messages remaining in the queue
497 * will not be freed and will be lost.
498 *
499 * @param[in,out] handlePtr Pointer to handle to delete.
500 *
501 * @return MessageQ status:
502 * - #MessageQ_E_FAIL: delete failed
503 * - #MessageQ_S_SUCCESS: delete successful
504 */
505 Int MessageQ_delete(MessageQ_Handle *handlePtr);
507 /*!
508 * @brief Open a message queue
509 *
510 * MessageQ_open() is used to retrieve the queue id for a queue that has been
511 * created either locally or remotely. Note that the queueId is simply a
512 * 32 bit value that uniquely identifies a queue. Therefore, it is also
513 * possible to put a message on a queue whose queueId has been retrieved using
514 * any other method.
515 *
516 * @param[in] name Name of queue to open
517 * @param[out] queueId QueueId that can be used in MessageQ_put()
518 *
519 * @return MessageQ status:
520 * - #MessageQ_E_NOTFOUND: open failed (name not found on any
521 * processor)
522 * - #MessageQ_S_SUCCESS: open successful
523 */
524 Int MessageQ_open(String name, MessageQ_QueueId *queueId);
526 /*!
527 * @brief Close the opened handle
528 *
529 * Only close a queueId that was returned from MessageQ_open().
530 *
531 * @param[in] queueId Pointer to queueId to close
532 *
533 * @return MessageQ status:
534 * - #MessageQ_E_FAIL: close failed
535 * - #MessageQ_S_SUCCESS: close successful
536 */
537 Int MessageQ_close(MessageQ_QueueId *queueId);
539 /*!
540 * @brief Allocates a message from the heap
541 *
542 * This function allocates a message from the heap associated with the heapId.
543 * The first field of the message must be a #MessageQ_MsgHeader structure.
544 * For example:
545 * @code
546 * typedef struct MyMsg {
547 * MessageQ_MsgHeader header;
548 * ...
549 * } MyMsg;
550 * @endcode
551 *
552 * @param[in] heapId heapId
553 * @param[in] size size of requested message (including the
554 * #MessageQ_MsgHeader).
555 *
556 * @pre @c size must be at least large enough to hold a
557 * MessageQ_MsgHeader
558 *
559 * @return Allocated message or NULL if no memory.
560 */
561 MessageQ_Msg MessageQ_alloc(UInt16 heapId, UInt32 size);
563 /*!
564 * @brief Frees a message back to the heap
565 *
566 * Frees the message back to the heap that was used to allocate it.
567 *
568 * @param[in] msg Message to free.
569 *
570 * @return MessageQ status:
571 * - #MessageQ_E_FAIL: failed to free message
572 * - #MessageQ_S_SUCCESS: successfully freed the message
573 */
574 Int MessageQ_free(MessageQ_Msg msg);
576 /*!
577 * @brief Register a heap with MessageQ
578 *
579 * This function registers a heap with MessageQ. The user selects a unique
580 * heapId associated with this heap. When a message is allocated via
581 * MessageQ_alloc(), the heapId is specified. Internally, MessageQ
582 * uses the heapId to access the heap.
583 *
584 * Care must be taken when assigning heapIds. Internally MessageQ stores
585 * the heapId into the message. When the message is freed
586 * (via MessageQ_free()), the heapId is used to determine which heap to use.
587 * On systems with shared memory the heapIds must match on corresponding
588 * processors. For example, assume there is a heap called myHeap which
589 * acts on shared memory and processors 0 and 1 both use this heap.
590 * When you register the heap with MessageQ, the same heapId must be used
591 * on both processor 0 and 1.
592 *
593 * If a heap is already registered for the specified heapId, no action is
594 * taken and #MessageQ_E_ALREADYEXISTS is returned.
595 *
596 * @param[in] heap Heap to register
597 * @param[in] heapId heapId associated with the heap
598 *
599 * @return MessageQ status:
600 * - #MessageQ_S_SUCCESS: heap successfully registered
601 * - #MessageQ_E_ALREADYEXISTS: heap already exists with heapId
602 */
603 Int MessageQ_registerHeap(Ptr heap, UInt16 heapId);
605 /*!
606 * @brief Unregister a heap with MessageQ
607 *
608 * This function unregisters the heap associated with the heapId.
609 * Care must be taken to ensure that there are no outstanding messages
610 * allocated from this heap. If there are outstanding messages, an attempt
611 * to free the message will result in non-deterministic results.
612 *
613 * @param[in] heapId Heap to unregister
614 *
615 * @return MessageQ status:
616 * - #MessageQ_S_SUCCESS: heap successfully unregistered
617 */
618 Int MessageQ_unregisterHeap(UInt16 heapId);
620 /*!
621 * @brief Sets the message tracing flag on a given message
622 *
623 * This function enables message tracing for a message. Tracing is offered
624 * in the form of Log messages that are output during operations on the
625 * message (i.e. MessageQ_free(), MessageQ_put(), etc).
626 *
627 * @param msg Message
628 * @param traceFlag Message trace flag (TRUE = tracing enabled)
629 */
630 Void MessageQ_setMsgTrace(MessageQ_Msg msg, Bool traceFlag);
632 /*!
633 * @brief Initializes a message not obtained from MessageQ_alloc()
634 *
635 * There are several fields in the #MessageQ_MsgHeader that
636 * are initialized by the MessageQ_alloc() function. MessageQ_staticMsgInit()
637 * can be used to initialize these fields for messages that are
638 * not allocated from MessageQ.
639 *
640 * There is one strict constraint with using messages not allocated
641 * from MessageQ. The message cannot be freed via MessageQ_free().
642 * This includes
643 * - The application calling MessageQ_free() on the same processor
644 * - The application calling MessageQ_free() on a different processor
645 * - The application cannot send the message to another processor
646 * where the transport might call MessageQ_free() on the message.
647 * For example, copy based transport call MessageQ_free() after sending
648 * the message.
649 * If a staticMsgInit'd msg is passed to MessageQ_free() an assert will occur
650 *
651 * @param msg Message to initialize
652 * @param[in] size Size of the message in MAUs
653 *
654 * @pre @c size must be at least large enough to hold a #MessageQ_MsgHeader
655 */
656 Void MessageQ_staticMsgInit(MessageQ_Msg msg, UInt32 size);
658 /* =============================================================================
659 * MessageQ Per-instance Functions
660 * =============================================================================
661 */
663 /*!
664 * @brief Gets a message from the message queue
665 *
666 * This function returns a status. It also returns a message in msg.
667 * If no message is available, it blocks on the synchronizer object
668 * until the synchronizer is signaled or a timeout occurs.
669 * The synchronizer is signaled, when Message_put is called on the MessageQ
670 * handle. If a timeout occurs, the msg is set to NULL and the status is
671 * #MessageQ_E_TIMEOUT. If a timeout of zero is specified, the function
672 * returns immediately and if no message is available, the msg
673 * is set to NULL and the status is #MessageQ_E_TIMEOUT. The
674 * #MessageQ_E_UNBLOCKED status is return, if MessageQ_unblock is called
675 * on the MessageQ handle. If a message is successfully retrieved, the msg
676 * is set to the message and a #MessageQ_S_SUCCESS status is returned.
677 *
678 * @param[in] handle MessageQ handle
679 * @param[out] msg Pointer to the message
680 * @param[in] timeout Maximum duration to wait for a message in
681 * microseconds.
682 *
683 * @return MessageQ status:
684 * - #MessageQ_S_SUCCESS: Message successfully returned
685 * - #MessageQ_E_TIMEOUT: MessageQ_get() timed out
686 * - #MessageQ_E_UNBLOCKED: MessageQ_get() was unblocked
687 * - #MessageQ_E_FAIL: A general failure has occurred
688 *
689 * @sa MessageQ_put()
690 * @sa MessageQ_unblock()
691 */
692 Int MessageQ_get(MessageQ_Handle handle, MessageQ_Msg *msg, UInt timeout);
694 /*!
695 * @brief Place a message onto a message queue
696 *
697 * This call places the message onto the specified message queue. The
698 * message queue could be local or remote. The MessageQ module manages
699 * the delivery.
700 *
701 * In the case where the queue is remote, MessageQ does not guarantee that
702 * the message is actually delivered before the MessageQ_put() call returns
703 *
704 * The queue id must have been returned from one of the following functions:
705 * - MessageQ_open()
706 * - MessageQ_getReplyQueue()
707 * - MessageQ_getDstQueue()
708 *
709 * After the message is placed onto the final destination, the queue's
710 * #MessageQ_Params.synchronizer signal function is called.
711 *
712 * The application loses ownership of the message once MessageQ_put() is called.
713 *
714 * @param[in] queueId Destination MessageQ
715 * @param[in] msg Message to be sent.
716 *
717 * @return Status of the call.
718 * - #MessageQ_S_SUCCESS denotes success.
719 * - #MessageQ_E_FAIL denotes failure. The put was not successful.
720 * The caller still owns the message.
721 */
722 Int MessageQ_put(MessageQ_QueueId queueId, MessageQ_Msg msg);
724 /*!
725 * @brief Returns the number of messages in a message queue
726 *
727 * This function returns the number of messages in a message queue.
728 *
729 * @param[in] handle MessageQ handle
730 *
731 * @return Number of messages in the message queue.
732 */
733 Int MessageQ_count(MessageQ_Handle handle);
735 /*!
736 * @brief Returns the QueueId associated with the handle
737 *
738 * Since the MessageQ_put() function takes a QueueId, the creator
739 * of a message queue cannot send a message to itself without
740 * retrieving the QueueId. This function extracts the QueueId
741 * from the object.
742 *
743 * @param[in] handle MessageQ handle
744 *
745 * @return QueueId associated to the object
746 */
747 UInt32 MessageQ_getQueueId(MessageQ_Handle handle);
749 /*!
750 * @brief Embeds a source message queue into a message
751 *
752 * This function along with MessageQ_getReplyQueue()
753 * can be used instead of MessageQ_open(). The sender
754 * of a message can embed a messageQ into the message with this
755 * function. The receiver of the message can extract the message queue
756 * id with the MessageQ_getReplyQueue() function.
757 *
758 * This method is particularly useful in a client/server relationship
759 * where the server does not want to know who the clients are. The
760 * clients can embed their message queue into the message to the server
761 * and the server extracts it and uses it to reply.
762 *
763 * @param handle MessageQ handle
764 * @param msg Message to embed queue into
765 */
766 Void MessageQ_setReplyQueue(MessageQ_Handle handle, MessageQ_Msg msg);
768 /*!
769 * @brief Unblocks a MessageQ
770 *
771 * Unblocks a reader thread that is blocked on a MessageQ_get(). The
772 * MessageQ_get() call will return with status #MessageQ_E_UNBLOCKED indicating
773 * that it returned due to a MessageQ_unblock() rather than a timeout or a
774 * received message. This call should only be used during a shutdown sequence
775 * in order to ensure that there is no blocked reader on a queue before
776 * deleting the queue. A queue may not be used after it has been unblocked.
777 *
778 * MessageQ_unblock() works by raising a flag in the queue indicating that it
779 * is unblocked and then signaling the synchronizer that is configured with
780 * the target queue. If MessageQ_unblock() is called upon a queue that has
781 * no blocked listeners, then any subsequent MessageQ_get will not block and
782 * will immediately return #MessageQ_E_UNBLOCKED regardless of whether there
783 * is a message on the queue.
784 *
785 * Restrictions:
786 * - A queue may not be used after it has been unblocked.
787 * - MessageQ_unblock() may only be called on a local queue.
788 * - May only be used with a queue configured with a blocking synchronizer.
789 *
790 * @param[in] handle MessageQ handle
791 *
792 * @sa MessageQ_get
793 */
794 Void MessageQ_unblock(MessageQ_Handle handle);
796 #if defined (__cplusplus)
797 }
798 #endif /* defined (__cplusplus) */
799 #endif /* ti_ipc_MessageQ__include */