1    /* --COPYRIGHT--,TI
     2     * Copyright (c) $(CPYYEAR)
     3     * Texas Instruments
     4     *
     5     *  All rights reserved.  Property of Texas Instruments
     6     *  Restricted rights to use, duplicate or disclose this code are
     7     *  granted through contract.
     8     * 
     9     * --/COPYRIGHT--*/
    10    /*
    11     *  ======== MessageQ.xdc ========
    12     *
    13     *! Revision History
    14     *! ================
    15     *! 26-Feb-2010 skp     Fixed SDOCM00067176 (QueueId defined in MessageQ.xdc)
    16     *! 16-Feb-2010 jv      Fix a couple of issues from SDOCM00066822 here.
    17     *! 04-Feb-2010 skp     Removed 'name' from Instance state
    18     *! 07-Aug-2008 skp     cdoc cleanup
    19     *! 04-Jun-2008 agd     cdoc cleanup
    20     *! 14-Dec-2007 connell updated call context table
    21     *! 06-Jun-2007 toddm   nodoc'd the whole module. Not supported in BIOS 6.0.
    22     *! 11-May-2007 agd     Addressed SDSCM00016616
    23     *! 16-Apr-2007 cmcc    Added calling context table
    24     *! 29-Sep-2006 toddm   Added error block into MessageQ_alloc
    25     *! 10-Apr-2006 toddm   created
    26     */
    27    
    28    package ti.sdo.ipc;
    29    
    30    import xdc.runtime.IHeap;
    31    import xdc.runtime.Assert;
    32    import xdc.runtime.Error;
    33    import xdc.runtime.Diags;
    34    import xdc.runtime.Log;
    35    import xdc.runtime.IGateProvider;
    36    import xdc.runtime.knl.ISync;
    37    
    38    import ti.sysbios.syncs.SyncSem;
    39    
    40    import ti.sdo.ipc.interfaces.IMessageQTransport;
    41    import ti.sdo.utils.NameServer;
    42    import ti.sdo.utils.List;
    43    
    44    import xdc.rov.ViewInfo;
    45    
    46    /*!
    47     *  ======== MessageQ ======== 
    48     *  Message-passing with queuing
    49     *
    50     *  The MessageQ module supports the structured sending and receiving of 
    51     *  variable length messages. This module can be used for homogeneous
    52     *  (DSP to DSP)  or heterogeneous (Arm to DSP) multi-processor messaging. 
    53     * 
    54     *  MessageQ provides more sophisticated messaging than other modules. It is
    55     *  typically used for complex situations such as multi-processor messaging. 
    56     * 
    57     *  The following are key features of the MessageQ module:
    58     *  @p(blist)
    59     *  -Writers and readers can be relocated to another processor with no
    60     *   runtime code changes.
    61     *  -Timeouts are allowed when receiving messages.
    62     *  -Readers can determine the writer and reply back.
    63     *  -Receiving a message is deterministic when the timeout is zero.
    64     *  -Messages can reside on any message queue.
    65     *  -Supports zero-copy transfers.
    66     *  -Can send and receive from any type of thread.
    67     *  -Notification mechanism is specified by application.
    68     *  -Allows QoS (quality of service) on message buffer pools. For example,
    69     *   using specific buffer pools for specific message queues.
    70     *  @p
    71     *
    72     *  Messages are sent and received by being placed on and removed from a
    73     *  message queue. A reader is a thread that gets (reads) messages from a
    74     *  message queue. A writer is a thread that puts (writes) a message to a
    75     *  message queue. Each message queue has one reader and can have many writers.
    76     *  A thread may read from or write to multiple message queues.
    77     *
    78     *  Conceptually, the reader thread owns a message queue. The reader thread
    79     *  creates a message queue. The writer threads open a created message queue
    80     *  to get access to them.
    81     *
    82     *  Message queues are identified by a system-wide unique name. Internally, 
    83     *  MessageQ uses the {@link ti.sdo.utils.NameServer} module for managing 
    84     *  these names. The names are used for opening a message queue.
    85     * 
    86     *  Messages must be allocated from the MessageQ module. Once a message is
    87     *  allocated, it can be sent to any message queue. Once a message is sent, the
    88     *  writer loses ownership of the message and should not attempt to modify the
    89     *  message. Once the reader receives the message, it owns the message. It
    90     *  may either free the message or re-use the message.
    91     *
    92     *  Messages in a message queue can be of variable length. The only
    93     *  requirement is that the first field in the definition of a message must be a
    94     *  {@link #MsgHeader} structure. For example:
    95     *  @p(code)
    96     *  typedef struct MyMsg {
    97     *      MessageQ_MsgHeader header;
    98     *      ...
    99     *  } MyMsg;
   100     *  @p
   101     *
   102     *  The MessageQ API uses the MessageQ_MsgHeader internally. Your application
   103     *  should not modify or directly access the fields in the MessageQ_MsgHeader.
   104     *
   105     *  All messages sent via the MessageQ module must be allocated from a 
   106     *  {@link xdc.runtime.IHeap} implementation. The heap can also be used for
   107     *  other memory allocation not related to MessageQ.
   108     *
   109     *  An application can use multiple heaps. The purpose of having multiple
   110     *  heaps is to allow an application to regulate its message usage. For
   111     *  example, an application can allocate critical messages from one heap of fast
   112     *  on-chip memory and non-critical messages from another heap of slower
   113     *  external memory.
   114     *
   115     *  The {@link #registerHeap} and {@link #registerHeapMeta} are APIs used to
   116     *  assign a MessageQ heapId to a heap. When allocating a message, the heapId
   117     *  is used, not the heap handle. This heapId is actually placed into the 
   118     *  message (part of the {@link #MsgHeader}). Care must be taken when assigning
   119     *  heapIds. Refer to the {@link #registerHeap} and {@link #registerHeapMeta}
   120     *  descriptions for more details.
   121     *
   122     *  MessageQ also supports the usage of messages that are not allocated via the
   123     *  {@link #alloc} function. Please refer to the {@link #staticMsgInit}
   124     *  function description for more details.
   125     *
   126     *  MessageQ supports reads/writes of different thread models. This is
   127     *  accomplished by having the creator of the message queue specify a 
   128     *  {@link xdc.runtime.knl.ISync#Object} via the {@link #synchronizer}
   129     *  configuration parameter. The {@link xdc.runtime.knl.ISync#signal} 
   130     *  portion of the ISync instance is called whenever the {@link #put}
   131     *  is called. The {@link xdc.runtime.knl.ISync#wait} portion is 
   132     *  called in the {@link #get} if and only if there are no messages.
   133     *
   134     *  Since ISyncs are binary, the reader must drain the message queue of all
   135     *  messages before waiting for another signal. For example, if the reader 
   136     *  was a SYSBIOS Swi, the {@link xdc.runtime.knl.ISync} instance 
   137     *  could be a SyncSwi. If a {@link #put} was called, the Swi_post() would 
   138     *  be called. The Swi would run and it must call {@link #get} until no 
   139     *  messages are returned.
   140     * 
   141     *  In a multiple processor system, MessageQ communicates to other
   142     *  processors via {@link IMessageQTransport} instances.  MessageQ supports
   143     *  a high priority and a normal priority transport between any two
   144     *  processors. The IMessageQTransport instances are created via the
   145     *  {@link #SetupTransportProxy}. The instances are responsible for
   146     *  registering themselves with MessageQ. This is accomplished via the
   147     * {@link #registerTransport} function.
   148     */
   149    
   150    @ModuleStartup 
   151    @InstanceInitError
   152    @InstanceFinalize
   153    
   154    module MessageQ
   155    {
   156        /*!
   157         *  ======== QueuesView ========
   158         *  @_nodoc
   159         */
   160        metaonly struct QueuesView {
   161            String  name;
   162            UInt    queueId;
   163        }
   164        
   165        /*!
   166         *  ======== MessagesView ========
   167         *  @_nodoc
   168         */
   169        metaonly struct MessagesView {
   170            Int          seqNum;
   171            Int          msgSize;
   172            String       priority;
   173            String       srcProc;        
   174            String       replyProc;
   175            String       replyId;
   176            Int          msgId;          
   177            String       heap;
   178            Bool         traceEnabled;
   179            Int          version;
   180        }
   181    
   182        /*!
   183         *  ======== ModuleView ========
   184         *  @_nodoc
   185         */
   186        metaonly struct ModuleView {        
   187            String               heaps[];        
   188            String               gate;
   189            UInt16               nextSeqNum;
   190        }
   191    
   192        
   193        /*!
   194         *  ======== rovViewInfo ========
   195         *  @_nodoc
   196         */
   197        @Facet
   198        metaonly config xdc.rov.ViewInfo.Instance rovViewInfo = 
   199            xdc.rov.ViewInfo.create({
   200                viewMap: [
   201                    ['Queues',
   202                        {
   203                            type: xdc.rov.ViewInfo.INSTANCE,
   204                            viewInitFxn: 'viewInitQueues',
   205                            structName: 'QueuesView'
   206                        }
   207                    ],
   208                    ['Messages', 
   209                        {
   210                            type: xdc.rov.ViewInfo.INSTANCE_DATA,
   211                            viewInitFxn: 'viewInitMessages',
   212                            structName: 'MessagesView'
   213                        }
   214                    ],
   215                    ['Module', 
   216                        {
   217                            type: xdc.rov.ViewInfo.MODULE,
   218                            viewInitFxn: 'viewInitModule',
   219                            structName: 'ModuleView'
   220                        }
   221                    ]
   222                ]
   223            });
   224        
   225        /*!
   226         *  ======== LM_setTrace ========
   227         *  Logged when setting the trace flag on a message
   228         *
   229         *  This is logged when tracing on a message is set via
   230         *  {@link #setMsgTrace}.
   231         */
   232        config Log.Event LM_setTrace = {
   233            mask: Diags.USER1,
   234            msg: "LM_setTrace: Message 0x%x (seqNum = %d, srcProc = %d) traceFlag = %d"
   235        };
   236        
   237        /*!
   238         *  ======== LM_alloc ========
   239         *  Logged when allocating a message
   240         *
   241         *  When the {@link #traceFlag} is true, all message allocations
   242         *  are logged.
   243         */
   244        config Log.Event LM_alloc = {
   245            mask: Diags.USER1,
   246            msg: "LM_alloc: Message 0x%x (seqNum = %d, srcProc = %d) was allocated"
   247        };
   248        
   249        /*!
   250         *  ======== LM_staticMsgInit ========
   251         *  Logged when statically initializing a message
   252         *
   253         *  When the {@link #traceFlag} is true, all messages that
   254         *  are statically initialized via {@link #staticMsgInit} are logged.
   255         */
   256        config Log.Event LM_staticMsgInit = {
   257            mask: Diags.USER1,
   258            msg: "LM_staticMsgInit: Message 0x%x (seqNum = %d, srcProc = %d) was set in MessageQ_staticMsgInit"
   259        };
   260        
   261        /*!
   262         *  ======== LM_free ========
   263         *  Logged when freeing a message
   264         *
   265         *  When the {@link #traceFlag} is true, all freeing of messages
   266         *  are logged. If an individual message's tracing was enabled 
   267         *  via {@link #setMsgTrace}, the MessageQ_free is also logged.
   268         */
   269        config Log.Event LM_free = {
   270            mask: Diags.USER1,
   271            msg: "LM_free: Message 0x%x (seqNum = %d, srcProc = %d) was freed"
   272        };
   273        
   274        /*!
   275         *  ======== LM_putLocal ========
   276         *  Logged when a message is placed onto a local queue
   277         *
   278         *  When the {@link #traceFlag} is true, all putting of messages
   279         *  are logged. If an individual message's tracing was enabled 
   280         *  via {@link #setMsgTrace}, the MessageQ_put is also logged.
   281         */
   282        config Log.Event LM_putLocal = {
   283            mask: Diags.USER1,
   284            msg: "LM_putLocal: Message 0x%x (seqNum = %d, srcProc = %d) was placed onto queue 0x%x"
   285        };
   286        
   287        /*!
   288         *  ======== LM_putRemote ========
   289         *  Logged when a message is given to a transport
   290         *
   291         *  When the {@link #traceFlag} is true, all putting of messages
   292         *  to a transport are logged. If an individual message's tracing
   293         *  was enabled  via {@link #setMsgTrace}, the MessageQ_put is 
   294         *  also logged.
   295         */
   296        config Log.Event LM_putRemote = {
   297            mask: Diags.USER1,
   298            msg: "LM_putRemote: Message 0x%x (seqNum = %d, srcProc = %d) was given to processor %d transport"
   299        };
   300        
   301        /*!
   302         *  ======== LM_rcvByTransport ========
   303         *  Logged when a transport receives an incoming message
   304         *
   305         *  When the {@link #traceFlag} is true, all incoming messages
   306         *  are logged. If an individual message's tracing
   307         *  was enabled  via {@link #setMsgTrace}, the receiving of a message is 
   308         *  also logged.
   309         */
   310        config Log.Event LM_rcvByTransport = {
   311            mask: Diags.USER1,
   312            msg: "LM_rcvByTransport: Message 0x%x (seqNum = %d, srcProc = %d) was received"
   313        };
   314        
   315        /*!
   316         *  ======== LM_get ========
   317         *  Logged when a message is received off the queue
   318         *
   319         *  When the {@link #traceFlag} is true, all getting of messages
   320         *  are logged. If an individual message's tracing
   321         *  was enabled  via {@link #setMsgTrace}, the MessageQ_get is 
   322         *  also logged.
   323         */
   324        config Log.Event LM_get = {
   325            mask: Diags.USER1,
   326            msg: "LM_get: Message 0x%x (seqNum = %d, srcProc = %d) was received by queue 0x%x"
   327        };
   328        
   329        /*! MessageQ ID */
   330        typedef UInt32 QueueId;
   331        
   332        /*!
   333         *  ======== SetupTransportProxy ========
   334         *  MessageQ transport setup proxy
   335         */
   336        proxy SetupTransportProxy inherits ti.sdo.ipc.interfaces.ITransportSetup;
   337        
   338        /*!
   339         *  Message priority values. These must match the values defined in
   340         *  ti/ipc/MessageQ.h but are needed here for ROV.
   341         */
   342        const UInt NORMALPRI   = 0;
   343        const UInt HIGHPRI     = 1;
   344        const UInt RESERVEDPRI = 2;
   345        const UInt URGENTPRI   = 3;
   346        
   347        /*!
   348         *  Assert raised when calling API with wrong handle
   349         *
   350         *  Some APIs can only be called with an opened handle (e.g. 
   351         *  {@link #close}. Some can only be called with a created handle
   352         *  (e.g. {@link #get}).
   353         */
   354        config Assert.Id A_invalidContext  = {
   355            msg: "A_invalidContext: Cannot call with an open/create handle"
   356        };
   357                
   358        /*!
   359         *  Assert raised when attempting to free a static message
   360         */
   361        config Assert.Id A_cannotFreeStaticMsg  = {
   362            msg: "A_cannotFreeStaticMsg: Cannot call MessageQ_free with static msg"
   363        };
   364        
   365        /*!
   366         *  Assert raised when an invalid message is supplied
   367         */
   368        config Assert.Id A_invalidMsg  = {
   369            msg: "A_invalidMsg: Invalid message"
   370        };
   371    
   372        /*!
   373         *  Assert raised when an invalid queueId is supplied
   374         */
   375        config Assert.Id A_invalidQueueId  = {
   376            msg: "A_invalidQueueId: Invalid queueId is used"
   377        };
   378    
   379        /*!
   380         *  Assert raised when using an invalid heapId
   381         */
   382        config Assert.Id A_heapIdInvalid  = {
   383            msg: "A_heapIdInvalid: heapId is invalid"
   384        };
   385        
   386        /*!
   387         *  Assert raised when using an invalid procId
   388         */
   389        config Assert.Id A_procIdInvalid  = {
   390            msg: "A_procIdInvalid: procId is invalid"
   391        };
   392        
   393        /*!
   394         *  Assert raised for an invalid MessageQ object 
   395         */
   396        config Assert.Id A_invalidObj  = {
   397            msg: "A_invalidObj: an invalid obj is used"
   398        };
   399    
   400        /*!
   401         *  Assert raised for an invalid parameter 
   402         */
   403        config Assert.Id A_invalidParam  = {
   404            msg: "A_invalidParam: an invalid parameter was passed in"
   405        };
   406    
   407        /*!
   408         *  Assert raised when attempting to send a message to a core
   409         *  where a transport has not been registered.
   410         */
   411        config Assert.Id A_unregisteredTransport  = {
   412            msg: "A_unregisteredTransport: transport is not registered"
   413        };
   414        
   415        /*!
   416         *  Assert raised when attempting to unblock a remote MessageQ or one that
   417         *  has been configured with a non-blocking synchronizer
   418         */
   419        config Assert.Id A_invalidUnblock  = {
   420            msg: "A_invalidUnblock: Trying to unblock a remote MessageQ or a queue with non-blocking synchronizer"
   421        };
   422        
   423        /*!
   424         *  Error raised if all the message queue objects are taken
   425         */
   426        config Error.Id E_maxReached  = {
   427            msg: "E_maxReached: All objects in use. MessageQ.maxRuntimeEntries is %d"
   428        };
   429        
   430        /*!
   431         *  Error raised when heapId has not been registered
   432         */
   433        config Error.Id E_unregisterHeapId  = {
   434            msg: "E_unregisterHeapId: Heap id %d not registered"
   435        };
   436    
   437        /*!
   438         *  Trace setting
   439         *
   440         *  This flag allows the configuration of the default module trace 
   441         *  settings.     
   442         */
   443        config Bool traceFlag = false;    
   444        
   445        /*!
   446         *  Number of heapIds in the system
   447         *
   448         *  This allows MessageQ to pre-allocate the heaps table.
   449         *  The heaps table is used when registering heaps.
   450         *
   451         *  The default is 1. 
   452         *  
   453         *  There is no default heap, so unless the system is only using
   454         *  {@link #staticMsgInit}, the application must register a heap.
   455         */
   456        config UInt16 numHeaps = 1;    
   457        
   458        /*! 
   459         *  Maximum number of MessageQs that can be dynamically created
   460         */
   461        config UInt maxRuntimeEntries = NameServer.ALLOWGROWTH;
   462        
   463        /*! 
   464         *  Gate used to make the name table thread safe
   465         *
   466         *  This gate is used when accessing the name table during 
   467         *  a {@link #create}, {@link #delete}, and {@link #open}.
   468         *
   469         *  This gate is also used to protect MessageQ when growing
   470         *  internal tables in the {@link #create}.
   471         *
   472         *  The table is in local memory, not shared memory. So a
   473         *  single processor gate will work.
   474         *
   475         *  The default will be {@link xdc.runtime.knl.GateThread}
   476         *  instance.
   477         */
   478        config IGateProvider.Handle nameTableGate = null;
   479        
   480        /*! 
   481         *  Maximum length for Message queue names
   482         */
   483        config UInt maxNameLen = 32;
   484    
   485        /*! 
   486         *  Section name is used to place the names table
   487         */
   488        metaonly config String tableSection = null;
   489        
   490        /*!
   491         *  ======== registerHeapMeta ========
   492         *  Statically register a heap with MessageQ
   493         *
   494         *  Build error if heapId is in use.
   495         *
   496         *  @param(heap)        Heap to register
   497         *  @param(heapId)      heapId associated with the heap
   498         */
   499        metaonly Void registerHeapMeta(IHeap.Handle heap, UInt16 heapId);
   500         
   501         /*!
   502         *  ======== registerTransportMeta ========
   503         *  Statically register a transport with MessageQ
   504         *
   505         *  Build error if remote processor already has a transport
   506         *  registered.
   507         *
   508         *  @param(transport)   transport to register
   509         *  @param(procId)      procId that transport communicaties with
   510         *  @param(priority)    priority of transport
   511         */
   512         metaonly Void registerTransportMeta(IMessageQTransport.Handle transport, UInt16 procId, UInt priority);
   513         
   514        /*! @_nodoc
   515         *  ======== attach ========
   516         *  Calls the {@link #SetupProxy} to setup the MessageQ transports.
   517         */
   518        Int attach(UInt16 remoteProcId, Ptr sharedAddr);
   519        
   520        /*! @_nodoc
   521         *  ======== detach ========
   522         *  Calls the {@link #SetupProxy} to detach the MessageQ transports.
   523         */
   524        Int detach(UInt16 remoteProcId);
   525        
   526        /*! @_nodoc
   527         *  ======== sharedMemReq ========
   528         *  Returns the amount of shared memory used by one transport instance.
   529         *
   530         *  The MessageQ module itself does not use any shared memory but the
   531         *  underlying transport may use some shared memory.
   532         */
   533        SizeT sharedMemReq(Ptr sharedAddr);
   534    
   535        /*!
   536         *  ======== registerTransport ========
   537         *  Register a transport with MessageQ
   538         *
   539         *  This API is called by the transport when it is created.
   540         *
   541         *  @param(transport)   transport to register
   542         *  @param(procId)      MultiProc id that transport communicates with
   543         *  @param(priority)    priority of transport
   544         *
   545         *  @b(returns)         Whether the register was successful.
   546         */
   547        Bool registerTransport(IMessageQTransport.Handle transport, UInt16 procId,
   548            UInt priority);
   549    
   550        /*!
   551         *  ======== unregisterTransport ========
   552         *  Unregister a transport with MessageQ
   553         *
   554         *  @param(procId)      unregister transport that communicates with
   555         *                      this remote processor
   556         *  @param(priority)    priority of transport
   557         */
   558        Void unregisterTransport(UInt16 procId, UInt priority);
   559        
   560    instance:
   561      
   562        /*! 
   563         *  ISync handle used to signal IO completion 
   564         *
   565         *  The ISync instance is used in the {@link #get} and {@link #put}.
   566         *  The {@link xdc.runtime.knl.ISync#signal} is called as part
   567         *  of the {@link #put} call.  The {@link xdc.runtime.knl.ISync#wait} is 
   568         *  called in the {@link #get} if there are no messages present.
   569         */
   570        config ISync.Handle synchronizer = null;
   571        
   572        /*! @_nodoc
   573         *  ======== create ========
   574         *  Create a message queue
   575         *
   576         *  @param(name)         Name of the message queue.
   577         */
   578        create(String name);   
   579        
   580    internal:
   581        /* 
   582         *  The following describes the usage of the flag field     
   583         *  ---------------------------------
   584         *  |V V V|T|     reserved      |P P|
   585         *  ---------------------------------
   586         *   E D C B A 0 9 8 7 6 5 4 3 2 1 0
   587         *     
   588         *  V = version
   589         *  P = priority
   590         *  T = trace flag
   591         */
   592    
   593        /*! Mask to extract version setting */
   594        const UInt VERSIONMASK = 0xE000;
   595        
   596        /*! Version setting */
   597        const UInt HEADERVERSION = 0x2000;
   598        
   599        /*! Mask to extract Trace setting */
   600        const UInt TRACEMASK = 0x1000;
   601        
   602        /*! Shift for Trace setting */
   603        const UInt TRACESHIFT = 12;
   604           
   605        /*!
   606         *  Mask to extract priority setting.
   607         *  This is needed here for ROV but must match
   608         *  the value defined in ti/ipc/MessageQ.h
   609         */
   610        const UInt PRIORITYMASK = 0x3;
   611        
   612        /*! Mask to extract priority setting */
   613        const UInt TRANSPORTPRIORITYMASK = 0x1;
   614            
   615         /*! return code for Instance_init */
   616        const Int PROXY_FAILURE = 1;
   617    
   618        /* 
   619         *  Used to denote a message that was initialized 
   620         *  with the MessageQ_staticMsgInit function.
   621         */
   622        const UInt16 STATICMSG = 0xFFFF;
   623    
   624        /*! Required first field in every message */
   625        @Opaque struct MsgHeader {
   626            Bits32       reserved0;         /* reserved for List.elem->next */
   627            Bits32       reserved1;         /* reserved for List.elem->prev */
   628            Bits32       msgSize;           /* message size                 */
   629            Bits16       flags;             /* bitmask of different flags   */
   630            Bits16       msgId;             /* message id                   */
   631            Bits16       dstId;             /* destination processor id     */
   632            Bits16       dstProc;           /* destination processor        */
   633            Bits16       replyId;           /* reply id                     */
   634            Bits16       replyProc;         /* reply processor              */
   635            Bits16       srcProc;           /* source processor             */
   636            Bits16       heapId;            /* heap id                      */
   637            Bits16       seqNum;            /* sequence number              */
   638            Bits16       reserved;          /* reserved                     */
   639        };
   640        
   641        struct HeapEntry {
   642            IHeap.Handle  heap;
   643            UInt16        heapId;
   644        };
   645        
   646        struct TransportEntry {
   647            IMessageQTransport.Handle  transport;
   648            UInt16             procId;
   649        };
   650        
   651        /*! 
   652         *  ======== nameSrvPrms ========
   653         *  This Params object is used for temporary storage of the
   654         *  module wide parameters that are for setting the NameServer instance.
   655         */
   656        metaonly config NameServer.Params nameSrvPrms;
   657        
   658        /*! 
   659         *  Statically registered heaps
   660         *
   661         *  This configuration parameter allows the static registeration
   662         *  of heaps. The index of the array corresponds to the heapId.     
   663         */
   664        metaonly config HeapEntry staticHeaps[];
   665        
   666        /*! 
   667         *  Statically registered transports
   668         *
   669         *  This configuration parameter allows the static registeration
   670         *  of transports. The index of the array corresponds to the procId.     
   671         */
   672        metaonly config TransportEntry staticTransports[];
   673        
   674        /*!
   675         *  Allows for the number of dynamically created message queues to grow.
   676         */
   677        UInt16 grow(Object *obj, Error.Block *eb);
   678      
   679        struct Instance_State {
   680            QueueId         queue;        /* Unique id                 */
   681            ISync.Handle    synchronizer; /* completion synchronizer   */
   682            List.Object     normalList;   /* Embedded List objects     */
   683            List.Object     highList;     /* Embedded List objects     */
   684            Ptr             nsKey;
   685            SyncSem.Handle  syncSemHandle; /* for use in finalize      */
   686            Bool            unblocked;    /* Whether MessageQ is unblocked */
   687        };
   688      
   689        struct Module_State {        
   690            IMessageQTransport.Handle transports[][2];
   691            Handle               queues[];        
   692            IHeap.Handle         heaps[];        
   693            IGateProvider.Handle gate;
   694            UInt16               numQueues;
   695            UInt16               numHeaps;        
   696            NameServer.Handle    nameServer;
   697            Bool                 canFreeQueues;
   698            UInt16               seqNum;
   699    
   700        };
   701    }