97303bc0e6526b818a7590279bc05f3716f92820
[ipc/ipcdev.git] / packages / ti / sdo / utils / NameServer.c
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  * */
32 /*
33  *  ======== NameServer.c ========
34  *  Implementation of functions specified in NameServer.xdc.
35  */
37  /*
38  *  The dynamic name/value table looks like the following. This approach allows
39  *  each instance table to have different value and different name lengths.
40  *  The names block is allocated on the create. The size of that block is
41  *  (maxRuntimeEntries * maxNameLen). That block is sliced and diced up and
42  *  given to each table entry.
43  *  The same thing is done for the values block.
44  *
45  *     names                    table                  values
46  *   -------------           -------------          -------------
47  *   |           |<-\        |   elem    |   /----->|           |
48  *   |           |   \-------|   name    |  /       |           |
49  *   |           |           |   value   |-/        |           |
50  *   |           |           |   len     |          |           |
51  *   |           |<-\        |-----------|          |           |
52  *   |           |   \       |   elem    |          |           |
53  *   |           |    \------|   name    |  /------>|           |
54  *   |           |           |   value   |-/        |           |
55  *   -------------           |   len     |          |           |
56  *                           -------------          |           |
57  *                                                  |           |
58  *                                                  |           |
59  *                                                  -------------
60  *
61  *  There is an optimization for small values (e.g. <= sizeof(UInt32).
62  *  In this case, there is no values block allocated. Instead the value
63  *  field is used directly.  This optimization occurs and is managed when
64  *  obj->maxValueLen <= sizeof(UInt32).
65  *
66  *  The static create is a little different. The static entries point directly
67  *  to a name string (and value). Since it points directly to static items,
68  *  this entries cannot be removed.
69  *  If maxRuntimeEntries is non-zero, a names and values block is created.
70  *  Here is an example of a table with 1 static entry and 2 dynamic entries
71  *
72  *                           -------------
73  *                           |   elem    |
74  *      "myName" <-----------|   name    |----------> someValue
75  *                           |   value   |
76  *     names                 |   len     |              values
77  *   -------------           -------------          -------------
78  *   |           |<-\        |   elem    |   /----->|           |
79  *   |           |   \-------|   name    |  /       |           |
80  *   |           |           |   value   |-/        |           |
81  *   |           |           |   len     |          |           |
82  *   |           |<-\        |-----------|          |           |
83  *   |           |   \       |   elem    |          |           |
84  *   |           |    \------|   name    |  /------>|           |
85  *   |           |           |   value   |-/        |           |
86  *   -------------           |   len     |          |           |
87  *                           -------------          |           |
88  *                                                  |           |
89  *                                                  |           |
90  *                                                  -------------
91  *
92  *  NameServer uses a freeList and nameList to maintain the empty
93  *  and filled-in entries. So when a name/value pair is added, an entry
94  *  is pulled off the freeList, filled-in and placed on the nameList.
95  *  The reverse happens on a remove.
96  *
97  *  For static adds, the entries are placed on the nameList statically.
98  *
99  *  For dynamic creates, the freeList is populated in postInit and there are no
100  *  entries placed on the nameList (this happens when the add is called).
101  */
103 /* below #define to eliminate strncpy depracation warning for win targets */
104 #define _CRT_SECURE_NO_DEPRECATE
106 #include <xdc/std.h>
107 #include <string.h>
108 #include <stdlib.h>
110 #include <xdc/runtime/Assert.h>
111 #include <xdc/runtime/System.h>
112 #include <xdc/runtime/Error.h>
113 #include <xdc/runtime/Memory.h>
114 #include <xdc/runtime/Startup.h>
116 #include <ti/sysbios/gates/GateSwi.h>
117 #include <ti/sysbios/hal/Hwi.h>
119 #include <ti/sdo/utils/List.h>
120 #include <ti/sdo/utils/INameServerRemote.h>
122 #include <ti/sdo/utils/_MultiProc.h>
123 #include <ti/sdo/utils/_NameServer.h>
125 #include "package/internal/NameServer.xdc.h"
127 #ifdef __ti__
128     #pragma FUNC_EXT_CALLED(NameServer_Params_init);
129     #pragma FUNC_EXT_CALLED(NameServer_add);
130     #pragma FUNC_EXT_CALLED(NameServer_addUInt32);
131     #pragma FUNC_EXT_CALLED(NameServer_create);
132     #pragma FUNC_EXT_CALLED(NameServer_delete);
133     #pragma FUNC_EXT_CALLED(NameServer_get);
134     #pragma FUNC_EXT_CALLED(NameServer_getHandle);
135     #pragma FUNC_EXT_CALLED(NameServer_getLocal);
136     #pragma FUNC_EXT_CALLED(NameServer_getLocalUInt32);
137     #pragma FUNC_EXT_CALLED(NameServer_getUInt32);
138     #pragma FUNC_EXT_CALLED(NameServer_match);
139     #pragma FUNC_EXT_CALLED(NameServer_remove);
140     #pragma FUNC_EXT_CALLED(NameServer_removeEntry);
141 #endif
143 /*
144  *************************************************************************
145  *                       Common Header Functions
146  *************************************************************************
147  */
149 /*
150  *  ======== NameServer_Params_init ========
151  */
152 Void NameServer_Params_init(NameServer_Params *params)
154     /* init the params to the defaults */
155     params->maxRuntimeEntries = NameServer_ALLOWGROWTH;
156     params->tableHeap         = NULL;
157     params->checkExisting     = TRUE;
158     params->maxValueLen       = 0;
159     params->maxNameLen        = NameServer_Params_MAXNAMELEN;
162 /*
163  *  ======== NameServer_add ========
164  *  Grab a free entry and fill it up.
165  */
166 Ptr NameServer_add(NameServer_Handle handle, String name, Ptr value,
167                    UInt32 len)
169     ti_sdo_utils_NameServer_Object *obj =
170             (ti_sdo_utils_NameServer_Object *)handle;
171     IArg key;
172     ti_sdo_utils_NameServer_TableEntry *tableEntry;
173     Error_Block eb;
174     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
175     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
177     /* Make sure the name and value can be copied into the table */
178     Assert_isTrue((len <= obj->maxValueLen),
179             ti_sdo_utils_NameServer_A_invalidLen);
180     Assert_isTrue((strlen(name) < obj->maxNameLen),
181             ti_sdo_utils_NameServer_A_invalidLen);
183     Error_init(&eb);
185     /* Only check if configured to check */
186     if (obj->checkExisting == TRUE ) {
187         key = GateSwi_enter(NameServer_module->gate);
188         if (NameServer_findLocal(obj, name) != NULL) {
189             GateSwi_leave(NameServer_module->gate, key);
190             Error_raise(&eb, ti_sdo_utils_NameServer_E_entryExists, name, 0);
191             return (NULL);
192         }
193         GateSwi_leave(NameServer_module->gate, key);
194     }
196     /* Get a free entry */
197     tableEntry = List_get(freeList);
199     /* If no entry, see if numDynamic is set to allow growth or raise error */
200     if (tableEntry == NULL) {
201         if (obj->numDynamic == NameServer_ALLOWGROWTH) {
203             tableEntry = Memory_alloc(obj->tableHeap,
204                 sizeof(ti_sdo_utils_NameServer_TableEntry), 0, &eb);
205             if (tableEntry == NULL) {
206                 return (NULL);
207             }
209             tableEntry->name = Memory_alloc(obj->tableHeap,
210                     strlen(name) + 1, 0, &eb);
211             if (tableEntry->name == NULL) {
212                 Memory_free(obj->tableHeap, tableEntry,
213                             sizeof(ti_sdo_utils_NameServer_TableEntry));
214                 return (NULL);
215             }
217             if (!(obj->maxValueLen == sizeof(UInt32))) {
219                 tableEntry->value = (UArg)Memory_alloc(obj->tableHeap,
220                         obj->maxValueLen, 0, &eb);
221                 if (tableEntry->value == 0) {
222                     Memory_free(obj->tableHeap, tableEntry,
223                             sizeof(ti_sdo_utils_NameServer_TableEntry));
224                     Memory_free(obj->tableHeap, tableEntry->name,
225                             strlen(name) + 1);
226                     return (NULL);
227                 }
228             }
229         }
230         else {
231             Error_raise(&eb, ti_sdo_utils_NameServer_E_maxReached,
232                     obj->numDynamic, 0);
233             return (NULL);
234         }
235     }
237     /*
238      *  Fill in the value.
239      *  If the maxValueLen is sizeof(UInt32), simply copy
240      *  the value into the value field.
241      */
242     if (obj->maxValueLen == sizeof(UInt32)) {
243         tableEntry->value = *((UInt32 *)value);
244         tableEntry->len = sizeof(UInt32);
245     }
246     else {
247         memcpy((Ptr)(tableEntry->value), (Ptr)value, len);
248         tableEntry->len = len;
249     }
251     /* Copy the name. Note the table holds the '\0' also */
252     strncpy(tableEntry->name, name, strlen(name) + 1);
254     /* Add to the nameList */
255     List_put(nameList, (List_Elem *)tableEntry);
257     return (tableEntry);
260 /*
261  *  ======== NameServer_addUInt32 ========
262  *  Defer to the add.
263  */
264 Ptr NameServer_addUInt32(NameServer_Handle handle, String name, UInt32 value)
266     return (NameServer_add(handle, name, &value, sizeof(UInt32)));
269 /*
270  *  ======== NameServer_create ========
271  */
272 NameServer_Handle NameServer_create(String name, const NameServer_Params *params)
274     ti_sdo_utils_NameServer_Params nsParams;
275     ti_sdo_utils_NameServer_Object *obj;
276     Error_Block eb;
277     NameServer_Handle handle = NULL;
279     Error_init(&eb);
281     /* check if the name is already created or not */
282     handle = NameServer_getHandle(name);
283     if (handle != NULL) {
284         obj = (ti_sdo_utils_NameServer_Object *)handle;
285         if ((obj->numDynamic == params->maxRuntimeEntries) &&
286             (obj->tableHeap == params->tableHeap) &&
287             (obj->checkExisting == params->checkExisting) &&
288             (obj->maxValueLen == params->maxValueLen) &&
289             (obj->maxNameLen == params->maxNameLen)) {
290             obj->refCount++;
291         }
292         else {
293             Error_raise(&eb, ti_sdo_utils_NameServer_E_paramMismatch, name, 0);
294             handle = NULL;
295         }
296     }
297     else {
298         if (params != NULL) {
299             /* init the module params struct */
300             ti_sdo_utils_NameServer_Params_init(&nsParams);
301             nsParams.maxRuntimeEntries = params->maxRuntimeEntries;
302             nsParams.tableHeap         = params->tableHeap;
303             nsParams.checkExisting     = params->checkExisting;
304             nsParams.maxValueLen       = params->maxValueLen;
305             nsParams.maxNameLen        = params->maxNameLen;
307             /* call the module create */
308             obj = ti_sdo_utils_NameServer_create(name, &nsParams, &eb);
309         }
310         else {
311             /* passing in NULL uses the default params */
312             obj = ti_sdo_utils_NameServer_create(name, NULL, &eb);
313         }
314     }
316     return ((NameServer_Handle)obj);
319 /*
320  *  ======== NameServer_delete ========
321  */
322 Int NameServer_delete(NameServer_Handle *handlePtr)
324     ti_sdo_utils_NameServer_Object * obj =
325         (ti_sdo_utils_NameServer_Object *)*handlePtr;
327     obj->refCount--;
328     if (obj->refCount == 0) {
329         ti_sdo_utils_NameServer_delete(
330             (ti_sdo_utils_NameServer_Handle *)handlePtr);
331     }
333     return (NameServer_S_SUCCESS);
336 /*
337  *  ======== NameServer_get ========
338  *  Currently not using ISync in RemoteProxy call. This is for async support.
339  */
340 Int NameServer_get(NameServer_Handle handle, String name, Ptr value,
341                    UInt32 *len, UInt16 procId[])
343     ti_sdo_utils_NameServer_Object *obj =
344             (ti_sdo_utils_NameServer_Object *)handle;
345     Int i;
346     Int status = NameServer_E_FAIL;
347     Error_Block eb;
348     UInt16 baseId;
349     UInt16 length;
350     UInt16 index;
352     Error_init(&eb);
354     /* processor address mode determines cluster baseId */
355     switch (ti_sdo_utils_MultiProc_procAddrMode) {
356         case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
357             baseId = 0;
358             break;
360         case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
361             baseId = MultiProc_getBaseIdOfCluster();
362             break;
364         default:
365             Assert_isTrue(FALSE, NULL);
366             break;
367     }
369     /*
370      *  Query all the processors.
371      */
372     if (procId == NULL) {
373         /* Query the local one first */
374         status = NameServer_getLocal(handle, name, value, len);
375         if (status == NameServer_E_NOTFOUND) {
376             /* To eliminate code if possible */
377             if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
378                 length = (UInt16)NameServer_module->nsRemoteHandle.length;
380                 for (i = 0; i < length; i++) {
381                     /* skip myself, local table already searched above */
382                     if ((baseId + i) == MultiProc_self()) {
383                         continue;
384                     }
385                     if (NameServer_module->nsRemoteHandle.elem[i] != NULL) {
386                         status = INameServerRemote_get(
387                                 NameServer_module->nsRemoteHandle.elem[i],
388                                 obj->name, name, value, len, NULL, &eb);
389                     }
390                     /* stop looking if found or encoutered fatal error */
391                     if ((status >= 0) || ((status != NameServer_E_NOTFOUND)
392                             && (status != NameServer_E_TIMEOUT))) {
393                         break;
394                     }
395                 }
396             }
397         }
398     }
399     else {
400         /*  Search the query list. It might contain the local proc
401          *  somewhere in the list.
402          */
403         status = NameServer_E_NOTFOUND;
405         for (i = 0; procId[i] != MultiProc_INVALIDID; i++) {
406             if (procId[i] == MultiProc_self()) {
407                 /* check local */
408                 status = NameServer_getLocal(handle, name, value, len);
409             }
410             else if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
411                 index = procId[i] - baseId;
412                 /* check remote */
413                 if (NameServer_module->nsRemoteHandle.elem[index] != NULL) {
414                     status = INameServerRemote_get(
415                             NameServer_module->nsRemoteHandle.elem[index],
416                             obj->name, name, value, len, NULL, &eb);
417                 }
418             }
419             /* stop looking if found or encoutered fatal error */
420             if ((status >= 0) || ((status != NameServer_E_NOTFOUND)
421                     && (status != NameServer_E_TIMEOUT))) {
422                 break;
423             }
424         }
425     }
427     return (status);
430 /*
431  *  ======== NameServer_getHandle ========
432  *  Helper function to get a handle based on the instance name.
433  */
434 NameServer_Handle NameServer_getHandle(String instanceName)
436     ti_sdo_utils_NameServer_Object *obj;
437     IArg key;
438     Int i;
440     /* Search static instances */
441     for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
442         obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
443         if ((obj->name != NULL) &&
444             (strcmp(obj->name, instanceName) == 0)) {
445             return ((NameServer_Handle)obj);
446         }
447     }
449     /* Search dynamic instances (in a thread safe manner) */
450     key = GateSwi_enter(NameServer_module->gate);
452     obj = ti_sdo_utils_NameServer_Object_first();
453     while (obj != NULL) {
454         if ((obj->name != NULL) &&
455             (strcmp(obj->name, instanceName) == 0)) {
456             GateSwi_leave(NameServer_module->gate, key);
457             return ((NameServer_Handle)obj);
458         }
459         obj = ti_sdo_utils_NameServer_Object_next(obj);
460     }
461     GateSwi_leave(NameServer_module->gate, key);
463     return (NULL);
466 /*
467  *  ======== NameServer_getLocal ========
468  */
469 Int NameServer_getLocal(NameServer_Handle handle, String name, Ptr value,
470                         UInt32 *len)
472     ti_sdo_utils_NameServer_Object *obj =
473             (ti_sdo_utils_NameServer_Object *)handle;
474     IArg key;
475     ti_sdo_utils_NameServer_TableEntry *tableEntry;
477     key = GateSwi_enter(NameServer_module->gate);
479     /* search the local table */
480     tableEntry = NameServer_findLocal(obj, name);
482     if (tableEntry != NULL) {
483         /*
484          *  Found the entry.
485          *  If the table holds value (and not buffers) simply
486          *  copy into value and return
487          */
488         if (obj->maxValueLen == sizeof(UInt32)) {
489             memcpy((Ptr)value, &(tableEntry->value), sizeof(UInt32));
490         }
491         else {
492             Assert_isTrue((tableEntry->len <= *len), ti_sdo_utils_NameServer_A_invalidLen);
493             memcpy((Ptr)value, (Ptr)(tableEntry->value), tableEntry->len);
494         }
495         GateSwi_leave(NameServer_module->gate, key);
496         *len = tableEntry->len;
497         return (NameServer_S_SUCCESS);
498     }
500     GateSwi_leave(NameServer_module->gate, key);
502     /* Name not found locally. */
503     return (NameServer_E_NOTFOUND);
506 /*
507  *  ======== NameServer_getLocalUInt32 ========
508  *
509  */
510 Int NameServer_getLocalUInt32(NameServer_Handle handle, String name, Ptr value)
512     UInt32 len = sizeof(UInt32);
513     Int status;
515     status = NameServer_getLocal(handle, name, value, &len);
517     return (status);
520 /*
521  *  ======== NameServer_getUInt32 ========
522  */
523 Int NameServer_getUInt32(NameServer_Handle handle, String name,
524                          Ptr value, UInt16 remoteProcId[])
526     UInt32 len = sizeof(UInt32);
527     Int status;
529     status = NameServer_get(handle, name, value, &len, remoteProcId);
531     return (status);
534 /*  ======== NameServer_match ========
535  *  Currently only supporting 32-bit values.
536  */
537 Int NameServer_match(NameServer_Handle handle, String name, UInt32 *value)
539     ti_sdo_utils_NameServer_Object *obj =
540             (ti_sdo_utils_NameServer_Object *)handle;
541     Int len = 0;
542     Int foundLen = 0;
543     IArg key;
544     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
545     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
547     Assert_isTrue((sizeof(UInt32) == obj->maxValueLen),
548             ti_sdo_utils_NameServer_A_invalidLen);
550     key = GateSwi_enter(NameServer_module->gate);
552     /* Search the entire table and find the longest match */
553     while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
555         len = strlen(tableEntry->name);
557         /*
558          *  Only check if the name in the table is going to potentially be
559          *  a better match.
560          */
561         if (len > foundLen) {
562             if (strncmp(name, tableEntry->name, len) == 0) {
563                 *value = (UInt32)(tableEntry->value);
564                 foundLen = len;
565             }
566         }
567     }
569     GateSwi_leave(NameServer_module->gate, key);
571     /* The name was not found...return 0 characters matched*/
572     return (foundLen);
575 /*
576  *  ======== NameServer_remove ========
577  *  Remove a name/value pair.
578  */
579 Int NameServer_remove(NameServer_Handle handle, String name)
581     ti_sdo_utils_NameServer_Object *obj =
582             (ti_sdo_utils_NameServer_Object *)handle;
583     UInt i;
584     IArg key;
585     Int status = NameServer_E_INVALIDARG;
586     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
587     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
589     /* Skip over the static ones. They are always at the head of the list */
590     for (i = 0; i < obj->numStatic; i++) {
591         tableEntry = List_next(nameList, (List_Elem *)tableEntry);
592     }
594     /* Enter the gate. */
595     key = GateSwi_enter(NameServer_module->gate);
597     /* Loop through the list searching for the name */
598     while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
599         /* Remove it from the nameList and add to the freeList */
600         if (strcmp(tableEntry->name, name) == 0) {
601             NameServer_removeLocal(obj, tableEntry);
602             status = NameServer_S_SUCCESS;
603             break;
604         }
605     }
607     /* Leave the gate */
608     GateSwi_leave(NameServer_module->gate, key);
610     return (status);
613 /*
614  *  ======== NameServer_removeEntry ========
615  */
616 Int NameServer_removeEntry(NameServer_Handle handle, Ptr entry)
618     ti_sdo_utils_NameServer_Object *obj =
619             (ti_sdo_utils_NameServer_Object *)handle;
621     NameServer_removeLocal(obj, (ti_sdo_utils_NameServer_TableEntry *)entry);
623     return (NameServer_S_SUCCESS);
626 /*
627  *************************************************************************
628  *                       Instance functions
629  *************************************************************************
630  */
632 /*
633  *  ======== ti_sdo_utils_NameServer_Instance_init ========
634  */
635 Int ti_sdo_utils_NameServer_Instance_init(
636         ti_sdo_utils_NameServer_Object *obj, String name,
637         const ti_sdo_utils_NameServer_Params *params, Error_Block *eb)
639     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
640     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
642     obj->name          = name;
643     obj->numStatic     = 0;
644     obj->numDynamic    = params->maxRuntimeEntries;
645     obj->checkExisting = params->checkExisting;
646     obj->maxNameLen    = params->maxNameLen;
647     obj->table         = NULL;
648     obj->values        = NULL;
649     obj->names         = NULL;
650     obj->refCount      = 1;
652     if (params->tableHeap == NULL) {
653         obj->tableHeap = ti_sdo_utils_NameServer_Object_heap();
654     }
655     else {
656         obj->tableHeap = params->tableHeap;
657     }
659     /* minimum value of maxValueLen is sizeof(UInt32) */
660     if (params->maxValueLen < sizeof(UInt32)) {
661         obj->maxValueLen = sizeof(UInt32);
662     }
663     else {
664         obj->maxValueLen = params->maxValueLen;
665     }
667     /* Construct the free and name lists */
668     List_construct(List_struct(freeList), NULL);
669     List_construct(List_struct(nameList), NULL);
671     /* Allocate the entry table. */
672     if (obj->numDynamic != NameServer_ALLOWGROWTH) {
673         obj->table = Memory_alloc(obj->tableHeap,
674             sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic, 0, eb);
676         if (obj->table == NULL) {
677             return (3);
678         }
680         /*
681          * Allocate one big buffer that will be used for a copy of the values.
682          * Allocate not done when size == UInt32 because we copy the value
683          * to obj->values directly and do not need the extra space.
684          */
685         if (!(obj->maxValueLen == sizeof(UInt32))) {
686             obj->values = Memory_alloc(obj->tableHeap,
687                           obj->maxValueLen * obj->numDynamic, 0, eb);
689             if (obj->values == NULL) {
690                 return (2);
691             }
692         }
694         /* Allocate one big buffer that will be used for a copy of the names */
695         obj->names = Memory_alloc(obj->tableHeap,
696                          params->maxNameLen * obj->numDynamic, 0, eb);
697         if (obj->names == NULL) {
698             return (1);
699         }
701         /* Finish the rest of the object init */
702         NameServer_postInit(obj);
703     }
705     return(0);
708 /*
709  *  ======== ti_sdo_utils_NameServer_Instance_finalize ========
710  */
711 Void ti_sdo_utils_NameServer_Instance_finalize(
712         ti_sdo_utils_NameServer_Object *obj, Int status)
714     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
715     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
716     ti_sdo_utils_NameServer_TableEntry *tableEntry;
717     ti_sdo_utils_NameServer_TableEntry *tableEntryNext;
719     if (obj->numDynamic != NameServer_ALLOWGROWTH) {
720         if (obj->names != NULL) {
721             Memory_free(obj->tableHeap, obj->names,
722                         obj->maxNameLen * obj->numDynamic);
723         }
725         if (obj->values != NULL && !(obj->maxValueLen == sizeof(UInt32))) {
726             Memory_free(obj->tableHeap, obj->values,
727                         obj->maxValueLen * obj->numDynamic);
728         }
730         if (obj->table != NULL) {
731             Memory_free(obj->tableHeap, obj->table,
732                         sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic);
733         }
734     }
735     else {
736         tableEntryNext = List_next(nameList, NULL);
737         while (tableEntryNext != NULL) {
738             tableEntry = tableEntryNext;
739             tableEntryNext = List_next(nameList, (List_Elem*)tableEntryNext);
741             /* Free the value if not UInt32 */
742             if (!(obj->maxValueLen == sizeof(UInt32))) {
743                 Memory_free(obj->tableHeap, (Ptr)(tableEntry->value),
744                             obj->maxValueLen);
745             }
747             /* Free the name */
748             Memory_free(obj->tableHeap, tableEntry->name,
749                         strlen(tableEntry->name) + 1);
751             /* Free the entry */
752             Memory_free(obj->tableHeap, tableEntry,
753                         sizeof(ti_sdo_utils_NameServer_TableEntry));
754         }
755     }
757     List_destruct(List_struct(freeList));
758     List_destruct(List_struct(nameList));
765 /*
766  *  ======== ti_sdo_utils_NameServer_removeLocal ========
767  */
768 Void ti_sdo_utils_NameServer_removeLocal(ti_sdo_utils_NameServer_Object *obj,
769                              ti_sdo_utils_NameServer_TableEntry *entry)
771     IArg key;
772     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
773     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
775     /* Remove it from the nameList and add to the freeList or free it */
776     if (obj->numDynamic == NameServer_ALLOWGROWTH) {
778         key = GateSwi_enter(NameServer_module->gate);
779         List_remove(nameList, (List_Elem *)entry);
780         GateSwi_leave(NameServer_module->gate, key);
782         if (!(obj->maxValueLen == sizeof(UInt32))) {
783             Memory_free(obj->tableHeap, (Ptr)entry->value,
784                         obj->maxValueLen);
785         }
787         Memory_free(obj->tableHeap, entry->name,
788                     strlen(entry->name) + 1);
790         Memory_free(obj->tableHeap, entry,
791                     sizeof(ti_sdo_utils_NameServer_TableEntry));
792     }
793     else {
794         key = GateSwi_enter(NameServer_module->gate);
795         List_remove(nameList, (List_Elem *)entry);
796         GateSwi_leave(NameServer_module->gate, key);
798         List_put(freeList, (List_Elem *)entry);
799     }
802 /*
803  *  ======== ti_sdo_utils_NameServer_getKey ========
804  */
805 Ptr ti_sdo_utils_NameServer_getKey(ti_sdo_utils_NameServer_Object *obj,
806         UInt32 val)
808     IArg  key;
809     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
810     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
812     /* Need to assume the value length is sizeof(UInt32) */
813     Assert_isTrue(obj->maxValueLen == sizeof(UInt32), NULL);
815     key = GateSwi_enter(NameServer_module->gate);
817     while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
818         != NULL) {
819         /* Do the comparison */
820         if (tableEntry->value == val) {
821             break;
822         }
823     }
825     GateSwi_leave(NameServer_module->gate, key);
827     return (tableEntry);
831 /*
832  *************************************************************************
833  *                      Module functions
834  *************************************************************************
835  */
837 /*
838  *  ======== ti_sdo_utils_NameServer_Module_startup ========
839  */
840 Int ti_sdo_utils_NameServer_Module_startup( Int phase )
842     Int i;
843     ti_sdo_utils_NameServer_Object *obj;
845     /* Finish setting up the freeList */
846     for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
847         obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
848         if ((obj->numDynamic != 0) &&
849             (obj->numDynamic != NameServer_ALLOWGROWTH)) {
850             NameServer_postInit(obj);
851         }
852     }
854     return (Startup_DONE);
858 /*
859  *  ======== ti_sdo_utils_NameServer_isRegistered ========
860  */
861 Bool ti_sdo_utils_NameServer_isRegistered(UInt16 procId)
863     Bool registered;
864     UInt16 index;
866     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
867             ti_sdo_utils_NameServer_A_invArgument);
869     switch (ti_sdo_utils_MultiProc_procAddrMode) {
870         case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
871             index = procId;
872             break;
874         case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
875             index = procId - MultiProc_getBaseIdOfCluster();
876             break;
878         default:
879             Assert_isTrue(FALSE, NULL);
880             break;
881     }
883     Assert_isTrue(index < NameServer_module->nsRemoteHandle.length,
884             ti_sdo_utils_NameServer_A_invArgument);
886     registered = (NameServer_module->nsRemoteHandle.elem[index] != NULL);
888     return (registered);
891 /*
892  *  ======== ti_sdo_utils_NameServer_registerRemoteDriver ========
893  */
894 Int ti_sdo_utils_NameServer_registerRemoteDriver(INameServerRemote_Handle
895         nsrHandle, UInt16 procId)
897     Int status;
898     UInt16 index;
899     UInt key;
901     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
902             ti_sdo_utils_NameServer_A_invArgument);
904     switch (ti_sdo_utils_MultiProc_procAddrMode) {
905         case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
906             index = procId;
907             break;
909         case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
910             index = procId - MultiProc_getBaseIdOfCluster();
911             break;
913         default:
914             Assert_isTrue(FALSE, NULL);
915             break;
916     }
918     Assert_isTrue(index < NameServer_module->nsRemoteHandle.length,
919             ti_sdo_utils_NameServer_A_invArgument);
921     key = Hwi_disable();
923     if (NameServer_module->nsRemoteHandle.elem[index] != NULL) {
924         status = NameServer_E_FAIL;
925     }
926     else {
927         NameServer_module->nsRemoteHandle.elem[index] = nsrHandle;
928         status = NameServer_S_SUCCESS;
929     }
931     Hwi_restore(key);
933     return (status);
936 /*
937  *  ======== ti_sdo_utils_NameServer_unregisterRemoteDriver ========
938  */
939 Void ti_sdo_utils_NameServer_unregisterRemoteDriver(UInt16 procId)
941     UInt16 index;
942     UInt key;
944     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
945             ti_sdo_utils_NameServer_A_invArgument);
947     switch (ti_sdo_utils_MultiProc_procAddrMode) {
948         case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
949             index = procId;
950             break;
952         case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
953             index = procId - MultiProc_getBaseIdOfCluster();
954             break;
956         default:
957             Assert_isTrue(FALSE, NULL);
958             break;
959     }
961     Assert_isTrue(index < NameServer_module->nsRemoteHandle.length,
962             ti_sdo_utils_NameServer_A_invArgument);
964     key = Hwi_disable();
966     NameServer_module->nsRemoteHandle.elem[index] = NULL;
968     Hwi_restore(key);
971 /*
972  *************************************************************************
973  *                       Internal functions
974  *************************************************************************
975  */
977 /*
978  *  ======== ti_sdo_utils_NameServer_findLocal ========
979  *  Searches the local instance table.
980  */
981 ti_sdo_utils_NameServer_TableEntry *NameServer_findLocal(
982         ti_sdo_utils_NameServer_Object *obj, String name)
984     IArg  key;
985     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
987     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
989     /* Search the table in a thread safe manner */
990     key = GateSwi_enter(NameServer_module->gate);
992     while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
993         != NULL) {
994         /* Do the comparison */
995         if (strcmp(tableEntry->name, name) == 0) {
996             break;
997         }
998     }
1000     GateSwi_leave(NameServer_module->gate, key);
1002     return (tableEntry);
1005 /*
1006  *  ======== ti_sdo_utils_NameServer_postInit ========
1007  *  Function to be called during
1008  *  1. module startup to complete the initialization of all static instances
1009  *  2. instance_init to complete the initialization of a dynamic instance
1010  *
1011  *  The empty entries are added into the freeList. There can be non-empty
1012  *  entries on statically created instances. The instance$static$init already
1013  *  put those entries onto the nameList.
1014  */
1015 Int ti_sdo_utils_NameServer_postInit(ti_sdo_utils_NameServer_Object *obj)
1017     UInt i;
1018     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
1019     ti_sdo_utils_NameServer_TableEntry *tableEntry;
1020     String name;
1022     name = obj->names;
1023     for (i = 0; i < obj->numDynamic; i++) {
1024         tableEntry = &(obj->table[i + obj->numStatic]);
1026         /* Carve out some room for the dynamically added names */
1027         tableEntry->name = name;
1028         name += obj->maxNameLen;
1030         /* Carve out some room for the dynamically added values */
1031         if (obj->maxValueLen > sizeof(UInt32)) {
1032             tableEntry->value = (UArg)((UInt32)obj->values +
1033                     (i * obj->maxValueLen));
1034             tableEntry->len   = obj->maxValueLen;
1035         }
1037         /* Put the entry onto the freeList */
1038         List_put(freeList, (List_Elem *)(tableEntry));
1039     }
1041     return (0);