f99fc3249999603503b355e74ac468436d677b6d
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)
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 == 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);
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 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);
420 }
422 /*
423 * ======== NameServer_getHandle ========
424 * Helper function to get a handle based on the instance name.
425 */
426 NameServer_Handle NameServer_getHandle(String instanceName)
427 {
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);
456 }
458 /*
459 * ======== NameServer_getLocal ========
460 */
461 Int NameServer_getLocal(NameServer_Handle handle, String name, Ptr value,
462 UInt32 *len)
463 {
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);
496 }
498 /*
499 * ======== NameServer_getLocalUInt32 ========
500 *
501 */
502 Int NameServer_getLocalUInt32(NameServer_Handle handle, String name, Ptr value)
503 {
504 UInt32 len = sizeof(UInt32);
505 Int status;
507 status = NameServer_getLocal(handle, name, value, &len);
509 return (status);
510 }
512 /*
513 * ======== NameServer_getUInt32 ========
514 */
515 Int NameServer_getUInt32(NameServer_Handle handle, String name,
516 Ptr value, UInt16 remoteProcId[])
517 {
518 UInt32 len = sizeof(UInt32);
519 Int status;
521 status = NameServer_get(handle, name, value, &len, remoteProcId);
523 return (status);
524 }
526 /* ======== NameServer_match ========
527 * Currently only supporting 32-bit values.
528 */
529 Int NameServer_match(NameServer_Handle handle, String name, UInt32 *value)
530 {
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);
565 }
567 /*
568 * ======== NameServer_remove ========
569 * Remove a name/value pair.
570 */
571 Int NameServer_remove(NameServer_Handle handle, String name)
572 {
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);
603 }
605 /*
606 * ======== NameServer_removeEntry ========
607 */
608 Int NameServer_removeEntry(NameServer_Handle handle, Ptr entry)
609 {
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);
616 }
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)
630 {
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);
698 }
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)
705 {
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));
751 }
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)
762 {
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 }
792 }
794 /*
795 * ======== ti_sdo_utils_NameServer_getKey ========
796 */
797 Ptr ti_sdo_utils_NameServer_getKey(ti_sdo_utils_NameServer_Object *obj,
798 UInt32 val)
799 {
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);
820 }
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 )
833 {
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);
851 }
854 /*
855 * ======== ti_sdo_utils_NameServer_isRegistered ========
856 */
857 Bool ti_sdo_utils_NameServer_isRegistered(UInt16 procId)
858 {
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);
867 }
869 /*
870 * ======== ti_sdo_utils_NameServer_registerRemoteDriver ========
871 */
872 Int ti_sdo_utils_NameServer_registerRemoteDriver(INameServerRemote_Handle nsrHandle,
873 UInt16 procId)
874 {
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);
894 }
896 /*
897 * ======== ti_sdo_utils_NameServer_unregisterRemoteDriver ========
898 */
899 Void ti_sdo_utils_NameServer_unregisterRemoteDriver(UInt16 procId)
900 {
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);
911 }
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)
925 {
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);
945 }
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)
958 {
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);
984 }