f99fc3249999603503b355e74ac468436d677b6d
[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                              break;
375                         }
376                     }
377                 }
378             }
379         }
380     }
381     else {
382         /*
383          *  Search the query list. It might contain the local proc
384          *  somewhere in the list.
385          */
386         i = 0;
387         status = NameServer_E_NOTFOUND;
388         while (procId[i] != MultiProc_INVALIDID) {
389             if (procId[i] == MultiProc_self()) {
390                 /* Check local */
391                 status = NameServer_getLocal(handle, name, value, len);
392             }
393             else if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
394                 /* Check remote */
395                 if (NameServer_module->nsRemoteHandle[procId[i]] != NULL) {
396                     status = INameServerRemote_get(
397                              NameServer_module->nsRemoteHandle[procId[i]],
398                              obj->name, name, value, len, NULL, &eb);
399                 }
400             }
402             /* continue only if not found */
403             if ((status >= 0) ||
404                 ((status < 0) &&
405                 (status != NameServer_E_NOTFOUND))) {
406                  break;
407             }
408             else {
409                 i++;
411                 /* if we've queried all procs then exit */
412                 if (i == MultiProc_getNumProcsInCluster()) {
413                     break;
414                 }
415             }
416         }
417     }
419     return (status);
422 /*
423  *  ======== NameServer_getHandle ========
424  *  Helper function to get a handle based on the instance name.
425  */
426 NameServer_Handle NameServer_getHandle(String instanceName)
428     ti_sdo_utils_NameServer_Object *obj;
429     IArg key;
430     Int i;
432     /* Search static instances */
433     for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
434         obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
435         if ((obj->name != NULL) &&
436             (strcmp(obj->name, instanceName) == 0)) {
437             return ((NameServer_Handle)obj);
438         }
439     }
441     /* Search dynamic instances (in a thread safe manner) */
442     key = GateSwi_enter(NameServer_module->gate);
444     obj = ti_sdo_utils_NameServer_Object_first();
445     while (obj != NULL) {
446         if ((obj->name != NULL) &&
447             (strcmp(obj->name, instanceName) == 0)) {
448             GateSwi_leave(NameServer_module->gate, key);
449             return ((NameServer_Handle)obj);
450         }
451         obj = ti_sdo_utils_NameServer_Object_next(obj);
452     }
453     GateSwi_leave(NameServer_module->gate, key);
455     return (NULL);
458 /*
459  *  ======== NameServer_getLocal ========
460  */
461 Int NameServer_getLocal(NameServer_Handle handle, String name, Ptr value,
462                         UInt32 *len)
464     ti_sdo_utils_NameServer_Object *obj =
465             (ti_sdo_utils_NameServer_Object *)handle;
466     IArg key;
467     ti_sdo_utils_NameServer_TableEntry *tableEntry;
469     key = GateSwi_enter(NameServer_module->gate);
471     /* search the local table */
472     tableEntry = NameServer_findLocal(obj, name);
474     if (tableEntry != NULL) {
475         /*
476          *  Found the entry.
477          *  If the table holds value (and not buffers) simply
478          *  copy into value and return
479          */
480         if (obj->maxValueLen == sizeof(UInt32)) {
481             memcpy((Ptr)value, &(tableEntry->value), sizeof(UInt32));
482         }
483         else {
484             Assert_isTrue((tableEntry->len <= *len), ti_sdo_utils_NameServer_A_invalidLen);
485             memcpy((Ptr)value, (Ptr)(tableEntry->value), tableEntry->len);
486         }
487         GateSwi_leave(NameServer_module->gate, key);
488         *len = tableEntry->len;
489         return (NameServer_S_SUCCESS);
490     }
492     GateSwi_leave(NameServer_module->gate, key);
494     /* Name not found locally. */
495     return (NameServer_E_NOTFOUND);
498 /*
499  *  ======== NameServer_getLocalUInt32 ========
500  *
501  */
502 Int NameServer_getLocalUInt32(NameServer_Handle handle, String name, Ptr value)
504     UInt32 len = sizeof(UInt32);
505     Int status;
507     status = NameServer_getLocal(handle, name, value, &len);
509     return (status);
512 /*
513  *  ======== NameServer_getUInt32 ========
514  */
515 Int NameServer_getUInt32(NameServer_Handle handle, String name,
516                          Ptr value, UInt16 remoteProcId[])
518     UInt32 len = sizeof(UInt32);
519     Int status;
521     status = NameServer_get(handle, name, value, &len, remoteProcId);
523     return (status);
526 /*  ======== NameServer_match ========
527  *  Currently only supporting 32-bit values.
528  */
529 Int NameServer_match(NameServer_Handle handle, String name, UInt32 *value)
531     ti_sdo_utils_NameServer_Object *obj =
532             (ti_sdo_utils_NameServer_Object *)handle;
533     Int len = 0;
534     Int foundLen = 0;
535     IArg key;
536     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
537     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
539     Assert_isTrue((sizeof(UInt32) == obj->maxValueLen),
540             ti_sdo_utils_NameServer_A_invalidLen);
542     key = GateSwi_enter(NameServer_module->gate);
544     /* Search the entire table and find the longest match */
545     while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
547         len = strlen(tableEntry->name);
549         /*
550          *  Only check if the name in the table is going to potentially be
551          *  a better match.
552          */
553         if (len > foundLen) {
554             if (strncmp(name, tableEntry->name, len) == 0) {
555                 *value = (UInt32)(tableEntry->value);
556                 foundLen = len;
557             }
558         }
559     }
561     GateSwi_leave(NameServer_module->gate, key);
563     /* The name was not found...return 0 characters matched*/
564     return (foundLen);
567 /*
568  *  ======== NameServer_remove ========
569  *  Remove a name/value pair.
570  */
571 Int NameServer_remove(NameServer_Handle handle, String name)
573     ti_sdo_utils_NameServer_Object *obj =
574             (ti_sdo_utils_NameServer_Object *)handle;
575     UInt i;
576     IArg key;
577     Int status = NameServer_E_INVALIDARG;
578     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
579     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
581     /* Skip over the static ones. They are always at the head of the list */
582     for (i = 0; i < obj->numStatic; i++) {
583         tableEntry = List_next(nameList, (List_Elem *)tableEntry);
584     }
586     /* Enter the gate. */
587     key = GateSwi_enter(NameServer_module->gate);
589     /* Loop through the list searching for the name */
590     while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
591         /* Remove it from the nameList and add to the freeList */
592         if (strcmp(tableEntry->name, name) == 0) {
593             NameServer_removeLocal(obj, tableEntry);
594             status = NameServer_S_SUCCESS;
595             break;
596         }
597     }
599     /* Leave the gate */
600     GateSwi_leave(NameServer_module->gate, key);
602     return (status);
605 /*
606  *  ======== NameServer_removeEntry ========
607  */
608 Int NameServer_removeEntry(NameServer_Handle handle, Ptr entry)
610     ti_sdo_utils_NameServer_Object *obj =
611             (ti_sdo_utils_NameServer_Object *)handle;
613     NameServer_removeLocal(obj, (ti_sdo_utils_NameServer_TableEntry *)entry);
615     return (NameServer_S_SUCCESS);
618 /*
619  *************************************************************************
620  *                       Instance functions
621  *************************************************************************
622  */
624 /*
625  *  ======== ti_sdo_utils_NameServer_Instance_init ========
626  */
627 Int ti_sdo_utils_NameServer_Instance_init(
628         ti_sdo_utils_NameServer_Object *obj, String name,
629         const ti_sdo_utils_NameServer_Params *params, Error_Block *eb)
631     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
632     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
634     obj->name          = name;
635     obj->numStatic     = 0;
636     obj->numDynamic    = params->maxRuntimeEntries;
637     obj->checkExisting = params->checkExisting;
638     obj->maxNameLen    = params->maxNameLen;
639     obj->table         = NULL;
640     obj->values        = NULL;
641     obj->names         = NULL;
642     obj->refCount      = 1;
644     if (params->tableHeap == NULL) {
645         obj->tableHeap = ti_sdo_utils_NameServer_Object_heap();
646     }
647     else {
648         obj->tableHeap = params->tableHeap;
649     }
651     /* minimum value of maxValueLen is sizeof(UInt32) */
652     if (params->maxValueLen < sizeof(UInt32)) {
653         obj->maxValueLen = sizeof(UInt32);
654     }
655     else {
656         obj->maxValueLen = params->maxValueLen;
657     }
659     /* Construct the free and name lists */
660     List_construct(List_struct(freeList), NULL);
661     List_construct(List_struct(nameList), NULL);
663     /* Allocate the entry table. */
664     if (obj->numDynamic != NameServer_ALLOWGROWTH) {
665         obj->table = Memory_alloc(obj->tableHeap,
666             sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic, 0, eb);
668         if (obj->table == NULL) {
669             return (3);
670         }
672         /*
673          * Allocate one big buffer that will be used for a copy of the values.
674          * Allocate not done when size == UInt32 because we copy the value
675          * to obj->values directly and do not need the extra space.
676          */
677         if (!(obj->maxValueLen == sizeof(UInt32))) {
678             obj->values = Memory_alloc(obj->tableHeap,
679                           obj->maxValueLen * obj->numDynamic, 0, eb);
681             if (obj->values == NULL) {
682                 return (2);
683             }
684         }
686         /* Allocate one big buffer that will be used for a copy of the names */
687         obj->names = Memory_alloc(obj->tableHeap,
688                          params->maxNameLen * obj->numDynamic, 0, eb);
689         if (obj->names == NULL) {
690             return (1);
691         }
693         /* Finish the rest of the object init */
694         NameServer_postInit(obj);
695     }
697     return(0);
700 /*
701  *  ======== ti_sdo_utils_NameServer_Instance_finalize ========
702  */
703 Void ti_sdo_utils_NameServer_Instance_finalize(
704         ti_sdo_utils_NameServer_Object *obj, Int status)
706     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
707     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
708     ti_sdo_utils_NameServer_TableEntry *tableEntry;
709     ti_sdo_utils_NameServer_TableEntry *tableEntryNext;
711     if (obj->numDynamic != NameServer_ALLOWGROWTH) {
712         if (obj->names != NULL) {
713             Memory_free(obj->tableHeap, obj->names,
714                         obj->maxNameLen * obj->numDynamic);
715         }
717         if (obj->values != NULL && !(obj->maxValueLen == sizeof(UInt32))) {
718             Memory_free(obj->tableHeap, obj->values,
719                         obj->maxValueLen * obj->numDynamic);
720         }
722         if (obj->table != NULL) {
723             Memory_free(obj->tableHeap, obj->table,
724                         sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic);
725         }
726     }
727     else {
728         tableEntryNext = List_next(nameList, NULL);
729         while (tableEntryNext != NULL) {
730             tableEntry = tableEntryNext;
731             tableEntryNext = List_next(nameList, (List_Elem*)tableEntryNext);
733             /* Free the value if not UInt32 */
734             if (!(obj->maxValueLen == sizeof(UInt32))) {
735                 Memory_free(obj->tableHeap, (Ptr)(tableEntry->value),
736                             obj->maxValueLen);
737             }
739             /* Free the name */
740             Memory_free(obj->tableHeap, tableEntry->name,
741                         strlen(tableEntry->name) + 1);
743             /* Free the entry */
744             Memory_free(obj->tableHeap, tableEntry,
745                         sizeof(ti_sdo_utils_NameServer_TableEntry));
746         }
747     }
749     List_destruct(List_struct(freeList));
750     List_destruct(List_struct(nameList));
757 /*
758  *  ======== ti_sdo_utils_NameServer_removeLocal ========
759  */
760 Void ti_sdo_utils_NameServer_removeLocal(ti_sdo_utils_NameServer_Object *obj,
761                              ti_sdo_utils_NameServer_TableEntry *entry)
763     IArg key;
764     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
765     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
767     /* Remove it from the nameList and add to the freeList or free it */
768     if (obj->numDynamic == NameServer_ALLOWGROWTH) {
770         key = GateSwi_enter(NameServer_module->gate);
771         List_remove(nameList, (List_Elem *)entry);
772         GateSwi_leave(NameServer_module->gate, key);
774         if (!(obj->maxValueLen == sizeof(UInt32))) {
775             Memory_free(obj->tableHeap, (Ptr)entry->value,
776                         obj->maxValueLen);
777         }
779         Memory_free(obj->tableHeap, entry->name,
780                     strlen(entry->name) + 1);
782         Memory_free(obj->tableHeap, entry,
783                     sizeof(ti_sdo_utils_NameServer_TableEntry));
784     }
785     else {
786         key = GateSwi_enter(NameServer_module->gate);
787         List_remove(nameList, (List_Elem *)entry);
788         GateSwi_leave(NameServer_module->gate, key);
790         List_put(freeList, (List_Elem *)entry);
791     }
794 /*
795  *  ======== ti_sdo_utils_NameServer_getKey ========
796  */
797 Ptr ti_sdo_utils_NameServer_getKey(ti_sdo_utils_NameServer_Object *obj,
798         UInt32 val)
800     IArg  key;
801     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
802     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
804     /* Need to assume the value length is sizeof(UInt32) */
805     Assert_isTrue(obj->maxValueLen == sizeof(UInt32), NULL);
807     key = GateSwi_enter(NameServer_module->gate);
809     while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
810         != NULL) {
811         /* Do the comparison */
812         if (tableEntry->value == val) {
813             break;
814         }
815     }
817     GateSwi_leave(NameServer_module->gate, key);
819     return (tableEntry);
823 /*
824  *************************************************************************
825  *                      Module functions
826  *************************************************************************
827  */
829 /*
830  *  ======== ti_sdo_utils_NameServer_Module_startup ========
831  */
832 Int ti_sdo_utils_NameServer_Module_startup( Int phase )
834     Int i;
835     ti_sdo_utils_NameServer_Object *obj;
837     for (i = 0; i < ti_sdo_utils_MultiProc_numProcessors; i++) {
838         NameServer_module->nsRemoteHandle[i] = NULL;
839     }
841     /* Finish setting up the freeList */
842     for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
843         obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
844         if ((obj->numDynamic != 0) &&
845             (obj->numDynamic != NameServer_ALLOWGROWTH)) {
846             NameServer_postInit(obj);
847         }
848     }
850     return (Startup_DONE);
854 /*
855  *  ======== ti_sdo_utils_NameServer_isRegistered ========
856  */
857 Bool ti_sdo_utils_NameServer_isRegistered(UInt16 procId)
859     Bool registered;
861     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
862             ti_sdo_utils_NameServer_A_invArgument);
864     registered = (NameServer_module->nsRemoteHandle[procId] != NULL);
866     return (registered);
869 /*
870  *  ======== ti_sdo_utils_NameServer_registerRemoteDriver ========
871  */
872 Int ti_sdo_utils_NameServer_registerRemoteDriver(INameServerRemote_Handle nsrHandle,
873         UInt16 procId)
875     Int   status;
876     UInt key;
878     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
879             ti_sdo_utils_NameServer_A_invArgument);
881     key = Hwi_disable();
883     if (NameServer_module->nsRemoteHandle[procId] != NULL) {
884         status = NameServer_E_FAIL;
885     }
886     else {
887         NameServer_module->nsRemoteHandle[procId] = nsrHandle;
888         status = NameServer_S_SUCCESS;
889     }
891     Hwi_restore(key);
893     return (status);
896 /*
897  *  ======== ti_sdo_utils_NameServer_unregisterRemoteDriver ========
898  */
899 Void ti_sdo_utils_NameServer_unregisterRemoteDriver(UInt16 procId)
901     UInt key;
903     Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
904             ti_sdo_utils_NameServer_A_invArgument);
906     key = Hwi_disable();
908     NameServer_module->nsRemoteHandle[procId] = NULL;
910     Hwi_restore(key);
913 /*
914  *************************************************************************
915  *                       Internal functions
916  *************************************************************************
917  */
919 /*
920  *  ======== ti_sdo_utils_NameServer_findLocal ========
921  *  Searches the local instance table.
922  */
923 ti_sdo_utils_NameServer_TableEntry *NameServer_findLocal(
924         ti_sdo_utils_NameServer_Object *obj, String name)
926     IArg  key;
927     ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
929     List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
931     /* Search the table in a thread safe manner */
932     key = GateSwi_enter(NameServer_module->gate);
934     while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
935         != NULL) {
936         /* Do the comparison */
937         if (strcmp(tableEntry->name, name) == 0) {
938             break;
939         }
940     }
942     GateSwi_leave(NameServer_module->gate, key);
944     return (tableEntry);
947 /*
948  *  ======== ti_sdo_utils_NameServer_postInit ========
949  *  Function to be called during
950  *  1. module startup to complete the initialization of all static instances
951  *  2. instance_init to complete the initialization of a dynamic instance
952  *
953  *  The empty entries are added into the freeList. There can be non-empty
954  *  entries on statically created instances. The instance$static$init already
955  *  put those entries onto the nameList.
956  */
957 Int ti_sdo_utils_NameServer_postInit(ti_sdo_utils_NameServer_Object *obj)
959     UInt i;
960     List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
961     ti_sdo_utils_NameServer_TableEntry *tableEntry;
962     String name;
964     name = obj->names;
965     for (i = 0; i < obj->numDynamic; i++) {
966         tableEntry = &(obj->table[i + obj->numStatic]);
968         /* Carve out some room for the dynamically added names */
969         tableEntry->name = name;
970         name += obj->maxNameLen;
972         /* Carve out some room for the dynamically added values */
973         if (obj->maxValueLen > sizeof(UInt32)) {
974             tableEntry->value = (UArg)((UInt32)obj->values +
975                     (i * obj->maxValueLen));
976             tableEntry->len   = obj->maxValueLen;
977         }
979         /* Put the entry onto the freeList */
980         List_put(freeList, (List_Elem *)(tableEntry));
981     }
983     return (0);