Change NameServer_get to ignore 'remote get' timeouts in BIOS
[ipc/ipcdev.git] / packages / ti / sdo / utils / NameServer.c
1 /*
2  * Copyright (c) 2012-2013, Texas Instruments Incorporated
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 == NULL) {
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;
349     Error_init(&eb);
351     /*
352      *  Query all the processors.
353      */
354     if (procId == NULL) {
355         /* Query the local one first */
356         status = NameServer_getLocal(handle, name, value, len);
357         if (status == NameServer_E_NOTFOUND) {
358             /* To eliminate code if possible */
359             if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
360                 /* Query all the remote processors */
361                 for (i = 0; i < ti_sdo_utils_MultiProc_numProcessors; i++) {
362                     /* Skip the local table. It was already searched */
363                     if (i != MultiProc_self()) {
364                         if (NameServer_module->nsRemoteHandle[i] != NULL) {
365                             status = INameServerRemote_get(
366                                      NameServer_module->nsRemoteHandle[i],
367                                      obj->name, name, value, len, NULL, &eb);
368                         }
370                         /* continue only if not found */
371                         if ((status >= 0) ||
372                             ((status < 0) &&
373                             (status != NameServer_E_NOTFOUND) &&
374                             (status != NameServer_E_TIMEOUT))) {
375                              break;
376                         }
377                     }
378                 }
379             }
380         }
381     }
382     else {
383         /*
384          *  Search the query list. It might contain the local proc
385          *  somewhere in the list.
386          */
387         i = 0;
388         status = NameServer_E_NOTFOUND;
389         while (procId[i] != MultiProc_INVALIDID) {
390             if (procId[i] == MultiProc_self()) {
391                 /* Check local */
392                 status = NameServer_getLocal(handle, name, value, len);
393             }
394             else if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
395                 /* Check remote */
396                 if (NameServer_module->nsRemoteHandle[procId[i]] != NULL) {
397                     status = INameServerRemote_get(
398                              NameServer_module->nsRemoteHandle[procId[i]],
399                              obj->name, name, value, len, NULL, &eb);
400                 }
401             }
403             /* continue only if not found */
404             if ((status >= 0) ||
405                 ((status < 0) &&
406                 (status != NameServer_E_NOTFOUND) &&
407                 (status != NameServer_E_TIMEOUT))) {
408                  break;
409             }
410             else {
411                 i++;
413                 /* if we've queried all procs then exit */
414                 if (i == MultiProc_getNumProcsInCluster()) {
415                     break;
416                 }
417             }
418         }
419     }
421     return (status);
424 /*
425  *  ======== NameServer_getHandle ========
426  *  Helper function to get a handle based on the instance name.
427  */
428 NameServer_Handle NameServer_getHandle(String instanceName)
430     ti_sdo_utils_NameServer_Object *obj;
431     IArg key;
432     Int i;
434     /* Search static instances */
435     for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
436         obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
437         if ((obj->name != NULL) &&
438             (strcmp(obj->name, instanceName) == 0)) {
439             return ((NameServer_Handle)obj);
440         }
441     }
443     /* Search dynamic instances (in a thread safe manner) */
444     key = GateSwi_enter(NameServer_module->gate);
446     obj = ti_sdo_utils_NameServer_Object_first();
447     while (obj != NULL) {
448         if ((obj->name != NULL) &&
449             (strcmp(obj->name, instanceName) == 0)) {
450             GateSwi_leave(NameServer_module->gate, key);
451             return ((NameServer_Handle)obj);
452         }
453         obj = ti_sdo_utils_NameServer_Object_next(obj);
454     }
455     GateSwi_leave(NameServer_module->gate, key);
457     return (NULL);
460 /*
461  *  ======== NameServer_getLocal ========
462  */
463 Int NameServer_getLocal(NameServer_Handle handle, String name, Ptr value,
464                         UInt32 *len)
466     ti_sdo_utils_NameServer_Object *obj =
467             (ti_sdo_utils_NameServer_Object *)handle;
468     IArg key;
469     ti_sdo_utils_NameServer_TableEntry *tableEntry;
471     key = GateSwi_enter(NameServer_module->gate);
473     /* search the local table */
474     tableEntry = NameServer_findLocal(obj, name);
476     if (tableEntry != NULL) {
477         /*
478          *  Found the entry.
479          *  If the table holds value (and not buffers) simply
480          *  copy into value and return
481          */
482         if (obj->maxValueLen == sizeof(UInt32)) {
483             memcpy((Ptr)value, &(tableEntry->value), sizeof(UInt32));
484         }
485         else {
486             Assert_isTrue((tableEntry->len <= *len), ti_sdo_utils_NameServer_A_invalidLen);
487             memcpy((Ptr)value, (Ptr)(tableEntry->value), tableEntry->len);
488         }
489         GateSwi_leave(NameServer_module->gate, key);
490         *len = tableEntry->len;
491         return (NameServer_S_SUCCESS);
492     }
494     GateSwi_leave(NameServer_module->gate, key);
496     /* Name not found locally. */
497     return (NameServer_E_NOTFOUND);
500 /*
501  *  ======== NameServer_getLocalUInt32 ========
502  *
503  */
504 Int NameServer_getLocalUInt32(NameServer_Handle handle, String name, Ptr value)
506     UInt32 len = sizeof(UInt32);
507     Int status;
509     status = NameServer_getLocal(handle, name, value, &len);
511     return (status);
514 /*
515  *  ======== NameServer_getUInt32 ========
516  */
517 Int NameServer_getUInt32(NameServer_Handle handle, String name,
518                          Ptr value, UInt16 remoteProcId[])
520     UInt32 len = sizeof(UInt32);
521     Int status;
523     status = NameServer_get(handle, name, value, &len, remoteProcId);
525     return (status);
528 /*  ======== NameServer_match ========
529  *  Currently only supporting 32-bit values.
530  */
531 Int NameServer_match(NameServer_Handle handle, String name, UInt32 *value)
533     ti_sdo_utils_NameServer_Object *obj =
534             (ti_sdo_utils_NameServer_Object *)handle;
535     Int len = 0;
536     Int foundLen = 0;
537     IArg key;
538     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
539     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
541     Assert_isTrue((sizeof(UInt32) == obj->maxValueLen),
542             ti_sdo_utils_NameServer_A_invalidLen);
544     key = GateSwi_enter(NameServer_module->gate);
546     /* Search the entire table and find the longest match */
547     while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
549         len = strlen(tableEntry->name);
551         /*
552          *  Only check if the name in the table is going to potentially be
553          *  a better match.
554          */
555         if (len > foundLen) {
556             if (strncmp(name, tableEntry->name, len) == 0) {
557                 *value = (UInt32)(tableEntry->value);
558                 foundLen = len;
559             }
560         }
561     }
563     GateSwi_leave(NameServer_module->gate, key);
565     /* The name was not found...return 0 characters matched*/
566     return (foundLen);
569 /*
570  *  ======== NameServer_remove ========
571  *  Remove a name/value pair.
572  */
573 Int NameServer_remove(NameServer_Handle handle, String name)
575     ti_sdo_utils_NameServer_Object *obj =
576             (ti_sdo_utils_NameServer_Object *)handle;
577     UInt i;
578     IArg key;
579     Int status = NameServer_E_INVALIDARG;
580     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
581     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
583     /* Skip over the static ones. They are always at the head of the list */
584     for (i = 0; i < obj->numStatic; i++) {
585         tableEntry = List_next(nameList, (List_Elem *)tableEntry);
586     }
588     /* Enter the gate. */
589     key = GateSwi_enter(NameServer_module->gate);
591     /* Loop through the list searching for the name */
592     while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
593         /* Remove it from the nameList and add to the freeList */
594         if (strcmp(tableEntry->name, name) == 0) {
595             NameServer_removeLocal(obj, tableEntry);
596             status = NameServer_S_SUCCESS;
597             break;
598         }
599     }
601     /* Leave the gate */
602     GateSwi_leave(NameServer_module->gate, key);
604     return (status);
607 /*
608  *  ======== NameServer_removeEntry ========
609  */
610 Int NameServer_removeEntry(NameServer_Handle handle, Ptr entry)
612     ti_sdo_utils_NameServer_Object *obj =
613             (ti_sdo_utils_NameServer_Object *)handle;
615     NameServer_removeLocal(obj, (ti_sdo_utils_NameServer_TableEntry *)entry);
617     return (NameServer_S_SUCCESS);
620 /*
621  *************************************************************************
622  *                       Instance functions
623  *************************************************************************
624  */
626 /*
627  *  ======== ti_sdo_utils_NameServer_Instance_init ========
628  */
629 Int ti_sdo_utils_NameServer_Instance_init(
630         ti_sdo_utils_NameServer_Object *obj, String name,
631         const ti_sdo_utils_NameServer_Params *params, Error_Block *eb)
633     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
634     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
636     obj->name          = name;
637     obj->numStatic     = 0;
638     obj->numDynamic    = params->maxRuntimeEntries;
639     obj->checkExisting = params->checkExisting;
640     obj->maxNameLen    = params->maxNameLen;
641     obj->table         = NULL;
642     obj->values        = NULL;
643     obj->names         = NULL;
644     obj->refCount      = 1;
646     if (params->tableHeap == NULL) {
647         obj->tableHeap = ti_sdo_utils_NameServer_Object_heap();
648     }
649     else {
650         obj->tableHeap = params->tableHeap;
651     }
653     /* minimum value of maxValueLen is sizeof(UInt32) */
654     if (params->maxValueLen < sizeof(UInt32)) {
655         obj->maxValueLen = sizeof(UInt32);
656     }
657     else {
658         obj->maxValueLen = params->maxValueLen;
659     }
661     /* Construct the free and name lists */
662     List_construct(List_struct(freeList), NULL);
663     List_construct(List_struct(nameList), NULL);
665     /* Allocate the entry table. */
666     if (obj->numDynamic != NameServer_ALLOWGROWTH) {
667         obj->table = Memory_alloc(obj->tableHeap,
668             sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic, 0, eb);
670         if (obj->table == NULL) {
671             return (3);
672         }
674         /*
675          * Allocate one big buffer that will be used for a copy of the values.
676          * Allocate not done when size == UInt32 because we copy the value
677          * to obj->values directly and do not need the extra space.
678          */
679         if (!(obj->maxValueLen == sizeof(UInt32))) {
680             obj->values = Memory_alloc(obj->tableHeap,
681                           obj->maxValueLen * obj->numDynamic, 0, eb);
683             if (obj->values == NULL) {
684                 return (2);
685             }
686         }
688         /* Allocate one big buffer that will be used for a copy of the names */
689         obj->names = Memory_alloc(obj->tableHeap,
690                          params->maxNameLen * obj->numDynamic, 0, eb);
691         if (obj->names == NULL) {
692             return (1);
693         }
695         /* Finish the rest of the object init */
696         NameServer_postInit(obj);
697     }
699     return(0);
702 /*
703  *  ======== ti_sdo_utils_NameServer_Instance_finalize ========
704  */
705 Void ti_sdo_utils_NameServer_Instance_finalize(
706         ti_sdo_utils_NameServer_Object *obj, Int status)
708     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
709     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
710     ti_sdo_utils_NameServer_TableEntry *tableEntry;
711     ti_sdo_utils_NameServer_TableEntry *tableEntryNext;
713     if (obj->numDynamic != NameServer_ALLOWGROWTH) {
714         if (obj->names != NULL) {
715             Memory_free(obj->tableHeap, obj->names,
716                         obj->maxNameLen * obj->numDynamic);
717         }
719         if (obj->values != NULL && !(obj->maxValueLen == sizeof(UInt32))) {
720             Memory_free(obj->tableHeap, obj->values,
721                         obj->maxValueLen * obj->numDynamic);
722         }
724         if (obj->table != NULL) {
725             Memory_free(obj->tableHeap, obj->table,
726                         sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic);
727         }
728     }
729     else {
730         tableEntryNext = List_next(nameList, NULL);
731         while (tableEntryNext != NULL) {
732             tableEntry = tableEntryNext;
733             tableEntryNext = List_next(nameList, (List_Elem*)tableEntryNext);
735             /* Free the value if not UInt32 */
736             if (!(obj->maxValueLen == sizeof(UInt32))) {
737                 Memory_free(obj->tableHeap, (Ptr)(tableEntry->value),
738                             obj->maxValueLen);
739             }
741             /* Free the name */
742             Memory_free(obj->tableHeap, tableEntry->name,
743                         strlen(tableEntry->name) + 1);
745             /* Free the entry */
746             Memory_free(obj->tableHeap, tableEntry,
747                         sizeof(ti_sdo_utils_NameServer_TableEntry));
748         }
749     }
751     List_destruct(List_struct(freeList));
752     List_destruct(List_struct(nameList));
759 /*
760  *  ======== ti_sdo_utils_NameServer_removeLocal ========
761  */
762 Void ti_sdo_utils_NameServer_removeLocal(ti_sdo_utils_NameServer_Object *obj,
763                              ti_sdo_utils_NameServer_TableEntry *entry)
765     IArg key;
766     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
767     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
769     /* Remove it from the nameList and add to the freeList or free it */
770     if (obj->numDynamic == NameServer_ALLOWGROWTH) {
772         key = GateSwi_enter(NameServer_module->gate);
773         List_remove(nameList, (List_Elem *)entry);
774         GateSwi_leave(NameServer_module->gate, key);
776         if (!(obj->maxValueLen == sizeof(UInt32))) {
777             Memory_free(obj->tableHeap, (Ptr)entry->value,
778                         obj->maxValueLen);
779         }
781         Memory_free(obj->tableHeap, entry->name,
782                     strlen(entry->name) + 1);
784         Memory_free(obj->tableHeap, entry,
785                     sizeof(ti_sdo_utils_NameServer_TableEntry));
786     }
787     else {
788         key = GateSwi_enter(NameServer_module->gate);
789         List_remove(nameList, (List_Elem *)entry);
790         GateSwi_leave(NameServer_module->gate, key);
792         List_put(freeList, (List_Elem *)entry);
793     }
796 /*
797  *  ======== ti_sdo_utils_NameServer_getKey ========
798  */
799 Ptr ti_sdo_utils_NameServer_getKey(ti_sdo_utils_NameServer_Object *obj,
800         UInt32 val)
802     IArg  key;
803     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
804     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
806     /* Need to assume the value length is sizeof(UInt32) */
807     Assert_isTrue(obj->maxValueLen == sizeof(UInt32), NULL);
809     key = GateSwi_enter(NameServer_module->gate);
811     while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
812         != NULL) {
813         /* Do the comparison */
814         if (tableEntry->value == val) {
815             break;
816         }
817     }
819     GateSwi_leave(NameServer_module->gate, key);
821     return (tableEntry);
825 /*
826  *************************************************************************
827  *                      Module functions
828  *************************************************************************
829  */
831 /*
832  *  ======== ti_sdo_utils_NameServer_Module_startup ========
833  */
834 Int ti_sdo_utils_NameServer_Module_startup( Int phase )
836     Int i;
837     ti_sdo_utils_NameServer_Object *obj;
839     for (i = 0; i < ti_sdo_utils_MultiProc_numProcessors; i++) {
840         NameServer_module->nsRemoteHandle[i] = NULL;
841     }
843     /* Finish setting up the freeList */
844     for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
845         obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
846         if ((obj->numDynamic != 0) &&
847             (obj->numDynamic != NameServer_ALLOWGROWTH)) {
848             NameServer_postInit(obj);
849         }
850     }
852     return (Startup_DONE);
856 /*
857  *  ======== ti_sdo_utils_NameServer_isRegistered ========
858  */
859 Bool ti_sdo_utils_NameServer_isRegistered(UInt16 procId)
861     Bool registered;
863     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
864             ti_sdo_utils_NameServer_A_invArgument);
866     registered = (NameServer_module->nsRemoteHandle[procId] != NULL);
868     return (registered);
871 /*
872  *  ======== ti_sdo_utils_NameServer_registerRemoteDriver ========
873  */
874 Int ti_sdo_utils_NameServer_registerRemoteDriver(INameServerRemote_Handle nsrHandle,
875         UInt16 procId)
877     Int   status;
878     UInt key;
880     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
881             ti_sdo_utils_NameServer_A_invArgument);
883     key = Hwi_disable();
885     if (NameServer_module->nsRemoteHandle[procId] != NULL) {
886         status = NameServer_E_FAIL;
887     }
888     else {
889         NameServer_module->nsRemoteHandle[procId] = nsrHandle;
890         status = NameServer_S_SUCCESS;
891     }
893     Hwi_restore(key);
895     return (status);
898 /*
899  *  ======== ti_sdo_utils_NameServer_unregisterRemoteDriver ========
900  */
901 Void ti_sdo_utils_NameServer_unregisterRemoteDriver(UInt16 procId)
903     UInt key;
905     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
906             ti_sdo_utils_NameServer_A_invArgument);
908     key = Hwi_disable();
910     NameServer_module->nsRemoteHandle[procId] = NULL;
912     Hwi_restore(key);
915 /*
916  *************************************************************************
917  *                       Internal functions
918  *************************************************************************
919  */
921 /*
922  *  ======== ti_sdo_utils_NameServer_findLocal ========
923  *  Searches the local instance table.
924  */
925 ti_sdo_utils_NameServer_TableEntry *NameServer_findLocal(
926         ti_sdo_utils_NameServer_Object *obj, String name)
928     IArg  key;
929     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
931     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
933     /* Search the table in a thread safe manner */
934     key = GateSwi_enter(NameServer_module->gate);
936     while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
937         != NULL) {
938         /* Do the comparison */
939         if (strcmp(tableEntry->name, name) == 0) {
940             break;
941         }
942     }
944     GateSwi_leave(NameServer_module->gate, key);
946     return (tableEntry);
949 /*
950  *  ======== ti_sdo_utils_NameServer_postInit ========
951  *  Function to be called during
952  *  1. module startup to complete the initialization of all static instances
953  *  2. instance_init to complete the initialization of a dynamic instance
954  *
955  *  The empty entries are added into the freeList. There can be non-empty
956  *  entries on statically created instances. The instance$static$init already
957  *  put those entries onto the nameList.
958  */
959 Int ti_sdo_utils_NameServer_postInit(ti_sdo_utils_NameServer_Object *obj)
961     UInt i;
962     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
963     ti_sdo_utils_NameServer_TableEntry *tableEntry;
964     String name;
966     name = obj->names;
967     for (i = 0; i < obj->numDynamic; i++) {
968         tableEntry = &(obj->table[i + obj->numStatic]);
970         /* Carve out some room for the dynamically added names */
971         tableEntry->name = name;
972         name += obj->maxNameLen;
974         /* Carve out some room for the dynamically added values */
975         if (obj->maxValueLen > sizeof(UInt32)) {
976             tableEntry->value = (UArg)((UInt32)obj->values +
977                     (i * obj->maxValueLen));
978             tableEntry->len   = obj->maxValueLen;
979         }
981         /* Put the entry onto the freeList */
982         List_put(freeList, (List_Elem *)(tableEntry));
983     }
985     return (0);