8298c91d271f996f07fe2805b1fdfcf81f350484
[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;
351     UInt16 cluster;
353     Error_init(&eb);
355     /* processor address mode determines cluster baseId */
356     switch (ti_sdo_utils_MultiProc_procAddrMode) {
357         case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
358             baseId = 0;
359             break;
361         case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
362             baseId = MultiProc_getBaseIdOfCluster();
363             break;
365         default:
366             Assert_isTrue(FALSE, 0);
367             break;
368     }
370     /*
371      *  Query all the processors.
372      */
373     if (procId == NULL) {
374         /* Query the local one first */
375         status = NameServer_getLocal(handle, name, value, len);
376         if (status == NameServer_E_NOTFOUND) {
377             /* To eliminate code if possible */
378             if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
379                 length = (UInt16)NameServer_module->nsRemoteHandle.length;
381                 for (i = 0; i < length; i++) {
382                     /* skip myself, local table already searched above */
383                     if ((baseId + i) == MultiProc_self()) {
384                         continue;
385                     }
386                     if (NameServer_module->nsRemoteHandle.elem[i] != NULL) {
387                         status = INameServerRemote_get(
388                                 NameServer_module->nsRemoteHandle.elem[i],
389                                 obj->name, name, value, len, NULL, &eb);
390                     }
391                     /* stop looking if found or encoutered fatal error */
392                     if ((status >= 0) || ((status != NameServer_E_NOTFOUND)
393                             && (status != NameServer_E_TIMEOUT))) {
394                         break;
395                     }
396                 }
397             }
398         }
399     }
400     else {
401         /*  Search the query list. It might contain the local proc
402          *  somewhere in the list.
403          */
404         status = NameServer_E_NOTFOUND;
405         cluster = MultiProc_getNumProcsInCluster();
407         for (i = 0; (procId[i] != MultiProc_INVALIDID) && (i < cluster); i++) {
408             if (procId[i] == MultiProc_self()) {
409                 /* check local */
410                 status = NameServer_getLocal(handle, name, value, len);
411             }
412             else if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
413                 index = procId[i] - baseId;
414                 /* check remote */
415                 if (NameServer_module->nsRemoteHandle.elem[index] != NULL) {
416                     status = INameServerRemote_get(
417                             NameServer_module->nsRemoteHandle.elem[index],
418                             obj->name, name, value, len, NULL, &eb);
419                 }
420             }
421             /* stop looking if found or encoutered fatal error */
422             if ((status >= 0) || ((status != NameServer_E_NOTFOUND)
423                     && (status != NameServer_E_TIMEOUT))) {
424                 break;
425             }
426         }
427     }
429     return (status);
432 /*
433  *  ======== NameServer_getHandle ========
434  *  Helper function to get a handle based on the instance name.
435  */
436 NameServer_Handle NameServer_getHandle(String instanceName)
438     ti_sdo_utils_NameServer_Object *obj;
439     IArg key;
440     Int i;
442     /* Search static instances */
443     for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
444         obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
445         if ((obj->name != NULL) &&
446             (strcmp(obj->name, instanceName) == 0)) {
447             return ((NameServer_Handle)obj);
448         }
449     }
451     /* Search dynamic instances (in a thread safe manner) */
452     key = GateSwi_enter(NameServer_module->gate);
454     obj = ti_sdo_utils_NameServer_Object_first();
455     while (obj != NULL) {
456         if ((obj->name != NULL) &&
457             (strcmp(obj->name, instanceName) == 0)) {
458             GateSwi_leave(NameServer_module->gate, key);
459             return ((NameServer_Handle)obj);
460         }
461         obj = ti_sdo_utils_NameServer_Object_next(obj);
462     }
463     GateSwi_leave(NameServer_module->gate, key);
465     return (NULL);
468 /*
469  *  ======== NameServer_getLocal ========
470  */
471 Int NameServer_getLocal(NameServer_Handle handle, String name, Ptr value,
472                         UInt32 *len)
474     ti_sdo_utils_NameServer_Object *obj =
475             (ti_sdo_utils_NameServer_Object *)handle;
476     IArg key;
477     ti_sdo_utils_NameServer_TableEntry *tableEntry;
479     key = GateSwi_enter(NameServer_module->gate);
481     /* search the local table */
482     tableEntry = NameServer_findLocal(obj, name);
484     if (tableEntry != NULL) {
485         /*
486          *  Found the entry.
487          *  If the table holds value (and not buffers) simply
488          *  copy into value and return
489          */
490         if (obj->maxValueLen == sizeof(UInt32)) {
491             memcpy((Ptr)value, &(tableEntry->value), sizeof(UInt32));
492         }
493         else {
494             Assert_isTrue((tableEntry->len <= *len), ti_sdo_utils_NameServer_A_invalidLen);
495             memcpy((Ptr)value, (Ptr)(tableEntry->value), tableEntry->len);
496         }
497         GateSwi_leave(NameServer_module->gate, key);
498         *len = tableEntry->len;
499         return (NameServer_S_SUCCESS);
500     }
502     GateSwi_leave(NameServer_module->gate, key);
504     /* Name not found locally. */
505     return (NameServer_E_NOTFOUND);
508 /*
509  *  ======== NameServer_getLocalUInt32 ========
510  *
511  */
512 Int NameServer_getLocalUInt32(NameServer_Handle handle, String name, Ptr value)
514     UInt32 len = sizeof(UInt32);
515     Int status;
517     status = NameServer_getLocal(handle, name, value, &len);
519     return (status);
522 /*
523  *  ======== NameServer_getUInt32 ========
524  */
525 Int NameServer_getUInt32(NameServer_Handle handle, String name,
526                          Ptr value, UInt16 remoteProcId[])
528     UInt32 len = sizeof(UInt32);
529     Int status;
531     status = NameServer_get(handle, name, value, &len, remoteProcId);
533     return (status);
536 /*  ======== NameServer_match ========
537  *  Currently only supporting 32-bit values.
538  */
539 Int NameServer_match(NameServer_Handle handle, String name, UInt32 *value)
541     ti_sdo_utils_NameServer_Object *obj =
542             (ti_sdo_utils_NameServer_Object *)handle;
543     Int len = 0;
544     Int foundLen = 0;
545     IArg key;
546     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
547     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
549     Assert_isTrue((sizeof(UInt32) == obj->maxValueLen),
550             ti_sdo_utils_NameServer_A_invalidLen);
552     key = GateSwi_enter(NameServer_module->gate);
554     /* Search the entire table and find the longest match */
555     while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
557         len = strlen(tableEntry->name);
559         /*
560          *  Only check if the name in the table is going to potentially be
561          *  a better match.
562          */
563         if (len > foundLen) {
564             if (strncmp(name, tableEntry->name, len) == 0) {
565                 *value = (UInt32)(tableEntry->value);
566                 foundLen = len;
567             }
568         }
569     }
571     GateSwi_leave(NameServer_module->gate, key);
573     /* The name was not found...return 0 characters matched*/
574     return (foundLen);
577 /*
578  *  ======== NameServer_remove ========
579  *  Remove a name/value pair.
580  */
581 Int NameServer_remove(NameServer_Handle handle, String name)
583     ti_sdo_utils_NameServer_Object *obj =
584             (ti_sdo_utils_NameServer_Object *)handle;
585     UInt i;
586     IArg key;
587     Int status = NameServer_E_INVALIDARG;
588     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
589     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
591     /* Skip over the static ones. They are always at the head of the list */
592     for (i = 0; i < obj->numStatic; i++) {
593         tableEntry = List_next(nameList, (List_Elem *)tableEntry);
594     }
596     /* Enter the gate. */
597     key = GateSwi_enter(NameServer_module->gate);
599     /* Loop through the list searching for the name */
600     while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
601         /* Remove it from the nameList and add to the freeList */
602         if (strcmp(tableEntry->name, name) == 0) {
603             NameServer_removeLocal(obj, tableEntry);
604             status = NameServer_S_SUCCESS;
605             break;
606         }
607     }
609     /* Leave the gate */
610     GateSwi_leave(NameServer_module->gate, key);
612     return (status);
615 /*
616  *  ======== NameServer_removeEntry ========
617  */
618 Int NameServer_removeEntry(NameServer_Handle handle, Ptr entry)
620     ti_sdo_utils_NameServer_Object *obj =
621             (ti_sdo_utils_NameServer_Object *)handle;
623     NameServer_removeLocal(obj, (ti_sdo_utils_NameServer_TableEntry *)entry);
625     return (NameServer_S_SUCCESS);
628 /*
629  *************************************************************************
630  *                       Instance functions
631  *************************************************************************
632  */
634 /*
635  *  ======== ti_sdo_utils_NameServer_Instance_init ========
636  */
637 Int ti_sdo_utils_NameServer_Instance_init(
638         ti_sdo_utils_NameServer_Object *obj, String name,
639         const ti_sdo_utils_NameServer_Params *params, Error_Block *eb)
641     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
642     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
644     obj->name          = name;
645     obj->numStatic     = 0;
646     obj->numDynamic    = params->maxRuntimeEntries;
647     obj->checkExisting = params->checkExisting;
648     obj->maxNameLen    = params->maxNameLen;
649     obj->table         = NULL;
650     obj->values        = NULL;
651     obj->names         = NULL;
652     obj->refCount      = 1;
654     if (params->tableHeap == NULL) {
655         obj->tableHeap = ti_sdo_utils_NameServer_Object_heap();
656     }
657     else {
658         obj->tableHeap = params->tableHeap;
659     }
661     /* minimum value of maxValueLen is sizeof(UInt32) */
662     if (params->maxValueLen < sizeof(UInt32)) {
663         obj->maxValueLen = sizeof(UInt32);
664     }
665     else {
666         obj->maxValueLen = params->maxValueLen;
667     }
669     /* Construct the free and name lists */
670     List_construct(List_struct(freeList), NULL);
671     List_construct(List_struct(nameList), NULL);
673     /* Allocate the entry table. */
674     if (obj->numDynamic != NameServer_ALLOWGROWTH) {
675         obj->table = Memory_alloc(obj->tableHeap,
676             sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic, 0, eb);
678         if (obj->table == NULL) {
679             return (3);
680         }
682         /*
683          * Allocate one big buffer that will be used for a copy of the values.
684          * Allocate not done when size == UInt32 because we copy the value
685          * to obj->values directly and do not need the extra space.
686          */
687         if (!(obj->maxValueLen == sizeof(UInt32))) {
688             obj->values = Memory_alloc(obj->tableHeap,
689                           obj->maxValueLen * obj->numDynamic, 0, eb);
691             if (obj->values == NULL) {
692                 return (2);
693             }
694         }
696         /* Allocate one big buffer that will be used for a copy of the names */
697         obj->names = Memory_alloc(obj->tableHeap,
698                          params->maxNameLen * obj->numDynamic, 0, eb);
699         if (obj->names == NULL) {
700             return (1);
701         }
703         /* Finish the rest of the object init */
704         NameServer_postInit(obj);
705     }
707     return(0);
710 /*
711  *  ======== ti_sdo_utils_NameServer_Instance_finalize ========
712  */
713 Void ti_sdo_utils_NameServer_Instance_finalize(
714         ti_sdo_utils_NameServer_Object *obj, Int status)
716     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
717     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
718     ti_sdo_utils_NameServer_TableEntry *tableEntry;
719     ti_sdo_utils_NameServer_TableEntry *tableEntryNext;
721     if (obj->numDynamic != NameServer_ALLOWGROWTH) {
722         if (obj->names != NULL) {
723             Memory_free(obj->tableHeap, obj->names,
724                         obj->maxNameLen * obj->numDynamic);
725         }
727         if (obj->values != NULL && !(obj->maxValueLen == sizeof(UInt32))) {
728             Memory_free(obj->tableHeap, obj->values,
729                         obj->maxValueLen * obj->numDynamic);
730         }
732         if (obj->table != NULL) {
733             Memory_free(obj->tableHeap, obj->table,
734                         sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic);
735         }
736     }
737     else {
738         tableEntryNext = List_next(nameList, NULL);
739         while (tableEntryNext != NULL) {
740             tableEntry = tableEntryNext;
741             tableEntryNext = List_next(nameList, (List_Elem*)tableEntryNext);
743             /* Free the value if not UInt32 */
744             if (!(obj->maxValueLen == sizeof(UInt32))) {
745                 Memory_free(obj->tableHeap, (Ptr)(tableEntry->value),
746                             obj->maxValueLen);
747             }
749             /* Free the name */
750             Memory_free(obj->tableHeap, tableEntry->name,
751                         strlen(tableEntry->name) + 1);
753             /* Free the entry */
754             Memory_free(obj->tableHeap, tableEntry,
755                         sizeof(ti_sdo_utils_NameServer_TableEntry));
756         }
757     }
759     List_destruct(List_struct(freeList));
760     List_destruct(List_struct(nameList));
767 /*
768  *  ======== ti_sdo_utils_NameServer_removeLocal ========
769  */
770 Void ti_sdo_utils_NameServer_removeLocal(ti_sdo_utils_NameServer_Object *obj,
771                              ti_sdo_utils_NameServer_TableEntry *entry)
773     IArg key;
774     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
775     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
777     /* Remove it from the nameList and add to the freeList or free it */
778     if (obj->numDynamic == NameServer_ALLOWGROWTH) {
780         key = GateSwi_enter(NameServer_module->gate);
781         List_remove(nameList, (List_Elem *)entry);
782         GateSwi_leave(NameServer_module->gate, key);
784         if (!(obj->maxValueLen == sizeof(UInt32))) {
785             Memory_free(obj->tableHeap, (Ptr)entry->value,
786                         obj->maxValueLen);
787         }
789         Memory_free(obj->tableHeap, entry->name,
790                     strlen(entry->name) + 1);
792         Memory_free(obj->tableHeap, entry,
793                     sizeof(ti_sdo_utils_NameServer_TableEntry));
794     }
795     else {
796         key = GateSwi_enter(NameServer_module->gate);
797         List_remove(nameList, (List_Elem *)entry);
798         GateSwi_leave(NameServer_module->gate, key);
800         List_put(freeList, (List_Elem *)entry);
801     }
804 /*
805  *  ======== ti_sdo_utils_NameServer_getKey ========
806  */
807 Ptr ti_sdo_utils_NameServer_getKey(ti_sdo_utils_NameServer_Object *obj,
808         UInt32 val)
810     IArg  key;
811     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
812     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
814     /* Need to assume the value length is sizeof(UInt32) */
815     Assert_isTrue(obj->maxValueLen == sizeof(UInt32), NULL);
817     key = GateSwi_enter(NameServer_module->gate);
819     while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
820         != NULL) {
821         /* Do the comparison */
822         if (tableEntry->value == val) {
823             break;
824         }
825     }
827     GateSwi_leave(NameServer_module->gate, key);
829     return (tableEntry);
833 /*
834  *************************************************************************
835  *                      Module functions
836  *************************************************************************
837  */
839 /*
840  *  ======== ti_sdo_utils_NameServer_Module_startup ========
841  */
842 Int ti_sdo_utils_NameServer_Module_startup( Int phase )
844     Int i;
845     ti_sdo_utils_NameServer_Object *obj;
847     /* Finish setting up the freeList */
848     for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
849         obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
850         if ((obj->numDynamic != 0) &&
851             (obj->numDynamic != NameServer_ALLOWGROWTH)) {
852             NameServer_postInit(obj);
853         }
854     }
856     return (Startup_DONE);
860 /*
861  *  ======== ti_sdo_utils_NameServer_isRegistered ========
862  */
863 Bool ti_sdo_utils_NameServer_isRegistered(UInt16 procId)
865     Bool registered;
866     UInt16 index;
868     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
869             ti_sdo_utils_NameServer_A_invArgument);
871     switch (ti_sdo_utils_MultiProc_procAddrMode) {
872         case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
873             index = procId;
874             break;
876         case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
877             index = procId - MultiProc_getBaseIdOfCluster();
878             break;
880         default:
881             Assert_isTrue(FALSE, 0);
882             break;
883     }
885     Assert_isTrue(index < NameServer_module->nsRemoteHandle.length,
886             ti_sdo_utils_NameServer_A_invArgument);
888     registered = (NameServer_module->nsRemoteHandle.elem[index] != NULL);
890     return (registered);
893 /*
894  *  ======== ti_sdo_utils_NameServer_registerRemoteDriver ========
895  */
896 Int ti_sdo_utils_NameServer_registerRemoteDriver(INameServerRemote_Handle
897         nsrHandle, UInt16 procId)
899     Int status;
900     UInt16 index;
901     UInt key;
903     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
904             ti_sdo_utils_NameServer_A_invArgument);
906     switch (ti_sdo_utils_MultiProc_procAddrMode) {
907         case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
908             index = procId;
909             break;
911         case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
912             index = procId - MultiProc_getBaseIdOfCluster();
913             break;
915         default:
916             Assert_isTrue(FALSE, NULL);
917             break;
918     }
920     Assert_isTrue(index < NameServer_module->nsRemoteHandle.length,
921             ti_sdo_utils_NameServer_A_invArgument);
923     key = Hwi_disable();
925     if (NameServer_module->nsRemoteHandle.elem[index] != NULL) {
926         status = NameServer_E_FAIL;
927     }
928     else {
929         NameServer_module->nsRemoteHandle.elem[index] = nsrHandle;
930         status = NameServer_S_SUCCESS;
931     }
933     Hwi_restore(key);
935     return (status);
938 /*
939  *  ======== ti_sdo_utils_NameServer_unregisterRemoteDriver ========
940  */
941 Void ti_sdo_utils_NameServer_unregisterRemoteDriver(UInt16 procId)
943     UInt16 index;
944     UInt key;
946     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
947             ti_sdo_utils_NameServer_A_invArgument);
949     switch (ti_sdo_utils_MultiProc_procAddrMode) {
950         case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
951             index = procId;
952             break;
954         case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
955             index = procId - MultiProc_getBaseIdOfCluster();
956             break;
958         default:
959             Assert_isTrue(FALSE, 0);
960             break;
961     }
963     Assert_isTrue(index < NameServer_module->nsRemoteHandle.length,
964             ti_sdo_utils_NameServer_A_invArgument);
966     key = Hwi_disable();
968     NameServer_module->nsRemoteHandle.elem[index] = NULL;
970     Hwi_restore(key);
973 /*
974  *************************************************************************
975  *                       Internal functions
976  *************************************************************************
977  */
979 /*
980  *  ======== ti_sdo_utils_NameServer_findLocal ========
981  *  Searches the local instance table.
982  */
983 ti_sdo_utils_NameServer_TableEntry *NameServer_findLocal(
984         ti_sdo_utils_NameServer_Object *obj, String name)
986     IArg  key;
987     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
989     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
991     /* Search the table in a thread safe manner */
992     key = GateSwi_enter(NameServer_module->gate);
994     while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
995         != NULL) {
996         /* Do the comparison */
997         if (strcmp(tableEntry->name, name) == 0) {
998             break;
999         }
1000     }
1002     GateSwi_leave(NameServer_module->gate, key);
1004     return (tableEntry);
1007 /*
1008  *  ======== ti_sdo_utils_NameServer_postInit ========
1009  *  Function to be called during
1010  *  1. module startup to complete the initialization of all static instances
1011  *  2. instance_init to complete the initialization of a dynamic instance
1012  *
1013  *  The empty entries are added into the freeList. There can be non-empty
1014  *  entries on statically created instances. The instance$static$init already
1015  *  put those entries onto the nameList.
1016  */
1017 Int ti_sdo_utils_NameServer_postInit(ti_sdo_utils_NameServer_Object *obj)
1019     UInt i;
1020     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
1021     ti_sdo_utils_NameServer_TableEntry *tableEntry;
1022     String name;
1024     name = obj->names;
1025     for (i = 0; i < obj->numDynamic; i++) {
1026         tableEntry = &(obj->table[i + obj->numStatic]);
1028         /* Carve out some room for the dynamically added names */
1029         tableEntry->name = name;
1030         name += obj->maxNameLen;
1032         /* Carve out some room for the dynamically added values */
1033         if (obj->maxValueLen > sizeof(UInt32)) {
1034             tableEntry->value = (UArg)((UInt32)obj->values +
1035                     (i * obj->maxValueLen));
1036             tableEntry->len   = obj->maxValueLen;
1037         }
1039         /* Put the entry onto the freeList */
1040         List_put(freeList, (List_Elem *)(tableEntry));
1041     }
1043     return (0);