ca32bb906664b8c9b487201278d9d189e67b31d2
1 /*
2 * Copyright (c) 2012-2014 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 */
32 /*
33 * ======== MessageQ.xdc ========
34 *
35 */
37 package ti.sdo.ipc;
39 import xdc.runtime.IHeap;
40 import xdc.runtime.Assert;
41 import xdc.runtime.Error;
42 import xdc.runtime.Diags;
43 import xdc.runtime.Log;
44 import xdc.runtime.IGateProvider;
45 import xdc.runtime.knl.ISync;
47 import ti.sysbios.syncs.SyncSem;
49 import ti.sdo.ipc.interfaces.ITransport;
50 import ti.sdo.ipc.interfaces.IMessageQTransport;
51 import ti.sdo.utils.NameServer;
52 import ti.sdo.utils.List;
54 import xdc.rov.ViewInfo;
56 /*!
57 * ======== MessageQ ========
58 * Message-passing with queuing
59 *
60 * The MessageQ module supports the structured sending and receiving of
61 * variable length messages. This module can be used for homogeneous
62 * (DSP to DSP) or heterogeneous (Arm to DSP) multi-processor messaging.
63 *
64 * MessageQ provides more sophisticated messaging than other modules. It is
65 * typically used for complex situations such as multi-processor messaging.
66 *
67 * The following are key features of the MessageQ module:
68 * @p(blist)
69 * -Writers and readers can be relocated to another processor with no
70 * runtime code changes.
71 * -Timeouts are allowed when receiving messages.
72 * -Readers can determine the writer and reply back.
73 * -Receiving a message is deterministic when the timeout is zero.
74 * -Messages can reside on any message queue.
75 * -Supports zero-copy transfers.
76 * -Can send and receive from any type of thread.
77 * -Notification mechanism is specified by application.
78 * -Allows QoS (quality of service) on message buffer pools. For example,
79 * using specific buffer pools for specific message queues.
80 * @p
81 *
82 * Messages are sent and received by being placed on and removed from a
83 * message queue. A reader is a thread that gets (reads) messages from a
84 * message queue. A writer is a thread that puts (writes) a message to a
85 * message queue. Each message queue has one reader and can have many writers.
86 * A thread may read from or write to multiple message queues.
87 *
88 * Conceptually, the reader thread owns a message queue. The reader thread
89 * creates a message queue. The writer threads open a created message queue
90 * to get access to them.
91 *
92 * Message queues are identified by a system-wide unique name. Internally,
93 * MessageQ uses the {@link ti.sdo.utils.NameServer} module for managing
94 * these names. The names are used for opening a message queue.
95 *
96 * Messages must be allocated from the MessageQ module. Once a message is
97 * allocated, it can be sent to any message queue. Once a message is sent, the
98 * writer loses ownership of the message and should not attempt to modify the
99 * message. Once the reader receives the message, it owns the message. It
100 * may either free the message or re-use the message.
101 *
102 * Messages in a message queue can be of variable length. The only
103 * requirement is that the first field in the definition of a message must be a
104 * {@link #MsgHeader} structure. For example:
105 * @p(code)
106 * typedef struct MyMsg {
107 * MessageQ_MsgHeader header;
108 * ...
109 * } MyMsg;
110 * @p
111 *
112 * The MessageQ API uses the MessageQ_MsgHeader internally. Your application
113 * should not modify or directly access the fields in the MessageQ_MsgHeader.
114 *
115 * All messages sent via the MessageQ module must be allocated from a
116 * {@link xdc.runtime.IHeap} implementation. The heap can also be used for
117 * other memory allocation not related to MessageQ.
118 *
119 * An application can use multiple heaps. The purpose of having multiple
120 * heaps is to allow an application to regulate its message usage. For
121 * example, an application can allocate critical messages from one heap of fast
122 * on-chip memory and non-critical messages from another heap of slower
123 * external memory.
124 *
125 * The {@link #registerHeap} and {@link #registerHeapMeta} are APIs used to
126 * assign a MessageQ heapId to a heap. When allocating a message, the heapId
127 * is used, not the heap handle. This heapId is actually placed into the
128 * message (part of the {@link #MsgHeader}). Care must be taken when assigning
129 * heapIds. Refer to the {@link #registerHeap} and {@link #registerHeapMeta}
130 * descriptions for more details.
131 *
132 * MessageQ also supports the usage of messages that are not allocated via the
133 * {@link #alloc} function. Please refer to the {@link #staticMsgInit}
134 * function description for more details.
135 *
136 * MessageQ supports reads/writes of different thread models. This is
137 * accomplished by having the creator of the message queue specify a
138 * {@link xdc.runtime.knl.ISync#Object} via the {@link #synchronizer}
139 * configuration parameter. The {@link xdc.runtime.knl.ISync#signal}
140 * portion of the ISync instance is called whenever the {@link #put}
141 * is called. The {@link xdc.runtime.knl.ISync#wait} portion is
142 * called in the {@link #get} if and only if there are no messages.
143 *
144 * Since ISyncs are binary, the reader must drain the message queue of all
145 * messages before waiting for another signal. For example, if the reader
146 * was a SYSBIOS Swi, the {@link xdc.runtime.knl.ISync} instance
147 * could be a SyncSwi. If a {@link #put} was called, the Swi_post() would
148 * be called. The Swi would run and it must call {@link #get} until no
149 * messages are returned.
150 *
151 * In a multiple processor system, MessageQ communicates to other
152 * processors via {@link ti.sdo.ipc.interfaces.IMessageQTransport} instances.
153 * MessageQ supports a high priority and a normal priority transport between
154 * any two processors. The IMessageQTransport instances are created via the
155 * {@link #SetupTransportProxy}. The instances are responsible for
156 * registering themselves with MessageQ. This is accomplished via the
157 * {@link #registerTransport} function.
158 */
160 @ModuleStartup
161 @InstanceInitError
162 @InstanceFinalize
164 module MessageQ
165 {
166 /*!
167 * ======== QueuesView ========
168 * @_nodoc
169 */
170 metaonly struct QueuesView {
171 String name;
172 UInt queueId;
173 }
175 /*!
176 * ======== MessagesView ========
177 * @_nodoc
178 */
179 metaonly struct MessagesView {
180 Int seqNum;
181 Int msgSize;
182 String priority;
183 String srcProc;
184 String replyProc;
185 String replyId;
186 Int msgId;
187 String heap;
188 Bool traceEnabled;
189 Int version;
190 }
192 /*!
193 * ======== ModuleView ========
194 * @_nodoc
195 */
196 metaonly struct ModuleView {
197 String heaps[];
198 String gate;
199 UInt16 nextSeqNum;
200 String freeHookFxn[];
201 }
203 /*!
204 * ======== rovViewInfo ========
205 * @_nodoc
206 */
207 @Facet
208 metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
209 xdc.rov.ViewInfo.create({
210 viewMap: [
211 ['Queues',
212 {
213 type: xdc.rov.ViewInfo.INSTANCE,
214 viewInitFxn: 'viewInitQueues',
215 structName: 'QueuesView'
216 }
217 ],
218 ['Messages',
219 {
220 type: xdc.rov.ViewInfo.INSTANCE_DATA,
221 viewInitFxn: 'viewInitMessages',
222 structName: 'MessagesView'
223 }
224 ],
225 ['Module',
226 {
227 type: xdc.rov.ViewInfo.MODULE,
228 viewInitFxn: 'viewInitModule',
229 structName: 'ModuleView'
230 }
231 ]
232 ]
233 });
235 /*!
236 * ======== LM_setTrace ========
237 * Logged when setting the trace flag on a message
238 *
239 * This is logged when tracing on a message is set via
240 * {@link #setMsgTrace}.
241 */
242 config Log.Event LM_setTrace = {
243 mask: Diags.USER1,
244 msg: "LM_setTrace: Message 0x%x (seqNum = %d, srcProc = %d) traceFlag = %d"
245 };
247 /*!
248 * ======== LM_alloc ========
249 * Logged when allocating a message
250 *
251 * When the {@link #traceFlag} is true, all message allocations
252 * are logged.
253 */
254 config Log.Event LM_alloc = {
255 mask: Diags.USER1,
256 msg: "LM_alloc: Message 0x%x (seqNum = %d, srcProc = %d) was allocated"
257 };
259 /*!
260 * ======== LM_staticMsgInit ========
261 * Logged when statically initializing a message
262 *
263 * When the {@link #traceFlag} is true, all messages that
264 * are statically initialized via {@link #staticMsgInit} are logged.
265 */
266 config Log.Event LM_staticMsgInit = {
267 mask: Diags.USER1,
268 msg: "LM_staticMsgInit: Message 0x%x (seqNum = %d, srcProc = %d) was set in MessageQ_staticMsgInit"
269 };
271 /*!
272 * ======== LM_free ========
273 * Logged when freeing a message
274 *
275 * When the {@link #traceFlag} is true, all freeing of messages
276 * are logged. If an individual message's tracing was enabled
277 * via {@link #setMsgTrace}, the MessageQ_free is also logged.
278 */
279 config Log.Event LM_free = {
280 mask: Diags.USER1,
281 msg: "LM_free: Message 0x%x (seqNum = %d, srcProc = %d) was freed"
282 };
284 /*!
285 * ======== LM_putLocal ========
286 * Logged when a message is placed onto a local queue
287 *
288 * When the {@link #traceFlag} is true, all putting of messages
289 * are logged. If an individual message's tracing was enabled
290 * via {@link #setMsgTrace}, the MessageQ_put is also logged.
291 */
292 config Log.Event LM_putLocal = {
293 mask: Diags.USER1,
294 msg: "LM_putLocal: Message 0x%x (seqNum = %d, srcProc = %d) was placed onto queue 0x%x"
295 };
297 /*!
298 * ======== LM_putRemote ========
299 * Logged when a message is given to a transport
300 *
301 * When the {@link #traceFlag} is true, all putting of messages
302 * to a transport are logged. If an individual message's tracing
303 * was enabled via {@link #setMsgTrace}, the MessageQ_put is
304 * also logged.
305 */
306 config Log.Event LM_putRemote = {
307 mask: Diags.USER1,
308 msg: "LM_putRemote: Message 0x%x (seqNum = %d, srcProc = %d) was given to processor %d transport"
309 };
311 /*!
312 * ======== LM_rcvByTransport ========
313 * Logged when a transport receives an incoming message
314 *
315 * When the {@link #traceFlag} is true, all incoming messages
316 * are logged. If an individual message's tracing
317 * was enabled via {@link #setMsgTrace}, the receiving of a message is
318 * also logged.
319 */
320 config Log.Event LM_rcvByTransport = {
321 mask: Diags.USER1,
322 msg: "LM_rcvByTransport: Message 0x%x (seqNum = %d, srcProc = %d) was received"
323 };
325 /*!
326 * ======== LM_get ========
327 * Logged when a message is received off the queue
328 *
329 * When the {@link #traceFlag} is true, all getting of messages
330 * are logged. If an individual message's tracing
331 * was enabled via {@link #setMsgTrace}, the MessageQ_get is
332 * also logged.
333 */
334 config Log.Event LM_get = {
335 mask: Diags.USER1,
336 msg: "LM_get: Message 0x%x (seqNum = %d, srcProc = %d) was received by queue 0x%x"
337 };
339 /*!
340 * ======== FreeHookFxn ========
341 * Function prototype for the MessageQ_free callback
342 *
343 * @param(Bits16) heapId of message that was freed
344 * @param(Bits16) msgId of message that was freed
345 */
346 typedef Void (*FreeHookFxn)(Bits16, Bits16);
348 /*!
349 * ======== PutHookFxn ========
350 * Function prototype for the MessageQ_put callback
351 *
352 * @param(Bits32) queueId of the destination message queue
353 * @param(Ptr) pointer to a message header structure
354 */
355 typedef Void (*PutHookFxn)(Bits32, Ptr);
357 /*! MessageQ ID */
358 typedef UInt32 QueueId;
360 /*!
361 * ======== SetupTransportProxy ========
362 * MessageQ transport setup proxy
363 */
364 proxy SetupTransportProxy inherits ti.sdo.ipc.interfaces.ITransportSetup;
366 /*!
367 * Message priority values. These must match the values defined in
368 * ti/ipc/MessageQ.h but are needed here for ROV.
369 */
370 const UInt NORMALPRI = 0;
371 const UInt HIGHPRI = 1;
372 const UInt RESERVEDPRI = 2;
373 const UInt URGENTPRI = 3;
375 /*!
376 * Denotes any queueId is acceptable
377 *
378 * This constant is the default for the {@link #queueId} parameter.
379 * This value must match ti/ipc/MessageQ.h but is needed to initialize
380 * queueId.
381 */
382 const Bits16 ANY = ~(0);
384 /*!
385 * Assert raised when calling API with wrong handle
386 *
387 * Some APIs can only be called with an opened handle (e.g.
388 * {@link #close}. Some can only be called with a created handle
389 * (e.g. {@link #get}).
390 */
391 config Assert.Id A_invalidContext = {
392 msg: "A_invalidContext: Cannot call with an open/create handle"
393 };
395 /*!
396 * Assert raised when attempting to free a static message
397 */
398 config Assert.Id A_cannotFreeStaticMsg = {
399 msg: "A_cannotFreeStaticMsg: Cannot call MessageQ_free with static msg"
400 };
402 /*!
403 * Assert raised when an invalid message is supplied
404 */
405 config Assert.Id A_invalidMsg = {
406 msg: "A_invalidMsg: Invalid message"
407 };
409 /*!
410 * Assert raised when an invalid queueId is supplied
411 */
412 config Assert.Id A_invalidQueueId = {
413 msg: "A_invalidQueueId: Invalid queueId is used"
414 };
416 /*!
417 * Assert raised when using an invalid heapId
418 */
419 config Assert.Id A_heapIdInvalid = {
420 msg: "A_heapIdInvalid: heapId is invalid"
421 };
423 /*!
424 * Assert raised when using an invalid procId
425 */
426 config Assert.Id A_procIdInvalid = {
427 msg: "A_procIdInvalid: procId is invalid"
428 };
430 /*!
431 * Assert raised for an invalid MessageQ object
432 */
433 config Assert.Id A_invalidObj = {
434 msg: "A_invalidObj: an invalid obj is used"
435 };
437 /*!
438 * Assert raised for an invalid parameter
439 */
440 config Assert.Id A_invalidParam = {
441 msg: "A_invalidParam: an invalid parameter was passed in"
442 };
444 /*!
445 * Assert raised when attempting to send a message to a core
446 * where a transport has not been registered.
447 */
448 config Assert.Id A_unregisteredTransport = {
449 msg: "A_unregisteredTransport: transport is not registered"
450 };
452 /*!
453 * Assert raised when attempting to unblock a remote MessageQ or one that
454 * has been configured with a non-blocking synchronizer
455 */
456 config Assert.Id A_invalidUnblock = {
457 msg: "A_invalidUnblock: Trying to unblock a remote MessageQ or a queue with non-blocking synchronizer"
458 };
460 /*!
461 * Error raised if all the message queue objects are taken
462 */
463 config Error.Id E_maxReached = {
464 msg: "E_maxReached: All objects in use. MessageQ.maxRuntimeEntries is %d"
465 };
467 /*!
468 * Error raised when heapId has not been registered
469 */
470 config Error.Id E_unregisterHeapId = {
471 msg: "E_unregisterHeapId: Heap id %d not registered"
472 };
474 /*!
475 * Error raised in a create call when a name fails to be added
476 * to the NameServer table. This can be because the name already
477 * exists, the table has reached its max length, or out of memory.
478 */
479 config Error.Id E_nameFailed = {
480 msg: "E_nameFailed: '%s' name failed to be added to NameServer"
481 };
483 /*!
484 * Error raised if the requested queueIndex is not available
485 */
486 config Error.Id E_indexNotAvailable = {
487 msg: "E_indexNotAvailable: queueIndex %d not available"
488 };
490 /*!
491 * Trace setting
492 *
493 * This flag allows the configuration of the default module trace
494 * settings.
495 */
496 config Bool traceFlag = false;
498 /*!
499 * Number of heapIds in the system
500 *
501 * This allows MessageQ to pre-allocate the heaps table.
502 * The heaps table is used when registering heaps.
503 *
504 * There is no default heap, so unless the system is only using
505 * {@link #staticMsgInit}, the application must register a heap.
506 */
507 config UInt16 numHeaps = 8;
509 /*!
510 * Maximum number of MessageQs that can be dynamically created
511 */
512 config UInt maxRuntimeEntries = NameServer.ALLOWGROWTH;
514 /*!
515 * Number of reserved MessageQ indexes
516 *
517 * An application can request the first N message queue indexes be
518 * reserved to be used by MessageQ_create2. MessageQ_create will
519 * not use these slots. The application can use any index less than
520 * the value of numReservedEntries for the queueIndex field in the
521 * MessageQ_Params2 structure.
522 *
523 * numReservedEntries must be equal or less than
524 * {@link #maxRuntimeEntries}.
525 */
526 config UInt numReservedEntries = 0;
528 /*!
529 * Gate used to make the name table thread safe
530 *
531 * This gate is used when accessing the name table during
532 * a {@link #create}, {@link #delete}, and {@link #open}.
533 *
534 * This gate is also used to protect MessageQ when growing
535 * internal tables in the {@link #create}.
536 *
537 * The table is in local memory, not shared memory. So a
538 * single processor gate will work.
539 *
540 * The default will be {@link xdc.runtime.knl.GateThread}
541 * instance.
542 */
543 config IGateProvider.Handle nameTableGate = null;
545 /*!
546 * Maximum length for Message queue names
547 */
548 config UInt maxNameLen = 32;
550 /*!
551 * Section name is used to place the names table
552 */
553 metaonly config String tableSection = null;
555 /*!
556 * ======== freeHookFxn ========
557 * Free function in MessageQ_free after message was freed back to the heap
558 */
559 config FreeHookFxn freeHookFxn = null;
561 /*!
562 * ======== putHookFxn ========
563 * Put function hook
564 */
565 config PutHookFxn putHookFxn = null;
567 /*!
568 * ======== registerHeapMeta ========
569 * Statically register a heap with MessageQ
570 *
571 * Build error if heapId is in use.
572 *
573 * @param(heap) Heap to register
574 * @param(heapId) heapId associated with the heap
575 */
576 metaonly Void registerHeapMeta(IHeap.Handle heap, UInt16 heapId);
578 /*!
579 * ======== registerTransportMeta ========
580 * Statically register a transport with MessageQ
581 *
582 * Build error if remote processor already has a transport
583 * registered.
584 *
585 * @param(transport) transport to register
586 * @param(procId) procId that transport communicaties with
587 * @param(priority) priority of transport
588 */
589 metaonly Void registerTransportMeta(IMessageQTransport.Handle transport, UInt16 procId, UInt priority);
591 /*!
592 * ======== registerTransport ========
593 * Register a transport with MessageQ
594 *
595 * This API is called by the transport when it is created.
596 *
597 * @param(transport) transport to register
598 * @param(procId) MultiProc id that transport communicates with
599 * @param(priority) priority of transport
600 *
601 * @b(returns) Whether the register was successful.
602 */
603 Bool registerTransport(IMessageQTransport.Handle transport, UInt16 procId,
604 UInt priority);
606 /*!
607 * ======== unregisterTransport ========
608 * Unregister a transport with MessageQ
609 *
610 * @param(procId) unregister transport that communicates with
611 * this remote processor
612 * @param(priority) priority of transport
613 */
614 Void unregisterTransport(UInt16 procId, UInt priority);
616 /*!
617 * ======== registerTransportId ========
618 * Register the transport instance for the given ID
619 */
620 Bool registerTransportId(UInt tid, ITransport.Handle inst);
622 /*!
623 * ======== unregisterTransportId ========
624 * Unregister the transport for the given ID
625 */
626 Bool unregisterTransportId(UInt tid);
628 instance:
630 /*!
631 * ISync handle used to signal IO completion
632 *
633 * The ISync instance is used in the {@link #get} and {@link #put}.
634 * The {@link xdc.runtime.knl.ISync#signal} is called as part
635 * of the {@link #put} call. The {@link xdc.runtime.knl.ISync#wait} is
636 * called in the {@link #get} if there are no messages present.
637 */
638 config ISync.Handle synchronizer = null;
640 /*!
641 * Requested MessageQ_QueueIndex
642 *
643 * This parameter allows an application to specify the queueIndex to
644 * be used for a message queue. To use this functionality, the
645 * MessageQ.numReservedEntries static configuration parameter must be
646 * set to a specific value.
647 *
648 * The default is {@link #ANY}. This means do that you are not asking for
649 * an explicit index. MessageQ will find the first available one which is
650 * equal or greater than MessageQ.numReservedEntries.
651 */
652 config UInt16 queueIndex = ANY;
654 /*! @_nodoc
655 * ======== create ========
656 * Create a message queue
657 *
658 * @param(name) Name of the message queue.
659 */
660 create(String name);
662 internal:
663 /*
664 * The following describes the usage of the flag field
665 * ---------------------------------
666 * |V V V|T| reserved |t t t|P P|
667 * ---------------------------------
668 * F E D C B A 9 8 7 6 5 4 3 2 1 0
669 *
670 * [15:13] V = version
671 * [12] T = trace flag
672 * [11:5] reserved
673 * [4:2] t = transport Id, zero = default
674 * [1:0] P = priority
675 */
677 /*! Mask to extract version setting */
678 const UInt VERSIONMASK = 0xE000;
680 /*! Version setting */
681 const UInt HEADERVERSION = 0x2000;
683 /*! Mask to extract Trace setting */
684 const UInt TRACEMASK = 0x1000;
686 /*! Shift for Trace setting */
687 const UInt TRACESHIFT = 12;
689 /*!
690 * Mask to extract priority setting.
691 * This is needed here for ROV but must match
692 * the value defined in ti/ipc/MessageQ.h
693 */
694 const UInt PRIORITYMASK = 0x3;
696 /*! Mask to extract priority setting */
697 const UInt TRANSPORTPRIORITYMASK = 0x1;
699 /*! return code for Instance_init */
700 const Int PROXY_FAILURE = 1;
702 /*
703 * Used to denote a message that was initialized
704 * with the MessageQ_staticMsgInit function.
705 */
706 const UInt16 STATICMSG = 0xFFFF;
708 /*! Required first field in every message */
709 @Opaque struct MsgHeader {
710 Bits32 reserved0; /* reserved for List.elem->next */
711 Bits32 reserved1; /* reserved for List.elem->prev */
712 Bits32 msgSize; /* message size */
713 Bits16 flags; /* bitmask of different flags */
714 Bits16 msgId; /* message id */
715 Bits16 dstId; /* destination queue id */
716 Bits16 dstProc; /* destination processor id */
717 Bits16 replyId; /* reply queue id */
718 Bits16 replyProc; /* reply processor id */
719 Bits16 srcProc; /* proc who initialized the msg */
720 Bits16 heapId; /* heap id */
721 Bits16 seqNum; /* sequence number */
722 Bits16 reserved; /* reserved */
723 };
725 struct HeapEntry {
726 IHeap.Handle heap;
727 UInt16 heapId;
728 };
730 struct TransportEntry {
731 IMessageQTransport.Handle transport;
732 UInt16 procId;
733 };
735 enum TransportType {
736 TransportType_IMessageQTransport,
737 TransportType_INetworkTransport,
738 TransportType_Invalid
739 };
741 struct RegisteredTransport {
742 ITransport.Handle transport;
743 TransportType type;
744 };
746 /*!
747 * ======== nameSrvPrms ========
748 * This Params object is used for temporary storage of the
749 * module wide parameters that are for setting the NameServer instance.
750 */
751 metaonly config NameServer.Params nameSrvPrms;
753 /*!
754 * Statically registered heaps
755 *
756 * This configuration parameter allows the static registeration
757 * of heaps. The index of the array corresponds to the heapId.
758 */
759 metaonly config HeapEntry staticHeaps[];
761 /*!
762 * Statically registered transports
763 *
764 * This configuration parameter allows the static registeration
765 * of transports. The index of the array corresponds to the procId.
766 */
767 metaonly config TransportEntry staticTransports[];
769 /*!
770 * Allows for the number of dynamically created message queues to grow.
771 */
772 UInt16 grow(Object *obj, Error.Block *eb);
774 struct Instance_State {
775 QueueId queue; /* Unique id */
776 ISync.Handle synchronizer; /* completion synchronizer */
777 List.Object normalList; /* Embedded List objects */
778 List.Object highList; /* Embedded List objects */
779 Ptr nsKey; /* unique NameServer key */
780 SyncSem.Handle syncSemHandle;/* for use in finalize */
781 Bool unblocked; /* Whether MessageQ is unblocked */
782 };
784 struct Module_State {
785 IMessageQTransport.Handle transports[][2];
786 Handle queues[];
787 IHeap.Handle heaps[];
788 IGateProvider.Handle gate;
789 UInt16 numQueues;
790 UInt16 numHeaps;
791 NameServer.Handle nameServer;
792 FreeHookFxn freeHookFxn;
793 PutHookFxn putHookFxn;
794 Bool canFreeQueues;
795 UInt16 seqNum;
796 RegisteredTransport regTrans[8];
797 };
798 }