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