autotools: Update autotools generated files with K3 AM65XX support
[ipc/ipcdev.git] / packages / ti / ipc / MessageQ.h
1 /*
2  * Copyright (c) 2012-2015 Texas Instruments Incorporated - http://www.ti.com
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  *  @brief  MessageQ was shutdown
259  */
260 #define MessageQ_E_SHUTDOWN             (-20)
262 /* =============================================================================
263  *  Macros
264  * =============================================================================
265  */
267 /*!
268  *  @brief      Used as the timeout value to specify wait forever
269  */
270 #define MessageQ_FOREVER                (~(0))
272 /*!
273  *  @brief      Invalid message id
274  */
275 #define MessageQ_INVALIDMSGID           (0xffff)
277 /*!
278  *  @brief      Invalid message queue
279  */
280 #define MessageQ_INVALIDMESSAGEQ        (0xffff)
282 /*!
283  *  @brief      Mask to extract priority setting
284  */
285 #define MessageQ_PRIORITYMASK           (0x3)
287 /** @cond INTERNAL */
288 /*!
289  *  @brief      Offset to avoid collision with reserved ports
290  *
291  *  A queue's port number is computed by adding this offset to the
292  *  queue index. Use the port number to address the message or when
293  *  binding a socket. Computing a port number with this offset avoids
294  *  collisions with reserved port numbers which are typically in the
295  *  same range as the queue indexes.
296  */
297 #define MessageQ_PORTOFFSET             (0x80)
298 /** @endcond INTERNAL */
300 /*!
301  *  @brief      Extract the destination queue ID from a message.
302  *
303  *  This function is typically used be a transport.
304  *
305  *  The destination address is written into the message header when
306  *  calling MessageQ_put(). Therefore, you can only use this function
307  *  to extract the destination queue ID after MessageQ_put() has been
308  *  called on the given message. However, ownership rules dictate that
309  *  you cannot dereference a message after calling MessageQ_put() (because
310  *  you have transfered ownership to the transport).
311  *
312  *  After receiving a message by calling MessageQ_get(), you may safely
313  *  use this function. Although there is little benefit from doing so.
314  *
315  *  When the message is given to the transport, the destination address
316  *  has been written into the message header. In addition, the transport
317  *  now has ownership of the message. So, it is appropriate for the transport
318  *  to use this macro.
319  *
320  *  @param[in]  msg     Message of type #MessageQ_Msg
321  *
322  *  @retval  queueId    Destination message queue ID of type #MessageQ_QueueId
323  */
324 #define MessageQ_getDstQueue(msg) \
325         (((MessageQ_Msg)(msg))->dstId == \
326         (MessageQ_QueueIndex)MessageQ_INVALIDMESSAGEQ) ? \
327         (MessageQ_QueueId)MessageQ_INVALIDMESSAGEQ : \
328         (((MessageQ_QueueId)((MessageQ_Msg)(msg))->dstProc << 16u) \
329         | (((MessageQ_Msg)(msg))->dstId))
332 /*!
333  *  @brief   Retrieves the message ID of a message.
334  *
335  *  This function retrieves the message ID from the message. The
336  *  MessageQ_setMsgId() function is used to insert the message ID.
337  *
338  *  The message id is part of the #MessageQ_MsgHeader header and is in every
339  *  MessageQ message. All message ids are initialized to #MessageQ_INVALIDMSGID
340  *  in the MessageQ_alloc() and MessageQ_staticMsgInit() calls.
341  *
342  *  @param[in]  msg     Message of type #MessageQ_Msg
343  *
344  *  @retval     msgId   16-bit message ID from the message
345  */
346 #define MessageQ_getMsgId(msg) (((MessageQ_Msg) (msg))->msgId)
348 /*!
349  *  @brief   Returns the size of the specified message. This function is helpful
350  *           when re-using a message.
351  *
352  *  @param[in]  msg     Message of type #MessageQ_Msg
353  *
354  *  @retval     size    Size of the message
355  */
356 #define MessageQ_getMsgSize(msg) (((MessageQ_Msg) (msg))->msgSize)
358 /*!
359  *  @brief   Gets the message priority of a message
360  *
361  *  @param[in]  msg     Message of type #MessageQ_Msg
362  *
363  *  @retval priority    Priority of the message
364  */
365 #define MessageQ_getMsgPri(msg)        \
366                  ((((MessageQ_Msg) (msg))->flags & MessageQ_PRIORITYMASK))
368 /*!
369  *  @brief      Returns the MultiProc processor id on which the queue resides
370  *
371  *  Message queues reside on the processor that created them. This function
372  *  allows the caller to determined on which processor the queue resides.
373  *
374  *  @param[in]  queueId      Unique #MessageQ_QueueId that identifies the queue
375  *
376  *  @retval     procId       The MultiProc id on which the queue resides
377  */
378 #define MessageQ_getProcId(queueId)     \
379                  ((UInt16)((queueId) >> 16))
381 /*!
382  *  @brief   Extract the queue index from the given queue ID
383  *
384  *  When creating and opening queues, the queue index is embedded
385  *  into the queue ID using an implementation dependent format. This
386  *  function extracts the queue index from the queue ID.
387  *
388  *  For example, in the MessageQ_put() hook function, you might extract
389  *  the queue index in order to set the transport ID.
390  *
391  *      @code
392  *      Void msgqPutHook(MessageQ_QueueId queueId, MessageQ_Msg msg)
393  *      {
394  *          MessageQ_QueueIndex queueIndex;
395  *          UInt tid;
396  *
397  *          queueIndex = MessageQ_getQueueIndex(queueId);
398  *          ...
399  *          MessageQ_setTransportId(msg, tid);
400  *      }
401  *      @endcode
402  *
403  *  This function performs no error checking. Using an invalid queue ID
404  *  will result in undefined behavior.
405  *
406  *  @param[in]  queueId         Message queue ID of type #MessageQ_QueueId
407  *
408  *  @retval     queueIndex      The queue index of type #MessageQ_QueueIndex
409  */
410 #define MessageQ_getQueueIndex(queueId) \
411         (((MessageQ_QueueIndex)((MessageQ_QueueId)0xFFFF & (queueId))) \
412         - MessageQ_PORTOFFSET)
414 /*!
415  *  @brief   Retrieves the message queue ID from a message.
416  *
417  *  This function along with the MessageQ_setReplyQueue() function can  be used
418  *  instead of the open function. The sender of a message can embed a messageQ
419  *  into the message with the MessageQ_setReplyQueue() function. The receiver of
420  *  the message can extract the message queue ID with this function.
421  *
422  *  This method is particularly useful in a client/server relationship where
423  *  the server does not want to know who the clients are. The clients can embed
424  *  their message queue into the message to the server and the server extracts
425  *  it and uses it to reply.
426  *
427  *  @param[in]  msg     Message of type #MessageQ_Msg
428  *
429  *  @retval  queueId    Message queue ID of type #MessageQ_QueueId
430  */
431 #define MessageQ_getReplyQueue(msg)           \
432                 (MessageQ_QueueId)((((MessageQ_Msg) (msg))->replyProc << 16u) \
433                 | ((MessageQ_Msg)(msg))->replyId)
435 /*!
436  *  @brief   Return the transport Id for the given message
437  *
438  *  Extract the transport Id from the message header.
439  *
440  *  @param[in]   msg      message of type #MessageQ_Msg
441  *  @retval      tid      transport Id
442  */
443 #define MessageQ_getTransportId(msg) \
444         ((((MessageQ_Msg)(msg))->flags & (0x7 << 2)) >> 2)
446 /*!
447  *  @brief   Sets the message id in a message.
448  *
449  *  This function sets the message ID in the message. The MessageQ_getMsgId()
450  *  function is used to retrieve the message ID.  The message id is part of the
451  *  #MessageQ_MsgHeader header and is in every MessageQ message. All message ids
452  *  are initialized to #MessageQ_INVALIDMSGID in the MessageQ_alloc() and
453  *  MessageQ_staticMsgInit() calls.
454  *
455  *  @param[in]   msg    Message of type #MessageQ_Msg
456  *  @param[in]   id     16-bit value
457  */
458 #define MessageQ_setMsgId(msg, id) ((MessageQ_Msg) (msg))->msgId = (id)
460 /*!
461  *  @brief   Sets the message priority of a message
462  *
463  *  @param[in]   msg      Message of type #MessageQ_Msg
464  *  @param[in]   priority Priority of message to be set.
465  */
466 #define MessageQ_setMsgPri(msg, priority) \
467         ((MessageQ_Msg)(msg))->flags = \
468         (((MessageQ_Msg)(msg))->flags & ~(MessageQ_PRIORITYMASK)) \
469         | ((priority) & MessageQ_PRIORITYMASK)
471 /*!
472  *  @brief   Set the transport Id for the given message
473  *
474  *  Set the transport Id in the flags field of the message header. When
475  *  set to a non-zero value, the message will be given to the specified
476  *  transport for delivery. The transport must be registered with MessageQ
477  *  with the given Id.
478  *
479  *  There is no error checking on the transport Id.
480  *
481  *  @param[in]   msg      message of type #MessageQ_Msg
482  *  @param[in]   tid      transport ID (1-7)
483  */
484 #define MessageQ_setTransportId(msg, tid) \
485         ((MessageQ_Msg)(msg))->flags = \
486         ((((MessageQ_Msg)(msg))->flags & ~(0x7 << 2)) | ((tid) << 2))
488 /* =============================================================================
489  *  Structures & Enums
490  * =============================================================================
491  */
493 /*!
494  *  @brief  A 32-bit value that uniquely identifies a message queue
495  */
496 typedef UInt32 MessageQ_QueueId;
498 /*!
499  *  @brief  Local queue index
500  */
501 typedef UInt16 MessageQ_QueueIndex;
503 /*!
504  *  @brief  MessageQ_Handle type
505  */
506 typedef struct MessageQ_Object *MessageQ_Handle;
508 /*!
509  *  @brief  Structure defining parameters for MessageQ_create().
510  */
511 typedef struct {
512 /** @cond INTERNAL */
513     Int __version;
514     /*  Used internally for tracking implementation evolution.
515      *  For internal use only.
516      */
517 /** @endcond INTERNAL */
519     Void *synchronizer;
520     /*!< Synchronizer instance used to signal IO completion
521      *
522      *  The synchronizer is used in MessageQ_put() and MessageQ_get().
523      *  The synchronizer signal is called as part of MessageQ_put().
524      *  The synchronizer waits in MessageQ_get() if there are no messages
525      *  present.
526      */
528      MessageQ_QueueIndex queueIndex;
529      /*!< Value used to specify the index in the MessageQ array
530       *
531       *  This parameter allows an application to specify a queueIndex to
532       *  be used for a message queue. To use this functionality, the
533       *  MessageQ.numReservedEntries static configuration parameter must be
534       *  set to one more than the highest requested queueIndex. The
535       *  MessageQ.numReservedEntries parameter reserves that number of
536       *  message queue slots starting at 0 and proceeding to
537       *  (MessageQ.numReservedEntries - 1).
538       *
539       *  The default is MessageQ_ANY, which means it is not taken from the
540       *  reserved slots.
541       */
543 } MessageQ_Params;
545 /** @cond INTERNAL */
546 /*  Date: 02 Dec 2014
547  *
548  *  Initial implementation of params structure which contains
549  *  a version field. This allows for binary compatibility as
550  *  the params structure is modified in the future.
551  */
552 #define MessageQ_Params_VERSION_2       2
553 /** @endcond INTERNAL */
555 /** @cond INTERNAL */
556 /*!
557  *  @brief      Defines the current params structure version
558  */
559 #define MessageQ_Params_VERSION         MessageQ_Params_VERSION_2
560 /** @endcond INTERNAL */
562 /*!
563  *  @brief  Structure defining parameters for MessageQ_create2().
564  *
565  *  MessageQ_Params2 is a superset of MessageQ_Params. It is used
566  *  with MessageQ_create2().
567  *
568  *  @deprecated This type has been deprecated. It will be removed
569  *  in a future release. Please use MessageQ_Params instead.
570  */
571 typedef struct {
572     Void *synchronizer;
573     /*!< Synchronizer instance used to signal IO completion
574      *
575      *  The synchronizer is used in MessageQ_put() and MessageQ_get().
576      *  The synchronizer signal is called as part of MessageQ_put().
577      *  The synchronizer waits in MessageQ_get() if there are no messages
578      *  present.
579      */
581      MessageQ_QueueIndex queueIndex;
582      /*!< Value used to specify the index in the MessageQ array
583       *
584       *  This parameter allows an application to specify a queueIndex to
585       *  be used for a message queue. To use this functionality, the
586       *  MessageQ.numReservedEntries static configuration parameter must be
587       *  set to one more than the highest requested queueIndex. The
588       *  MessageQ.numReservedEntries parameter reserves that number of
589       *  message queue slots starting at 0 and proceeding to
590       *  (MessageQ.numReservedEntries - 1).
591       *
592       *  The default is MessageQ_ANY, which means it is not taken from the
593       *  reserved slots.
594       */
596 } MessageQ_Params2;
598 /*!
599  *  @brief      Required first field in every message
600  */
601 typedef struct {
602     Bits32       reserved0;         /*!< reserved for List.elem->next       */
603     Bits32       reserved1;         /*!< reserved for List.elem->prev       */
604     Bits32       msgSize;           /*!< message size                       */
605     Bits16       flags;             /*!< bitmask of different flags         */
606     Bits16       msgId;             /*!< message id                         */
607     Bits16       dstId;             /*!< destination queue id               */
608     Bits16       dstProc;           /*!< destination processor id           */
609     Bits16       replyId;           /*!< reply id                           */
610     Bits16       replyProc;         /*!< reply processor                    */
611     Bits16       srcProc;           /*!< source processor                   */
612     Bits16       heapId;            /*!< heap id                            */
613     Bits16       seqNum;            /*!< sequence number                    */
614     Bits16       reserved;          /*!< reserved                           */
615 } MessageQ_MsgHeader;
617 /*!
618  *  @brief  Typedef for ease of use
619  */
620 typedef MessageQ_MsgHeader *MessageQ_Msg;
622 /*!
623  *  @brief      Message priority
624  */
625 typedef enum {
626     MessageQ_NORMALPRI      = 0,    /*!< Normal Priority                  */
627     MessageQ_HIGHPRI        = 1,    /*!< High Priority                    */
628     MessageQ_RESERVEDPRI    = 2,    /*!< Reserved Priority                */
629     MessageQ_URGENTPRI      = 3     /*!< Urgent Priority                  */
630 } MessageQ_Priority;
632 /*!
633  *  @brief      Denotes any queueId is acceptable.
634  *
635  *  This constant is the default for the queueId in the MessageQ_Params
636  *  structure.
637  */
638 #define MessageQ_ANY (Bits16)~(0)
640 /*!
641  *  @brief      Free hook prototype
642  *
643  *  @param[in]  heapId      heapId of message that was freed
644  *  @param[in]  msgId       msgId of message that was freed
645  */
646 typedef Void (*MessageQ_FreeHookFxn)(Bits16 heapId, Bits16 msgId);
648 /*!
649  *  @brief      Put hook function definition
650  *
651  *  This function is invoked near the beginning of the MessageQ_put()
652  *  function. It allows client code to augment the addressing of the
653  *  given message before it is delivered.
654  *
655  *  @param[in]  queueId     destination message queue
656  *  @param[in]  msg         message to be sent
657  */
658 typedef Void (*MessageQ_PutHookFxn)(MessageQ_QueueId queueId, MessageQ_Msg msg);
660 #ifdef STD_H
661 #include <ti/ipc/interfaces/ITransport.h>
662 #include <ti/ipc/interfaces/IMessageQTransport.h>
663 #else
664 #include <ti/sdo/ipc/interfaces/ITransport.h>
665 #include <ti/sdo/ipc/interfaces/IMessageQTransport.h>
666 #endif
668 Bool MessageQ_registerTransport(IMessageQTransport_Handle handle,
669                                 UInt16 rprocId, UInt priority);
670 Void MessageQ_unregisterTransport(UInt16 rprocId, UInt priority);
673 /* =============================================================================
674  *  MessageQ Module-wide Functions
675  * =============================================================================
676  */
678 /** @cond INTERNAL */
679 /* Returns the local handle associated with queueId. */
680 MessageQ_Handle MessageQ_getLocalHandle(MessageQ_QueueId queueId);
681 /** @endcond INTERNAL */
684 /** @cond INTERNAL */
685 Void MessageQ_Params_init__S(MessageQ_Params *params, Int version);
686 /** @endcond INTERNAL */
688 /*!
689  *  @brief      Initialize MessageQ_Params
690  *
691  *  Initialized the given structure to its default values.
692  *
693  *  @param[in]  params      Parameters required to create a MessageQ
694  */
695 #ifndef MessageQ_internal
696 static inline Void MessageQ_Params_init(MessageQ_Params *params)
698     if (params != NULL) {
699         MessageQ_Params_init__S(params, MessageQ_Params_VERSION);
700     }
702 #endif
704 /*!
705  *  @brief      Initialize MessageQ_Params2
706  *
707  *  Initialized the given structure to its default values.
708  *
709  *  @deprecated This function has been deprecated. It will be removed
710  *  in a future release. Please use MessageQ_Params_init() instead.
711  *
712  *  @param[in]  params      Parameters required to create a MessageQ
713  */
714 Void MessageQ_Params2_init(MessageQ_Params2 *params);
716 /*!
717  *  @brief      Create a MessageQ instance
718  *
719  *  The name supplied here does not have to be in persistent memory.  The
720  *  maximum length of the string supplied here, including the '\\0' terminator,
721  *  is '32' by default.
722  *
723  *  There are no verifications to ensure that the name supplied in
724  *  MessageQ_create() is unique across all processors. Caution must be exercised
725  *  to ensure that each processor uses a unique name.
726  *
727  *  @param[in]  name        Name of the queue
728  *  @param[in]  params      Initialized MessageQ parameters
729  *
730  *  @return     MessageQ Handle
731  */
732 MessageQ_Handle MessageQ_create(String name, const MessageQ_Params *params);
734 /*!
735  *  @brief      Announce a previously created MessageQ to NameServer
736  *              (Linux/Android only)
737  *
738  *  The name supplied here does not have to be in persistent memory.  The
739  *  maximum length of the string supplied here, including the '\\0' terminator,
740  *  is '32' by default.
741  *
742  *  There are no verifications to ensure that the name supplied in
743  *  MessageQ_announce() is unique across all processors. Caution must be
744  *  exercised to ensure that each processor uses a unique name.
745  *
746  *  @param[in]  name        Name of the queue
747  *  @param[in]  handlePtr   Pointer to handle returned from MessageQ_create.
748  *
749  *  @return     MessageQ status:
750  *              - #MessageQ_E_FAIL: announce failed
751  *              - #MessageQ_S_SUCCESS: announce successful
752  */
753 Int MessageQ_announce(String name, MessageQ_Handle * handlePtr);
755 /*!
756  *  @brief      Create a MessageQ instance using the type MessageQ_Params2
757  *
758  *  The name supplied here does not have to be in persistent memory.  The
759  *  maximum length of the string supplied here, including the '\\0' terminator,
760  *  is '32' by default.
761  *
762  *  There are no verifications to ensure that the name supplied in
763  *  MessageQ_create2() is unique across all processors. Caution must
764  *  be exercised to ensure that each processor uses a unique name.
765  *
766  *  @deprecated This function has been deprecated. It will be removed
767  *  in a future release. Please use MessageQ_create() instead.
768  *
769  *  @param[in]  name        Name of the queue
770  *  @param[in]  params      Initialized MessageQ_Params2
771  *
772  *  @return     MessageQ Handle
773  */
774 MessageQ_Handle MessageQ_create2(String name, const MessageQ_Params2 *params);
776 /*!
777  *  @brief      Delete a created MessageQ instance
778  *
779  *  This function deletes a created message queue instance. If the
780  *  message queue is non-empty, any messages remaining in the queue
781  *  will not be freed and will be lost.
782  *
783  *  @param[in,out]  handlePtr   Pointer to handle to delete.
784  *
785  *  @return     MessageQ status:
786  *              - #MessageQ_E_FAIL: delete failed
787  *              - #MessageQ_S_SUCCESS: delete successful
788  */
789 Int MessageQ_delete(MessageQ_Handle *handlePtr);
791 /*!
792  *  @brief      Open a message queue
793  *
794  *  MessageQ_open() is used to retrieve the queue id for a queue that has been
795  *  created either locally or remotely.  Note that the queueId is simply a
796  *  32 bit value that uniquely identifies a queue.  Therefore, it is also
797  *  possible to put a message on a queue whose queueId has been retrieved using
798  *  any other method.
799  *
800  *  @param[in]  name        Name of queue to open
801  *  @param[out] queueId     QueueId that can be used in MessageQ_put()
802  *
803  *  @return     MessageQ status:
804  *              - #MessageQ_E_NOTFOUND: open failed (name not found on any
805  *                processor)
806  *              - #MessageQ_S_SUCCESS: open successful
807  */
808 Int MessageQ_open(String name, MessageQ_QueueId *queueId);
810 /*!
811  *  @brief      Open a MessageQ given the queue index and processor ID
812  *
813  *  This function can be used instead of MessageQ_open() if the queue
814  *  was created with a reserved queue index. In the example below, the
815  *  serverFxn function must be running on the processor with PROCID 2.
816  *
817  *      @code
818  *      #define SERVER_QUEIDX   1
819  *      #define SERVER_PROCID   2
820  *
821  *      serverFxn()
822  *      {
823  *          MessageQ_Params params;
824  *
825  *          MessageQ_Params_init(&params);
826  *          params.queueIndex = SERVER_QUEIDX;
827  *          messageQ = MessageQ_create(NULL, &params);
828  *          ...
829  *      }
830  *
831  *      clientFxn()
832  *      {
833  *          MessageQ_QueueId serverQueue;
834  *          serverQueue = MessageQ_openQueueId(SERVER_QUEIDX, SERVER_PROCID);
835  *      }
836  *      @endcode
837  *
838  *  It is up to the application to guarantee that the queue which is being
839  *  opened has already been created. MessageQ_openQueueId() does not validate
840  *  that the queue has been created (unlike the MessageQ_open() function).
841  *
842  *  @param[in] queueIndex   QueueIndex specified in MessageQ_Params when
843  *                          the message queue was created.
844  *  @param[in] procId       Multiproc_Id of where the created queue resides.
845  *
846  *  @return     The MessageQ_QueueId associated with the queueIndex
847  *              and remoteProcId
848  */
849 MessageQ_QueueId MessageQ_openQueueId(UInt16 queueIndex, UInt16 procId);
851 /*!
852  *  @brief      Close the opened handle
853  *
854  *  Only close a queueId that was returned from MessageQ_open().
855  *
856  *  @param[in]  queueId     Pointer to queueId to close
857  *
858  *  @return     MessageQ status:
859  *              - #MessageQ_E_FAIL: close failed
860  *              - #MessageQ_S_SUCCESS: close successful
861  */
862 Int MessageQ_close(MessageQ_QueueId *queueId);
864 /*!
865  *  @brief      Allocates a message from the heap
866  *
867  *  This function allocates a message from the heap associated with the heapId.
868  *  The first field of the message must be a #MessageQ_MsgHeader structure.
869  *  For example:
870  *      @code
871  *      typedef struct MyMsg {
872  *         MessageQ_MsgHeader header;
873  *         ...
874  *      } MyMsg;
875  *      @endcode
876  *
877  *  @param[in]  heapId      heapId
878  *  @param[in]  size        size of requested message (including the
879  *                          #MessageQ_MsgHeader).
880  *
881  *  @pre        @c size must be at least large enough to hold a
882  *              MessageQ_MsgHeader
883  *
884  *  @return    Allocated message or NULL if no memory.
885  */
886 MessageQ_Msg MessageQ_alloc(UInt16 heapId, UInt32 size);
888 /*!
889  *  @brief      Frees a message back to the heap
890  *
891  *  Frees the message back to the heap that was used to allocate it.
892  *
893  *  @param[in]  msg         Message to free.
894  *
895  *  @return     MessageQ status:
896  *              - #MessageQ_E_FAIL: failed to free message
897  *              - #MessageQ_S_SUCCESS: successfully freed the message
898  */
899 Int MessageQ_free(MessageQ_Msg msg);
901 /*!
902  *  @brief      Register a heap with MessageQ
903  *
904  *  This function registers a heap with MessageQ. The user selects a unique
905  *  heapId associated with this heap. When a message is allocated via
906  *  MessageQ_alloc(), the heapId is specified. Internally, MessageQ
907  *  uses the heapId to access the heap.
908  *
909  *  Care must be taken when assigning heapIds. Internally MessageQ stores
910  *  the heapId into the message. When the message is freed
911  *  (via MessageQ_free()), the heapId is used to determine which heap to use.
912  *  On systems with shared memory the heapIds must match on corresponding
913  *  processors. For example, assume there is a heap called myHeap which
914  *  acts on shared memory and processors 0 and 1 both use this heap.
915  *  When you register the heap with MessageQ, the same heapId must be used
916  *  on both processor 0 and 1.
917  *
918  *  If a heap is already registered for the specified heapId, no action is
919  *  taken and #MessageQ_E_ALREADYEXISTS is returned.
920  *
921  *  @param[in]  heap        Heap to register
922  *  @param[in]  heapId      heapId associated with the heap
923  *
924  *  @return     MessageQ status:
925  *              - #MessageQ_S_SUCCESS: heap successfully registered
926  *              - #MessageQ_E_ALREADYEXISTS: heap already exists with heapId
927  */
928 Int MessageQ_registerHeap(Ptr heap, UInt16 heapId);
930 /*!
931  *  @brief      Register a transport instance for the given ID
932  *
933  *  Additional transport instances can be registered with the MessageQ
934  *  module. This allows for message delivery over selected transports.
935  *
936  *  To arrange for a message to be delivered using a registered transport,
937  *  the corresponding transport ID must be set in the message header by
938  *  calling MessageQ_setTransportId().
939  *
940  *  @param[in]  tid         Transport ID, must be 1-7 inclusive
941  *  @param[in]  inst        Transport instance handle
942  *
943  *  @return     Status result
944  *              - TRUE: transport handle successfully registered
945  *              - FALSE: failure, most likely transport ID already in use
946  *
947  *  @sa         MessageQ_setTransportId()
948  *  @sa         MessageQ_unregisterTransportId()
949  */
950 Bool MessageQ_registerTransportId(UInt tid, ITransport_Handle inst);
952 /*!
953  *  @brief      Unregister a heap with MessageQ
954  *
955  *  This function unregisters the heap associated with the heapId.
956  *  Care must be taken to ensure that there are no outstanding messages
957  *  allocated from this heap. If there are outstanding messages, an attempt
958  *  to free the message will result in non-deterministic results.
959  *
960  *  @param[in]  heapId      Heap to unregister
961  *
962  *  @return     MessageQ status:
963  *              - #MessageQ_S_SUCCESS: heap successfully unregistered
964  */
965 Int MessageQ_unregisterHeap(UInt16 heapId);
967 /*!
968  *  @brief      Unregister the transport instance for the given ID
969  *
970  *  Remove the registered transport instance for the give transport ID.
971  *
972  *  @param[in]  tid         Transport ID, must be 1-7 inclusive
973  *
974  *  @sa         MessageQ_registerTransportId()
975  */
976 Void MessageQ_unregisterTransportId(UInt tid);
978 /*!
979  *  @brief      Sets the message tracing flag on a given message
980  *
981  *  This function enables message tracing for a message.  Tracing is offered
982  *  in the form of Log messages that are output during operations on the
983  *  message (i.e. MessageQ_free(), MessageQ_put(), etc).
984  *
985  *  @param      msg         Message
986  *  @param      traceFlag   Message trace flag (TRUE = tracing enabled)
987  */
988 Void MessageQ_setMsgTrace(MessageQ_Msg msg, Bool traceFlag);
990 /*!
991  *  @brief      Initializes a message not obtained from MessageQ_alloc()
992  *
993  *  There are several fields in the #MessageQ_MsgHeader that
994  *  are initialized by the MessageQ_alloc() function. MessageQ_staticMsgInit()
995  *  can be used to initialize these fields for messages that are
996  *  not allocated from MessageQ.
997  *
998  *  There is one strict constraint with using messages not allocated
999  *  from MessageQ. The message cannot be freed via MessageQ_free().
1000  *  This includes
1001  *      - The application calling MessageQ_free() on the same processor
1002  *      - The application calling MessageQ_free() on a different processor
1003  *      - The application cannot send the message to another processor
1004  *        where the transport might call MessageQ_free() on the message.
1005  *        For example, copy based transport call MessageQ_free() after sending
1006  *        the message.
1007  *  If a staticMsgInit'd msg is passed to MessageQ_free() an assert will occur
1008  *
1009  *  @param      msg     Message to initialize
1010  *  @param[in]  size    Size of the message in MAUs
1011  *
1012  *  @pre    @c size must be at least large enough to hold a #MessageQ_MsgHeader
1013  */
1014 Void MessageQ_staticMsgInit(MessageQ_Msg msg, UInt32 size);
1016 /*!
1017  *  @brief      Sets MessageQ's free hook function.
1018  *
1019  *  This API allows a user to specify a hook function which is called within
1020  *  MessageQ_free(). The hook is called after a message is freed back to the
1021  *  associated heap. The two parameters to the hook function are the heapId
1022  *  and the msgId of the freed message.
1023  *
1024  *  The function is called within MessageQ_free(), so care must be taken to
1025  *  minimize any performance or calling context impact.
1026  *
1027  *  MessageQ_setFreeHookFxn() is not thread safe. It should only
1028  *  be called when no MessageQ_free()'s are happening.
1029  *
1030  *  To disable the hook function, call MessageQ_setFreeHookFxn() with NULL.
1031  *
1032  *  @param[in]  freeHookFxn  function to be called within MessageQ_free()
1033  */
1034 Void MessageQ_setFreeHookFxn(MessageQ_FreeHookFxn freeHookFxn);
1036 /*!
1037  *  @brief      Set the function hook for the MessageQ_put() method
1038  *
1039  *  Register a hook function which is called from the beginning of the
1040  *  MessageQ_put() function. Only one hook may be registered at a time.
1041  *  Subsequent calls to register a put function will overwrite the
1042  *  previously registered function.
1043  *
1044  *  To disable the hook function, call MessageQ_setPutHookFxn() with NULL.
1045  *
1046  *  @param[in]  putHookFxn  function to be called within MessageQ_put()
1047  */
1048 Void MessageQ_setPutHookFxn(MessageQ_PutHookFxn putHookFxn);
1050 /* =============================================================================
1051  *  MessageQ Per-instance Functions
1052  * =============================================================================
1053  */
1055 /*!
1056  *  @brief      Gets a message from the message queue
1057  *
1058  *  This function returns a status. It also returns a message in msg.
1059  *  If no message is available, it blocks on the synchronizer object
1060  *  until the synchronizer is signaled or a timeout occurs.
1061  *  The synchronizer is signaled, when Message_put is called on the MessageQ
1062  *  handle. If a timeout occurs, the msg is set to NULL and the status is
1063  *  #MessageQ_E_TIMEOUT. If a timeout of zero is specified, the function
1064  *  returns immediately and if no message is available, the msg
1065  *  is set to NULL and the status is #MessageQ_E_TIMEOUT. The
1066  *  #MessageQ_E_UNBLOCKED status is return, if MessageQ_unblock is called
1067  *  on the MessageQ handle. The #MessageQ_E_SHUTDOWN status is returned if
1068  *  MessageQ_shutdown is called on the MessageQ handle. If a message is
1069  *  successfully retrieved, the msg is set to the message and a
1070  *  #MessageQ_S_SUCCESS status is returned.
1071  *
1072  *  @param[in]  handle      MessageQ handle
1073  *  @param[out] msg         Pointer to the message
1074  *  @param[in]  timeout     Maximum duration to wait for a message in
1075  *                          microseconds.
1076  *
1077  *  @return     MessageQ status:
1078  *              - #MessageQ_S_SUCCESS: Message successfully returned
1079  *              - #MessageQ_E_TIMEOUT: MessageQ_get() timed out
1080  *              - #MessageQ_E_UNBLOCKED: MessageQ_get() was unblocked
1081  *              - #MessageQ_E_FAIL:    A general failure has occurred
1082  *
1083  *  @sa         MessageQ_put()
1084  *  @sa         MessageQ_unblock()
1085  *  @sa         MessageQ_shutdown()
1086  */
1087 Int MessageQ_get(MessageQ_Handle handle, MessageQ_Msg *msg, UInt timeout);
1089 /*!
1090  *  @brief      Place a message onto a message queue
1091  *
1092  *  This call places the message onto the specified message queue. The
1093  *  message queue could be local or remote. The MessageQ module manages
1094  *  the delivery.
1095  *
1096  *  In the case where the queue is remote, MessageQ does not guarantee that
1097  *  the message is actually delivered before the MessageQ_put() call returns
1098  *
1099  *  The queue id must have been returned from one of the following functions:
1100  *  - MessageQ_open()
1101  *  - MessageQ_getReplyQueue()
1102  *  - MessageQ_getDstQueue()
1103  *
1104  *  After the message is placed onto the final destination, the queue's
1105  *  #MessageQ_Params.synchronizer signal function is called.
1106  *
1107  *  The application loses ownership of the message once MessageQ_put() is called.
1108  *
1109  *  @param[in]  queueId     Destination MessageQ
1110  *  @param[in]  msg         Message to be sent.
1111  *
1112  *  @return     Status of the call.
1113  *              - #MessageQ_S_SUCCESS denotes success.
1114  *              - #MessageQ_E_FAIL denotes failure. The put was not successful.
1115  *                 The caller still owns the message.
1116  */
1117 Int MessageQ_put(MessageQ_QueueId queueId, MessageQ_Msg msg);
1119 /*!
1120  *  @brief      Returns the number of messages in a message queue
1121  *
1122  *  This function returns the number of messages in a message queue.
1123  *
1124  *  @param[in]  handle      MessageQ handle
1125  *
1126  *  @return     Number of messages in the message queue.
1127  */
1128 Int MessageQ_count(MessageQ_Handle handle);
1130 /*!
1131  *  @brief      Returns the QueueId associated with the handle
1132  *
1133  *  Since the MessageQ_put() function takes a QueueId, the creator
1134  *  of a message queue cannot send a message to itself without
1135  *  retrieving the QueueId. This function extracts the QueueId
1136  *  from the object.
1137  *
1138  *  @param[in]  handle      MessageQ handle
1139  *
1140  *  @return     QueueId associated to the object
1141  */
1142 UInt32 MessageQ_getQueueId(MessageQ_Handle handle);
1144 /*!
1145  *  @brief      Embeds a source message queue into a message
1146  *
1147  *  This function along with MessageQ_getReplyQueue()
1148  *  can be used instead of MessageQ_open(). The sender
1149  *  of a message can embed a messageQ into the message with this
1150  *  function. The receiver of the message can extract the message queue
1151  *  id with the MessageQ_getReplyQueue() function.
1152  *
1153  *  This method is particularly useful in a client/server relationship
1154  *  where the server does not want to know who the clients are. The
1155  *  clients can embed their message queue into the message to the server
1156  *  and the server extracts it and uses it to reply.
1157  *
1158  *  @param      handle      MessageQ handle
1159  *  @param      msg         Message to embed queue into
1160  */
1161 Void MessageQ_setReplyQueue(MessageQ_Handle handle, MessageQ_Msg msg);
1163 /*!
1164  *  @brief      Unblocks a MessageQ
1165  *
1166  *  Unblocks a reader thread that is blocked on a MessageQ_get().  The
1167  *  MessageQ_get() call will return with status #MessageQ_E_UNBLOCKED indicating
1168  *  that it returned due to a MessageQ_unblock() rather than a timeout or a
1169  *  received message.  This call should only be used during a shutdown sequence
1170  *  in order to ensure that there is no blocked reader on a queue before
1171  *  deleting the queue.  A queue may not be used after it has been unblocked.
1172  *
1173  *  MessageQ_unblock() works by raising a flag in the queue indicating that it
1174  *  is unblocked and then signaling the synchronizer that is configured with
1175  *  the target queue.  If MessageQ_unblock() is called upon a queue that has
1176  *  no blocked listeners, then any subsequent MessageQ_get will not block and
1177  *  will immediately return #MessageQ_E_UNBLOCKED regardless of whether there
1178  *  is a message on the queue.
1179  *
1180  *  Restrictions:
1181  *  -  A queue may not be used after it has been unblocked.
1182  *  -  MessageQ_unblock() may only be called on a local queue.
1183  *  -  May only be used with a queue configured with a blocking synchronizer.
1184  *
1185  *  @param[in]  handle      MessageQ handle
1186  *
1187  *  @sa         MessageQ_get
1188  *  @sa         MessageQ_shutdown()
1189  */
1190 Void MessageQ_unblock(MessageQ_Handle handle);
1192 /*!
1193  *  @brief      Shuts down a MessageQ
1194  *
1195  *  Similar to MessageQ_unblock(), MessageQ_shutdown() unblocks a reader thread
1196  *  that is blocked on a MessageQ_get(), but causes a different return code
1197  *  to be returned from MessageQ_get().  The MessageQ_get() call will return
1198  *  with status #MessageQ_E_SHUTDOWN indicating that it returned due to a
1199  *  MessageQ_shutdown() rather than MessageQ_unblock(), a timeout or a
1200  *  received message.  This call is intended to be used by MessageQ transports
1201  *  when the transport detects that the transport framework corresponding to
1202  *  the MessageQ has become unusable.  This call should only be used during a
1203  *  shutdown sequence in order to ensure that there is no blocked reader on a
1204  *  queue before deleting the queue.  A queue may not be used after it has been
1205  *  shut down.
1206  *
1207  *  MessageQ_shutdown() works by raising a flag in the queue indicating that it
1208  *  is shut down and then signaling the synchronizer that is configured with
1209  *  the target queue.  If MessageQ_shutdown() is called upon a queue that has
1210  *  no blocked listeners, then any subsequent MessageQ_get will not block and
1211  *  will immediately return #MessageQ_E_SHUTDOWN regardless of whether there
1212  *  is a message on the queue.
1213  *
1214  *  Restrictions:
1215  *  -  A queue may not be used after it has been shut down.
1216  *  -  MessageQ_shutdown() may only be called on a local queue.
1217  *  -  May only be used with a queue configured with a blocking synchronizer.
1218  *
1219  *  @param[in]  handle      MessageQ handle
1220  *
1221  *  @sa         MessageQ_get
1222  *  @sa         MessageQ_unblock
1223  */
1224 Void MessageQ_shutdown(MessageQ_Handle handle);
1226 #if defined (__cplusplus)
1228 #endif /* defined (__cplusplus) */
1229 #endif /* ti_ipc_MessageQ__include */