Cleanup, removed unused local array: sharedCreateId
[ipc/ipcdev.git] / packages / ti / sdo / ipc / MessageQ.xs
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.xs ========
34  *
35  */
37 var MultiProc  = null;
38 var NameServer = null;
39 var MessageQ   = null;
40 var GateThread = null;
41 var Settings   = null;
42 var SyncSem    = null;
44 var instCount = 0;  /* use to determine if processing last instance */
46 /*
47  *  ======== module$meta$init ========
48  */
49 function module$meta$init(name)
50 {
51     /* Only process during "cfg" phase */
52     if (xdc.om.$name != "cfg") {
53         return;
54     }
55 }
57 /*
58  *  ======== module$use ========
59  */
60 function module$use()
61 {
62     MessageQ   = this;
63     Settings   = xdc.useModule('ti.sdo.ipc.family.Settings');
64     List       = xdc.useModule("ti.sdo.utils.List");
65     MultiProc  = xdc.useModule("ti.sdo.utils.MultiProc");
66     NameServer = xdc.useModule('ti.sdo.utils.NameServer');
67     GateThread = xdc.useModule("xdc.runtime.knl.GateThread");
68     SyncSem    = xdc.useModule("ti.sysbios.syncs.SyncSem");
70     /* Plug the SetupTransportProxy for the MessageQ transport */
71     if (MessageQ.SetupTransportProxy == null) {
72         try {
73             MessageQ.SetupTransportProxy =
74                 xdc.useModule(Settings.getMessageQSetupDelegate());
75         }
76         catch (e) {
77             /* Plug in the generic shared memory transport */
78             MessageQ.SetupTransportProxy =
79                 xdc.useModule('ti.sdo.ipc.transports.TransportShmSetup');
80         }
81     }
82 }
84 /*
85  *  ======== module$static$init ========
86  *  Initialize module values.
87  */
88 function module$static$init(mod, params)
89 {
90     /* initialize the NameServer param to be used now or later */
91     MessageQ.nameSrvPrms.maxRuntimeEntries = params.maxRuntimeEntries;
92     MessageQ.nameSrvPrms.tableSection      = params.tableSection;
93     MessageQ.nameSrvPrms.maxNameLen        = params.maxNameLen;
95     /*
96      *  Get the current number of created static instances of this module.
97      *  Note: if user creates a static instance after this point and
98      *        expects to use NameServer, this is a problem.
99      */
100      var instCount = this.$instances.length;
102     /* create NameServer here only if no static instances are created */
103     if (instCount == 0) {
104         mod.nameServer = NameServer.create("MessageQ",
105                                            MessageQ.nameSrvPrms);
106     }
107     else {
108         mod.nameServer = null;
109     }
111     /*
112      *  If no growth allowed, pre-allocate the max length
113      *  Also pre-allocate if numReservedEntries is not zero.
114      *  maxRuntimeEntries < numReservedEntries is caught in validate.
115      */
116     mod.numQueues = this.$instances.length;
117     if (params.maxRuntimeEntries != NameServer.ALLOWGROWTH) {
118         mod.numQueues += params.maxRuntimeEntries;
119     }
120     else if (params.numReservedEntries != 0){
121         mod.numQueues += params.numReservedEntries;
122     }
124     mod.queues.length = mod.numQueues;
125     mod.canFreeQueues = false;
126     mod.freeHookFxn   = params.freeHookFxn;
128     if (params.nameTableGate == null) {
129          mod.gate = null;
130     }
131     else {
132         mod.gate = params.nameTableGate;
133     }
135     var messsageQParams = new this.Params;
137     /* Initial the seqNum used for tracing */
138     mod.seqNum     = 0;
140     /* Set the length of the heaps array */
141     mod.numHeaps     = params.numHeaps;
142     mod.heaps.length = mod.numHeaps;
144     /* Initialize the heaps array to null */
145     for (var i = 0; i < mod.heaps.length; i++) {
146             mod.heaps[i] = null;
147     }
149     /*
150      *  Sort the static heaps by heap id into the heaps array
151      */
152     for (var i = 0; i < params.staticHeaps.length; i++) {
154         /* Make sure the id is not too big */
155         if (params.staticHeaps[i].heapId >= mod.numHeaps) {
156             MessageQ.$logError("Out of range heapId (" +
157                                 params.staticHeaps[i].heapId +
158                                 "). Max heapId is " + (params.numHeaps - 1) +
159                                 " (MessageQ.numHeaps - 1).", this);
160         }
162         /* Make sure the same id is not used twice */
163         if (mod.heaps[params.staticHeaps[i].heapId] != null) {
164             MessageQ.$logError("Cannot register multiple heaps to heapId " +
165                                 params.staticHeaps[i].heapId + ".", this);
166         }
168         mod.heaps[params.staticHeaps[i].heapId] = params.staticHeaps[i].heap;
169     }
171     /* Set the length of the transport array */
172     mod.transports.length = MultiProc.numProcessors;
174     /* Initialize all the transports to null */
175     for (var i = 0; i < mod.transports.length; i++) {
176         mod.transports[i][0] = null;
177         mod.transports[i][1] = null;
178     }
180     /*
181      *  Sort the static Transports by processor id into the
182      *  transport array
183      */
184     for (var i = 0; i < params.staticTransports.length; i++) {
186         /* Make sure the procId is not too big */
187         if (params.staticTransports[i].procId >= MultiProc.numProcessors) {
188             MessageQ.$logError("MessageQ Out of range procId (" +
189                                 params.staticTransports[i].procId +
190                                 "). Max procId is " +
191                                 (MultiProc.numProcessors) +
192                                 " (MultiProc.numProcessors).", this);
193         }
195         /* Make sure the same id is not used twice */
196         if (mod.transports[params.staticTransports[i].procId] != null) {
197             MessageQ.$logError("Cannot register multiple transports to one" +
198                                " remote processor " +
199                                params.staticTransports[i].procId + ".", this);
200         }
202         mod.transports[params.staticTransports[i].procId] =
203             params.staticTransports[i].transport;
204     }
207 /*
208  *  ======== registerHeapMeta ========
209  */
210 function registerHeapMeta(heap, heapId)
212     var entry = new this.HeapEntry();
213     entry.heap = heap;
214     entry.heapId = heapId;
215     this.staticHeaps.$add(entry);
218 /*
219  *  ======== registerTransportMeta ========
220  */
221 function registerTransportMeta(transport, procId, priority)
223     var entry = new this.transportEntry();
224     entry.transport = transport;
225     entry.procId    = procId;
226     this.staticTransports.$add(entry);
229 /*
230  *  ======== viewInitQueues ========
231  */
232 function viewInitQueues(view, obj)
234     var Program         = xdc.useModule('xdc.rov.Program');
235     var NameServer      = xdc.useModule('ti.sdo.utils.NameServer');
236     var SharedRegion    = xdc.useModule('ti.sdo.ipc.SharedRegion');
238     /* view.name */
239     try {
240         view.name = NameServer.getName$view("MessageQ", obj.queue);
241     }
242     catch(e) {
243         Program.displayError(view, "name",
244             "Error retrieving name from NameServer: " + e);
245     }
247     /* view.queueId */
248     view.queueId = obj.queue & 0xffff;
252 /*
253  *  ======== viewInitMessages ========
254  */
255 function viewInitMessages(view, obj)
257     var Program = xdc.useModule('xdc.rov.Program');
258     var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
259     var NameServer = xdc.useModule('ti.sdo.utils.NameServer');
261     print("viewInitMessages called");
263     /* view.label */
264     try {
265         view.label = NameServer.getName$view("MessageQ", obj.queue);
266     }
267     catch(e) {
268         Program.displayError(view, "label",
269             "Error retrieving name from NameServer: " + e);
270         return;
271     }
273     /* Retrieve the ROV view for the embedded high priority message list. */
274     addMsgsFromList(view, obj.highList);
276     /* Retrieve the ROV view for the embedded normal priority message list. */
277     addMsgsFromList(view, obj.normalList);
280 /*
281  *  ======== addMsgsFromList ========
282  *  Scans the provided list object and adds the messages on it to the view.
283  */
284 function addMsgsFromList(view, list)
286     var Program = xdc.useModule('xdc.rov.Program');
288     print("Calling addMsgsFromList");
290     /* Scan the list to retrieve the addresses of the messages. */
291     try {
292         var listView = Program.scanObjectView("ti.sdo.utils.List", list,
293             "Basic");
294     }
295     /* If there was a problem scanning the list, report it. */
296     catch (e) {
297         var msgView = Program.newViewStruct('ti.sdo.ipc.MessageQ', 'Messages');
298         /*
299          * If there was a problem, report it using the first field, and
300          * return.
301          */
302         Program.displayError(msgView, 'seqNum', String(e));
303         view.elements.$add(msgView);
304         return;
305     }
307     try {
308         /* Fetch each of the message headers on the list. */
309         for each (var addr in listView.elems) {
310             print("Trying to call getMsgView for 0x" + Number(addr).toString(16));
311             var msgView = getMsgView(Number(addr));
313             view.elements.$add(msgView);
314         }
315     }
316     catch (e) {
317         /*
318          * If there were any problems retrieving the view, add an element
319          * to report the error.
320          */
321         var msgView = Program.newViewStruct('ti.sdo.ipc.MessageQ', 'Messages');
322         Program.displayError(msgView, 'seqNum', String(e));
323         view.elements.$add(msgView);
324     }
327 /*
328  *  ======== getMsgView ========
329  *  Returns a view structure representing the message at the given address.
330  */
331 function getMsgView(addr)
333     var Program = xdc.useModule('xdc.rov.Program');
334     var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
336     print("getting message view: 0x" + Number(addr).toString(16));
338     /* Create a new message view to populate. */
339     var msgView = Program.newViewStruct('ti.sdo.ipc.MessageQ', 'Messages');
341     /* Fetch the message header from the given address. */
342     try {
343         var msgHeader = Program.fetchStruct(MessageQ.MsgHeader$fetchDesc,
344                                             Number(addr));
345     }
346     catch (e) {
347         /*
348          * If there was a problem, report it using the first field, and
349          * return the view.
350          */
351         Program.displayError(msgView, 'seqNum', String(e));
352         return (msgView);
353     }
355     /* Display the messages sequence number and size. */
356     msgView.seqNum = msgHeader.seqNum;
357     msgView.msgSize = msgHeader.msgSize;
359     /* The flags field contains the message priority. */
360     var priority = msgHeader.flags & MessageQ.PRIORITYMASK;
361     getPriority(msgView, priority);
363     /* The flags field also contains the trace enabled bit. */
364     msgView.traceEnabled = msgHeader.flags & MessageQ.TRACEMASK;
366     /* The flags field also contains the version bits. */
367     msgView.version = (msgHeader.flags & MessageQ.VERSIONMASK) >> 13;
369     /* Display the message ID set by the user. */
370     msgView.msgId = msgHeader.msgId;
372     /*
373      * Scan in the MultiProc view so we have the mapping from processor id
374      * to processor name.
375      */
376     try {
377         var multiProcView = Program.scanModuleView('ti.sdo.utils.MultiProc',
378                                                    'Module');
379     }
380     catch (e) {
381         /*
382          * If there was a problem scanning the MultiProc view, display the
383          * error, but keep processing anyway.
384          */
385         Program.displayError(msgView, 'srcProc', String(e));
386     }
388     /* Lookup the names of the destination, reply, and source processors. */
389     msgView.srcProc = multiProcView.nameList[msgHeader.srcProc];
391     /* If a reply queue hasn't been specified, display "N/A" */
392     if (msgHeader.replyId == 0xFFFF) {
393         msgView.replyProc = "N/A";
394         msgView.replyId = "N/A";
395     }
396     /* Otherwise display the reply queue. */
397     else {
398         msgView.replyProc = multiProcView.nameList[msgHeader.replyProc];
399         // TODO - Should this display the name of the MessageQ?
400         msgView.replyId = String(msgHeader.replyId);
401     }
403     /* Display the heap that the message was allocated from. */
404     msgView.heap = getHeapNameFromId(msgHeader.heapId);
406     return (msgView);
409 /*
410  *  ======== getPriority ========
411  *  Fills in the message views 'priority' field given the priority value.
412  */
413 function getPriority(msgView, priority)
415     var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
416     var Program = xdc.useModule('xdc.rov.Program');
418     switch (priority) {
419         case MessageQ.NORMALPRI:
420             msgView.priority = "(" + MessageQ.NORMALPRI + ") Normal";
421             break;
422         case MessageQ.HIGHPRI:
423             msgView.priority = "(" + MessageQ.HIGHPRI + ") High";
424             break;
425         case MessageQ.RESERVEDPRI:
426             msgView.priority = "(" + MessageQ.RESERVEDPRI + ") Reserved";
427             break;
428         case MessageQ.URGENTPRI:
429             msgView.priority = "(" + MessageQ.URGENTPRI + ") Urgent";
430             break;
431         default:
432             Program.displayError(msgView, 'priority',
433                                  'Message has invalid priority: ' + priority);
434     }
437 /*
438  *  ======== getHeapNameFromId ========
439  *  This function takes the heap Id from a message (the heap ids are assigned
440  *  by MessageQ) and retrieves a name for the heap.
441  */
442 function getHeapNameFromId(heapId)
444     var Program = xdc.useModule('xdc.rov.Program');
446     /* The module state contains the list of heaps. */
447     var modView = Program.scanModuleView('ti.sdo.ipc.MessageQ', 'Module');
449     /* Get the string representation of the address. */
450     if ((heapId == -1) || (heapId == 65535)) {
451         var heapAddr = "[static]";
452     }
453     else {
454         var heapAddr = String(modView.heaps[heapId]);
455     }
457     return (heapId + " (" + heapAddr + ")");
460 /*
461  *  ======== viewInitModule ========
462  */
463 function viewInitModule(view, mod)
465     var Program = xdc.useModule('xdc.rov.Program');
467     /* Scan in the array of heaps. */
468     try {
469         view.heaps = Program.fetchArray(mod.heaps$fetchDesc, mod.heaps,
470                                           mod.numHeaps);
471     }
472     catch (e) {
473         Program.displayError(view, 'heaps', "Problem retrieving array of " +
474                              "heaps: " + e);
475     }
477     /* Display the handle to the module's gate. */
478     view.gate = mod.gate;
480     /*
481      * Display the module's sequence number, which is the next value
482      * that will be used.
483      */
484     view.nextSeqNum = mod.seqNum;
486     /* Display the freeHookFxn if there is one. */
487     if (Number(mod.freeHookFxn) != 0 ) {
488         view.freeHookFxn = Program.lookupFuncName(Number(mod.freeHookFxn));
489     }
492 function module$validate()
494     if ((MessageQ.maxRuntimeEntries != NameServer.ALLOWGROWTH) &&
495         (MessageQ.maxRuntimeEntries < MessageQ.numReservedEntries)) {
496         MessageQ.$logFatal(
497             "If MessageQ.maxRuntimeEntries is not NameServer.ALLOWGROWTH, " +
498             "it cannot be less than MessageQ.numReservedEntries.",
499             MessageQ);
500     }