]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - packages/ti/sdo/utils/NameServer.c
Rename: git mv src packages to complete application of ipc-j patches to ipcdev.
[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;
278     Error_init(&eb);
280     if (params != NULL) {
281         /* init the module params struct */
282         ti_sdo_utils_NameServer_Params_init(&nsParams);
283         nsParams.maxRuntimeEntries = params->maxRuntimeEntries;
284         nsParams.tableHeap         = params->tableHeap;
285         nsParams.checkExisting     = params->checkExisting;
286         nsParams.maxValueLen       = params->maxValueLen;
287         nsParams.maxNameLen        = params->maxNameLen;
289         /* call the module create */
290         obj = ti_sdo_utils_NameServer_create(name, &nsParams, &eb);
291     }
292     else {
293         /* passing in NULL uses the default params */
294         obj = ti_sdo_utils_NameServer_create(name, NULL, &eb);
295     }
297     return ((NameServer_Handle)obj);
300 /*
301  *  ======== NameServer_delete ========
302  */
303 Int NameServer_delete(NameServer_Handle *handlePtr)
305     ti_sdo_utils_NameServer_delete(
306         (ti_sdo_utils_NameServer_Handle *)handlePtr);
308     return (NameServer_S_SUCCESS);
311 /*
312  *  ======== NameServer_get ========
313  *  Currently not using ISync in RemoteProxy call. This is for async support.
314  */
315 Int NameServer_get(NameServer_Handle handle, String name, Ptr value,
316                    UInt32 *len, UInt16 procId[])
318     ti_sdo_utils_NameServer_Object *obj =
319             (ti_sdo_utils_NameServer_Object *)handle;
320     Int i;
321     Int status = NameServer_E_FAIL;
322     Error_Block eb;
324     Error_init(&eb);
326     /*
327      *  Query all the processors.
328      */
329     if (procId == NULL) {
330         /* Query the local one first */
331         status = NameServer_getLocal(handle, name, value, len);
332         if (status == NameServer_E_NOTFOUND) {
333             /* To eliminate code if possible */
334             if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
335                 /* Query all the remote processors */
336                 for (i = 0; i < ti_sdo_utils_MultiProc_numProcessors; i++) {
337                     /* Skip the local table. It was already searched */
338                     if (i != MultiProc_self()) {
339                         if (NameServer_module->nsRemoteHandle[i] != NULL) {
340                             status = INameServerRemote_get(
341                                      NameServer_module->nsRemoteHandle[i],
342                                      obj->name, name, value, len, NULL, &eb);
343                         }
345                         /* continue only if not found */
346                         if ((status >= 0) ||
347                             ((status < 0) &&
348                             (status != NameServer_E_NOTFOUND))) {
349                              break;
350                         }
351                     }
352                 }
353             }
354         }
355     }
356     else {
357         /*
358          *  Search the query list. It might contain the local proc
359          *  somewhere in the list.
360          */
361         i = 0;
362         status = NameServer_E_NOTFOUND;
363         while (procId[i] != MultiProc_INVALIDID) {
364             if (procId[i] == MultiProc_self()) {
365                 /* Check local */
366                 status = NameServer_getLocal(handle, name, value, len);
367             }
368             else if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
369                 /* Check remote */
370                 if (NameServer_module->nsRemoteHandle[procId[i]] != NULL) {
371                     status = INameServerRemote_get(
372                              NameServer_module->nsRemoteHandle[procId[i]],
373                              obj->name, name, value, len, NULL, &eb);
374                 }
375             }
377             /* continue only if not found */
378             if ((status >= 0) ||
379                 ((status < 0) &&
380                 (status != NameServer_E_NOTFOUND))) {
381                  break;
382             }
383             else {
384                 i++;
386                 /* if we've queried all procs then exit */
387                 if (i == MultiProc_getNumProcsInCluster()) {
388                     break;
389                 }
390             }
391         }
392     }
394     return (status);
397 /*
398  *  ======== NameServer_getHandle ========
399  *  Helper function to get a handle based on the instance name.
400  */
401 NameServer_Handle NameServer_getHandle(String instanceName)
403     ti_sdo_utils_NameServer_Object *obj;
404     IArg key;
405     Int i;
407     /* Search static instances */
408     for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
409         obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
410         if ((obj->name != NULL) &&
411             (strcmp(obj->name, instanceName) == 0)) {
412             return ((NameServer_Handle)obj);
413         }
414     }
416     /* Search dynamic instances (in a thread safe manner) */
417     key = GateSwi_enter(NameServer_module->gate);
419     obj = ti_sdo_utils_NameServer_Object_first();
420     while (obj != NULL) {
421         if ((obj->name != NULL) &&
422             (strcmp(obj->name, instanceName) == 0)) {
423             GateSwi_leave(NameServer_module->gate, key);
424             return ((NameServer_Handle)obj);
425         }
426         obj = ti_sdo_utils_NameServer_Object_next(obj);
427     }
428     GateSwi_leave(NameServer_module->gate, key);
430     return (NULL);
433 /*
434  *  ======== NameServer_getLocal ========
435  */
436 Int NameServer_getLocal(NameServer_Handle handle, String name, Ptr value,
437                         UInt32 *len)
439     ti_sdo_utils_NameServer_Object *obj =
440             (ti_sdo_utils_NameServer_Object *)handle;
441     IArg key;
442     ti_sdo_utils_NameServer_TableEntry *tableEntry;
444     key = GateSwi_enter(NameServer_module->gate);
446     /* search the local table */
447     tableEntry = NameServer_findLocal(obj, name);
449     if (tableEntry != NULL) {
450         /*
451          *  Found the entry.
452          *  If the table holds value (and not buffers) simply
453          *  copy into value and return
454          */
455         if (obj->maxValueLen == sizeof(UInt32)) {
456             memcpy((Ptr)value, &(tableEntry->value), sizeof(UInt32));
457         }
458         else {
459             Assert_isTrue((tableEntry->len <= *len), ti_sdo_utils_NameServer_A_invalidLen);
460             memcpy((Ptr)value, (Ptr)(tableEntry->value), tableEntry->len);
461         }
462         GateSwi_leave(NameServer_module->gate, key);
463         *len = tableEntry->len;
464         return (NameServer_S_SUCCESS);
465     }
467     GateSwi_leave(NameServer_module->gate, key);
469     /* Name not found locally. */
470     return (NameServer_E_NOTFOUND);
473 /*
474  *  ======== NameServer_getLocalUInt32 ========
475  *
476  */
477 Int NameServer_getLocalUInt32(NameServer_Handle handle, String name, Ptr value)
479     UInt32 len = sizeof(UInt32);
480     Int status;
482     status = NameServer_getLocal(handle, name, value, &len);
484     return (status);
487 /*
488  *  ======== NameServer_getUInt32 ========
489  */
490 Int NameServer_getUInt32(NameServer_Handle handle, String name,
491                          Ptr value, UInt16 remoteProcId[])
493     UInt32 len = sizeof(UInt32);
494     Int status;
496     status = NameServer_get(handle, name, value, &len, remoteProcId);
498     return (status);
501 /*  ======== NameServer_match ========
502  *  Currently only supporting 32-bit values.
503  */
504 Int NameServer_match(NameServer_Handle handle, String name, UInt32 *value)
506     ti_sdo_utils_NameServer_Object *obj =
507             (ti_sdo_utils_NameServer_Object *)handle;
508     Int len = 0;
509     Int foundLen = 0;
510     IArg key;
511     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
512     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
514     Assert_isTrue((sizeof(UInt32) == obj->maxValueLen),
515             ti_sdo_utils_NameServer_A_invalidLen);
517     key = GateSwi_enter(NameServer_module->gate);
519     /* Search the entire table and find the longest match */
520     while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
522         len = strlen(tableEntry->name);
524         /*
525          *  Only check if the name in the table is going to potentially be
526          *  a better match.
527          */
528         if (len > foundLen) {
529             if (strncmp(name, tableEntry->name, len) == 0) {
530                 *value = (UInt32)(tableEntry->value);
531                 foundLen = len;
532             }
533         }
534     }
536     GateSwi_leave(NameServer_module->gate, key);
538     /* The name was not found...return 0 characters matched*/
539     return (foundLen);
542 /*
543  *  ======== NameServer_remove ========
544  *  Remove a name/value pair.
545  */
546 Int NameServer_remove(NameServer_Handle handle, String name)
548     ti_sdo_utils_NameServer_Object *obj =
549             (ti_sdo_utils_NameServer_Object *)handle;
550     UInt i;
551     IArg key;
552     Int status = NameServer_E_INVALIDARG;
553     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
554     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
556     /* Skip over the static ones. They are always at the head of the list */
557     for (i = 0; i < obj->numStatic; i++) {
558         tableEntry = List_next(nameList, (List_Elem *)tableEntry);
559     }
561     /* Enter the gate. */
562     key = GateSwi_enter(NameServer_module->gate);
564     /* Loop through the list searching for the name */
565     while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
566         /* Remove it from the nameList and add to the freeList */
567         if (strcmp(tableEntry->name, name) == 0) {
568             NameServer_removeLocal(obj, tableEntry);
569             status = NameServer_S_SUCCESS;
570             break;
571         }
572     }
574     /* Leave the gate */
575     GateSwi_leave(NameServer_module->gate, key);
577     return (status);
580 /*
581  *  ======== NameServer_removeEntry ========
582  */
583 Int NameServer_removeEntry(NameServer_Handle handle, Ptr entry)
585     ti_sdo_utils_NameServer_Object *obj =
586             (ti_sdo_utils_NameServer_Object *)handle;
588     NameServer_removeLocal(obj, (ti_sdo_utils_NameServer_TableEntry *)entry);
590     return (NameServer_S_SUCCESS);
593 /*
594  *************************************************************************
595  *                       Instance functions
596  *************************************************************************
597  */
599 /*
600  *  ======== ti_sdo_utils_NameServer_Instance_init ========
601  */
602 Int ti_sdo_utils_NameServer_Instance_init(
603         ti_sdo_utils_NameServer_Object *obj, String name,
604         const ti_sdo_utils_NameServer_Params *params, Error_Block *eb)
606     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
607     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
609     obj->name          = name;
610     obj->numStatic     = 0;
611     obj->numDynamic    = params->maxRuntimeEntries;
612     obj->checkExisting = params->checkExisting;
613     obj->maxNameLen    = params->maxNameLen;
614     obj->table         = NULL;
615     obj->values        = NULL;
616     obj->names         = NULL;
618     if (params->tableHeap == NULL) {
619         obj->tableHeap = ti_sdo_utils_NameServer_Object_heap();
620     }
621     else {
622         obj->tableHeap = params->tableHeap;
623     }
625     /* minimum value of maxValueLen is sizeof(UInt32) */
626     if (params->maxValueLen < sizeof(UInt32)) {
627         obj->maxValueLen = sizeof(UInt32);
628     }
629     else {
630         obj->maxValueLen = params->maxValueLen;
631     }
633     /* Construct the free and name lists */
634     List_construct(List_struct(freeList), NULL);
635     List_construct(List_struct(nameList), NULL);
637     /* Allocate the entry table. */
638     if (obj->numDynamic != NameServer_ALLOWGROWTH) {
639         obj->table = Memory_alloc(obj->tableHeap,
640             sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic, 0, eb);
642         if (obj->table == NULL) {
643             return (3);
644         }
646         /*
647          * Allocate one big buffer that will be used for a copy of the values.
648          * Allocate not done when size == UInt32 because we copy the value
649          * to obj->values directly and do not need the extra space.
650          */
651         if (!(obj->maxValueLen == sizeof(UInt32))) {
652             obj->values = Memory_alloc(obj->tableHeap,
653                           obj->maxValueLen * obj->numDynamic, 0, eb);
655             if (obj->values == NULL) {
656                 return (2);
657             }
658         }
660         /* Allocate one big buffer that will be used for a copy of the names */
661         obj->names = Memory_alloc(obj->tableHeap,
662                          params->maxNameLen * obj->numDynamic, 0, eb);
663         if (obj->names == NULL) {
664             return (1);
665         }
667         /* Finish the rest of the object init */
668         NameServer_postInit(obj);
669     }
671     return(0);
674 /*
675  *  ======== ti_sdo_utils_NameServer_Instance_finalize ========
676  */
677 Void ti_sdo_utils_NameServer_Instance_finalize(
678         ti_sdo_utils_NameServer_Object *obj, Int status)
680     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
681     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
682     ti_sdo_utils_NameServer_TableEntry *tableEntry;
683     ti_sdo_utils_NameServer_TableEntry *tableEntryNext;
685     if (obj->numDynamic != NameServer_ALLOWGROWTH) {
686         if (obj->names != NULL) {
687             Memory_free(obj->tableHeap, obj->names,
688                         obj->maxNameLen * obj->numDynamic);
689         }
691         if (obj->values != NULL && !(obj->maxValueLen == sizeof(UInt32))) {
692             Memory_free(obj->tableHeap, obj->values,
693                         obj->maxValueLen * obj->numDynamic);
694         }
696         if (obj->table != NULL) {
697             Memory_free(obj->tableHeap, obj->table,
698                         sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic);
699         }
700     }
701     else {
702         tableEntryNext = List_next(nameList, NULL);
703         while (tableEntryNext != NULL) {
704             tableEntry = tableEntryNext;
705             tableEntryNext = List_next(nameList, (List_Elem*)tableEntryNext);
707             /* Free the value if not UInt32 */
708             if (!(obj->maxValueLen == sizeof(UInt32))) {
709                 Memory_free(obj->tableHeap, (Ptr)(tableEntry->value),
710                             obj->maxValueLen);
711             }
713             /* Free the name */
714             Memory_free(obj->tableHeap, tableEntry->name,
715                         strlen(tableEntry->name) + 1);
717             /* Free the entry */
718             Memory_free(obj->tableHeap, tableEntry,
719                         sizeof(ti_sdo_utils_NameServer_TableEntry));
720         }
721     }
723     List_destruct(List_struct(freeList));
724     List_destruct(List_struct(nameList));
731 /*
732  *  ======== ti_sdo_utils_NameServer_removeLocal ========
733  */
734 Void ti_sdo_utils_NameServer_removeLocal(ti_sdo_utils_NameServer_Object *obj,
735                              ti_sdo_utils_NameServer_TableEntry *entry)
737     IArg key;
738     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
739     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
741     /* Remove it from the nameList and add to the freeList or free it */
742     if (obj->numDynamic == NameServer_ALLOWGROWTH) {
744         key = GateSwi_enter(NameServer_module->gate);
745         List_remove(nameList, (List_Elem *)entry);
746         GateSwi_leave(NameServer_module->gate, key);
748         if (!(obj->maxValueLen == sizeof(UInt32))) {
749             Memory_free(obj->tableHeap, (Ptr)entry->value,
750                         obj->maxValueLen);
751         }
753         Memory_free(obj->tableHeap, entry->name,
754                     strlen(entry->name) + 1);
756         Memory_free(obj->tableHeap, entry,
757                     sizeof(ti_sdo_utils_NameServer_TableEntry));
758     }
759     else {
760         key = GateSwi_enter(NameServer_module->gate);
761         List_remove(nameList, (List_Elem *)entry);
762         GateSwi_leave(NameServer_module->gate, key);
764         List_put(freeList, (List_Elem *)entry);
765     }
768 /*
769  *  ======== ti_sdo_utils_NameServer_getKey ========
770  */
771 Ptr ti_sdo_utils_NameServer_getKey(ti_sdo_utils_NameServer_Object *obj,
772         UInt32 val)
774     IArg  key;
775     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
776     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
778     /* Need to assume the value length is sizeof(UInt32) */
779     Assert_isTrue(obj->maxValueLen == sizeof(UInt32), NULL);
781     key = GateSwi_enter(NameServer_module->gate);
783     while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
784         != NULL) {
785         /* Do the comparison */
786         if (tableEntry->value == val) {
787             break;
788         }
789     }
791     GateSwi_leave(NameServer_module->gate, key);
793     return (tableEntry);
797 /*
798  *************************************************************************
799  *                      Module functions
800  *************************************************************************
801  */
803 /*
804  *  ======== ti_sdo_utils_NameServer_Module_startup ========
805  */
806 Int ti_sdo_utils_NameServer_Module_startup( Int phase )
808     Int i;
809     ti_sdo_utils_NameServer_Object *obj;
811     for (i = 0; i < ti_sdo_utils_MultiProc_numProcessors; i++) {
812         NameServer_module->nsRemoteHandle[i] = NULL;
813     }
815     /* Finish setting up the freeList */
816     for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
817         obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
818         if ((obj->numDynamic != 0) &&
819             (obj->numDynamic != NameServer_ALLOWGROWTH)) {
820             NameServer_postInit(obj);
821         }
822     }
824     return (Startup_DONE);
828 /*
829  *  ======== ti_sdo_utils_NameServer_isRegistered ========
830  */
831 Bool ti_sdo_utils_NameServer_isRegistered(UInt16 procId)
833     Bool registered;
835     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
836             ti_sdo_utils_NameServer_A_invArgument);
838     registered = (NameServer_module->nsRemoteHandle[procId] != NULL);
840     return (registered);
843 /*
844  *  ======== ti_sdo_utils_NameServer_registerRemoteDriver ========
845  */
846 Int ti_sdo_utils_NameServer_registerRemoteDriver(INameServerRemote_Handle nsrHandle,
847         UInt16 procId)
849     Int   status;
850     UInt key;
852     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
853             ti_sdo_utils_NameServer_A_invArgument);
855     key = Hwi_disable();
857     if (NameServer_module->nsRemoteHandle[procId] != NULL) {
858         status = NameServer_E_FAIL;
859     }
860     else {
861         NameServer_module->nsRemoteHandle[procId] = nsrHandle;
862         status = NameServer_S_SUCCESS;
863     }
865     Hwi_restore(key);
867     return (status);
870 /*
871  *  ======== ti_sdo_utils_NameServer_unregisterRemoteDriver ========
872  */
873 Void ti_sdo_utils_NameServer_unregisterRemoteDriver(UInt16 procId)
875     UInt key;
877     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
878             ti_sdo_utils_NameServer_A_invArgument);
880     key = Hwi_disable();
882     NameServer_module->nsRemoteHandle[procId] = NULL;
884     Hwi_restore(key);
887 /*
888  *************************************************************************
889  *                       Internal functions
890  *************************************************************************
891  */
893 /*
894  *  ======== ti_sdo_utils_NameServer_findLocal ========
895  *  Searches the local instance table.
896  */
897 ti_sdo_utils_NameServer_TableEntry *NameServer_findLocal(
898         ti_sdo_utils_NameServer_Object *obj, String name)
900     IArg  key;
901     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
903     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
905     /* Search the table in a thread safe manner */
906     key = GateSwi_enter(NameServer_module->gate);
908     while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
909         != NULL) {
910         /* Do the comparison */
911         if (strcmp(tableEntry->name, name) == 0) {
912             break;
913         }
914     }
916     GateSwi_leave(NameServer_module->gate, key);
918     return (tableEntry);
921 /*
922  *  ======== ti_sdo_utils_NameServer_postInit ========
923  *  Function to be called during
924  *  1. module startup to complete the initialization of all static instances
925  *  2. instance_init to complete the initialization of a dynamic instance
926  *
927  *  The empty entries are added into the freeList. There can be non-empty
928  *  entries on statically created instances. The instance$static$init already
929  *  put those entries onto the nameList.
930  */
931 Int ti_sdo_utils_NameServer_postInit(ti_sdo_utils_NameServer_Object *obj)
933     UInt i;
934     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
935     ti_sdo_utils_NameServer_TableEntry *tableEntry;
936     String name;
938     name = obj->names;
939     for (i = 0; i < obj->numDynamic; i++) {
940         tableEntry = &(obj->table[i + obj->numStatic]);
942         /* Carve out some room for the dynamically added names */
943         tableEntry->name = name;
944         name += obj->maxNameLen;
946         /* Carve out some room for the dynamically added values */
947         if (obj->maxValueLen > sizeof(UInt32)) {
948             tableEntry->value = (UArg)((UInt32)obj->values +
949                     (i * obj->maxValueLen));
950             tableEntry->len   = obj->maxValueLen;
951         }
953         /* Put the entry onto the freeList */
954         List_put(freeList, (List_Elem *)(tableEntry));
955     }
957     return (0);