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