1 /*
2 * Copyright (c) 2012-2015 Texas Instruments Incorporated - http://www.ti.com
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * */
32 /*
33 * ======== NameServer.c ========
34 * Implementation of functions specified in NameServer.xdc.
35 */
37 /*
38 * The dynamic name/value table looks like the following. This approach allows
39 * each instance table to have different value and different name lengths.
40 * The names block is allocated on the create. The size of that block is
41 * (maxRuntimeEntries * maxNameLen). That block is sliced and diced up and
42 * given to each table entry.
43 * The same thing is done for the values block.
44 *
45 * names table values
46 * ------------- ------------- -------------
47 * | |<-\ | elem | /----->| |
48 * | | \-------| name | / | |
49 * | | | value |-/ | |
50 * | | | len | | |
51 * | |<-\ |-----------| | |
52 * | | \ | elem | | |
53 * | | \------| name | /------>| |
54 * | | | value |-/ | |
55 * ------------- | len | | |
56 * ------------- | |
57 * | |
58 * | |
59 * -------------
60 *
61 * There is an optimization for small values (e.g. <= sizeof(UInt32).
62 * In this case, there is no values block allocated. Instead the value
63 * field is used directly. This optimization occurs and is managed when
64 * obj->maxValueLen <= sizeof(UInt32).
65 *
66 * The static create is a little different. The static entries point directly
67 * to a name string (and value). Since it points directly to static items,
68 * this entries cannot be removed.
69 * If maxRuntimeEntries is non-zero, a names and values block is created.
70 * Here is an example of a table with 1 static entry and 2 dynamic entries
71 *
72 * -------------
73 * | elem |
74 * "myName" <-----------| name |----------> someValue
75 * | value |
76 * names | len | values
77 * ------------- ------------- -------------
78 * | |<-\ | elem | /----->| |
79 * | | \-------| name | / | |
80 * | | | value |-/ | |
81 * | | | len | | |
82 * | |<-\ |-----------| | |
83 * | | \ | elem | | |
84 * | | \------| name | /------>| |
85 * | | | value |-/ | |
86 * ------------- | len | | |
87 * ------------- | |
88 * | |
89 * | |
90 * -------------
91 *
92 * NameServer uses a freeList and nameList to maintain the empty
93 * and filled-in entries. So when a name/value pair is added, an entry
94 * is pulled off the freeList, filled-in and placed on the nameList.
95 * The reverse happens on a remove.
96 *
97 * For static adds, the entries are placed on the nameList statically.
98 *
99 * For dynamic creates, the freeList is populated in postInit and there are no
100 * entries placed on the nameList (this happens when the add is called).
101 */
103 /* below #define to eliminate strncpy depracation warning for win targets */
104 #define _CRT_SECURE_NO_DEPRECATE
106 #include <xdc/std.h>
107 #include <string.h>
108 #include <stdlib.h>
110 #include <xdc/runtime/Assert.h>
111 #include <xdc/runtime/System.h>
112 #include <xdc/runtime/Error.h>
113 #include <xdc/runtime/Memory.h>
114 #include <xdc/runtime/Startup.h>
116 #include <ti/sysbios/gates/GateSwi.h>
117 #include <ti/sysbios/hal/Hwi.h>
119 #include <ti/sdo/utils/List.h>
120 #include <ti/sdo/utils/INameServerRemote.h>
122 #include <ti/sdo/utils/_MultiProc.h>
123 #include <ti/sdo/utils/_NameServer.h>
125 #include "package/internal/NameServer.xdc.h"
127 #ifdef __ti__
128 #pragma FUNC_EXT_CALLED(NameServer_Params_init);
129 #pragma FUNC_EXT_CALLED(NameServer_add);
130 #pragma FUNC_EXT_CALLED(NameServer_addUInt32);
131 #pragma FUNC_EXT_CALLED(NameServer_create);
132 #pragma FUNC_EXT_CALLED(NameServer_delete);
133 #pragma FUNC_EXT_CALLED(NameServer_get);
134 #pragma FUNC_EXT_CALLED(NameServer_getHandle);
135 #pragma FUNC_EXT_CALLED(NameServer_getLocal);
136 #pragma FUNC_EXT_CALLED(NameServer_getLocalUInt32);
137 #pragma FUNC_EXT_CALLED(NameServer_getUInt32);
138 #pragma FUNC_EXT_CALLED(NameServer_match);
139 #pragma FUNC_EXT_CALLED(NameServer_remove);
140 #pragma FUNC_EXT_CALLED(NameServer_removeEntry);
141 #endif
143 /*
144 *************************************************************************
145 * Common Header Functions
146 *************************************************************************
147 */
149 /*
150 * ======== NameServer_Params_init ========
151 */
152 Void NameServer_Params_init(NameServer_Params *params)
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;
348 UInt16 baseId;
349 UInt16 length;
350 UInt16 index;
352 Error_init(&eb);
354 /* processor address mode determines cluster baseId */
355 switch (ti_sdo_utils_MultiProc_procAddrMode) {
356 case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
357 baseId = 0;
358 break;
360 case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
361 baseId = MultiProc_getBaseIdOfCluster();
362 break;
364 default:
365 Assert_isTrue(FALSE, NULL);
366 break;
367 }
369 /*
370 * Query all the processors.
371 */
372 if (procId == NULL) {
373 /* Query the local one first */
374 status = NameServer_getLocal(handle, name, value, len);
375 if (status == NameServer_E_NOTFOUND) {
376 /* To eliminate code if possible */
377 if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
378 length = (UInt16)NameServer_module->nsRemoteHandle.length;
380 for (i = 0; i < length; i++) {
381 /* skip myself, local table already searched above */
382 if ((baseId + i) == MultiProc_self()) {
383 continue;
384 }
385 if (NameServer_module->nsRemoteHandle.elem[i] != NULL) {
386 status = INameServerRemote_get(
387 NameServer_module->nsRemoteHandle.elem[i],
388 obj->name, name, value, len, NULL, &eb);
389 }
390 /* stop looking if found or encoutered fatal error */
391 if ((status >= 0) || ((status != NameServer_E_NOTFOUND)
392 && (status != NameServer_E_TIMEOUT))) {
393 break;
394 }
395 }
396 }
397 }
398 }
399 else {
400 /* Search the query list. It might contain the local proc
401 * somewhere in the list.
402 */
403 status = NameServer_E_NOTFOUND;
405 for (i = 0; procId[i] != MultiProc_INVALIDID; i++) {
406 if (procId[i] == MultiProc_self()) {
407 /* check local */
408 status = NameServer_getLocal(handle, name, value, len);
409 }
410 else if (ti_sdo_utils_NameServer_singleProcessor == FALSE) {
411 index = procId[i] - baseId;
412 /* check remote */
413 if (NameServer_module->nsRemoteHandle.elem[index] != NULL) {
414 status = INameServerRemote_get(
415 NameServer_module->nsRemoteHandle.elem[index],
416 obj->name, name, value, len, NULL, &eb);
417 }
418 }
419 /* stop looking if found or encoutered fatal error */
420 if ((status >= 0) || ((status != NameServer_E_NOTFOUND)
421 && (status != NameServer_E_TIMEOUT))) {
422 break;
423 }
424 }
425 }
427 return (status);
428 }
430 /*
431 * ======== NameServer_getHandle ========
432 * Helper function to get a handle based on the instance name.
433 */
434 NameServer_Handle NameServer_getHandle(String instanceName)
435 {
436 ti_sdo_utils_NameServer_Object *obj;
437 IArg key;
438 Int i;
440 /* Search static instances */
441 for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
442 obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
443 if ((obj->name != NULL) &&
444 (strcmp(obj->name, instanceName) == 0)) {
445 return ((NameServer_Handle)obj);
446 }
447 }
449 /* Search dynamic instances (in a thread safe manner) */
450 key = GateSwi_enter(NameServer_module->gate);
452 obj = ti_sdo_utils_NameServer_Object_first();
453 while (obj != NULL) {
454 if ((obj->name != NULL) &&
455 (strcmp(obj->name, instanceName) == 0)) {
456 GateSwi_leave(NameServer_module->gate, key);
457 return ((NameServer_Handle)obj);
458 }
459 obj = ti_sdo_utils_NameServer_Object_next(obj);
460 }
461 GateSwi_leave(NameServer_module->gate, key);
463 return (NULL);
464 }
466 /*
467 * ======== NameServer_getLocal ========
468 */
469 Int NameServer_getLocal(NameServer_Handle handle, String name, Ptr value,
470 UInt32 *len)
471 {
472 ti_sdo_utils_NameServer_Object *obj =
473 (ti_sdo_utils_NameServer_Object *)handle;
474 IArg key;
475 ti_sdo_utils_NameServer_TableEntry *tableEntry;
477 key = GateSwi_enter(NameServer_module->gate);
479 /* search the local table */
480 tableEntry = NameServer_findLocal(obj, name);
482 if (tableEntry != NULL) {
483 /*
484 * Found the entry.
485 * If the table holds value (and not buffers) simply
486 * copy into value and return
487 */
488 if (obj->maxValueLen == sizeof(UInt32)) {
489 memcpy((Ptr)value, &(tableEntry->value), sizeof(UInt32));
490 }
491 else {
492 Assert_isTrue((tableEntry->len <= *len), ti_sdo_utils_NameServer_A_invalidLen);
493 memcpy((Ptr)value, (Ptr)(tableEntry->value), tableEntry->len);
494 }
495 GateSwi_leave(NameServer_module->gate, key);
496 *len = tableEntry->len;
497 return (NameServer_S_SUCCESS);
498 }
500 GateSwi_leave(NameServer_module->gate, key);
502 /* Name not found locally. */
503 return (NameServer_E_NOTFOUND);
504 }
506 /*
507 * ======== NameServer_getLocalUInt32 ========
508 *
509 */
510 Int NameServer_getLocalUInt32(NameServer_Handle handle, String name, Ptr value)
511 {
512 UInt32 len = sizeof(UInt32);
513 Int status;
515 status = NameServer_getLocal(handle, name, value, &len);
517 return (status);
518 }
520 /*
521 * ======== NameServer_getUInt32 ========
522 */
523 Int NameServer_getUInt32(NameServer_Handle handle, String name,
524 Ptr value, UInt16 remoteProcId[])
525 {
526 UInt32 len = sizeof(UInt32);
527 Int status;
529 status = NameServer_get(handle, name, value, &len, remoteProcId);
531 return (status);
532 }
534 /* ======== NameServer_match ========
535 * Currently only supporting 32-bit values.
536 */
537 Int NameServer_match(NameServer_Handle handle, String name, UInt32 *value)
538 {
539 ti_sdo_utils_NameServer_Object *obj =
540 (ti_sdo_utils_NameServer_Object *)handle;
541 Int len = 0;
542 Int foundLen = 0;
543 IArg key;
544 ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
545 List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
547 Assert_isTrue((sizeof(UInt32) == obj->maxValueLen),
548 ti_sdo_utils_NameServer_A_invalidLen);
550 key = GateSwi_enter(NameServer_module->gate);
552 /* Search the entire table and find the longest match */
553 while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
555 len = strlen(tableEntry->name);
557 /*
558 * Only check if the name in the table is going to potentially be
559 * a better match.
560 */
561 if (len > foundLen) {
562 if (strncmp(name, tableEntry->name, len) == 0) {
563 *value = (UInt32)(tableEntry->value);
564 foundLen = len;
565 }
566 }
567 }
569 GateSwi_leave(NameServer_module->gate, key);
571 /* The name was not found...return 0 characters matched*/
572 return (foundLen);
573 }
575 /*
576 * ======== NameServer_remove ========
577 * Remove a name/value pair.
578 */
579 Int NameServer_remove(NameServer_Handle handle, String name)
580 {
581 ti_sdo_utils_NameServer_Object *obj =
582 (ti_sdo_utils_NameServer_Object *)handle;
583 UInt i;
584 IArg key;
585 Int status = NameServer_E_INVALIDARG;
586 ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
587 List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
589 /* Skip over the static ones. They are always at the head of the list */
590 for (i = 0; i < obj->numStatic; i++) {
591 tableEntry = List_next(nameList, (List_Elem *)tableEntry);
592 }
594 /* Enter the gate. */
595 key = GateSwi_enter(NameServer_module->gate);
597 /* Loop through the list searching for the name */
598 while ((tableEntry = List_next(nameList, (List_Elem*)tableEntry)) != NULL) {
599 /* Remove it from the nameList and add to the freeList */
600 if (strcmp(tableEntry->name, name) == 0) {
601 NameServer_removeLocal(obj, tableEntry);
602 status = NameServer_S_SUCCESS;
603 break;
604 }
605 }
607 /* Leave the gate */
608 GateSwi_leave(NameServer_module->gate, key);
610 return (status);
611 }
613 /*
614 * ======== NameServer_removeEntry ========
615 */
616 Int NameServer_removeEntry(NameServer_Handle handle, Ptr entry)
617 {
618 ti_sdo_utils_NameServer_Object *obj =
619 (ti_sdo_utils_NameServer_Object *)handle;
621 NameServer_removeLocal(obj, (ti_sdo_utils_NameServer_TableEntry *)entry);
623 return (NameServer_S_SUCCESS);
624 }
626 /*
627 *************************************************************************
628 * Instance functions
629 *************************************************************************
630 */
632 /*
633 * ======== ti_sdo_utils_NameServer_Instance_init ========
634 */
635 Int ti_sdo_utils_NameServer_Instance_init(
636 ti_sdo_utils_NameServer_Object *obj, String name,
637 const ti_sdo_utils_NameServer_Params *params, Error_Block *eb)
638 {
639 List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
640 List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
642 obj->name = name;
643 obj->numStatic = 0;
644 obj->numDynamic = params->maxRuntimeEntries;
645 obj->checkExisting = params->checkExisting;
646 obj->maxNameLen = params->maxNameLen;
647 obj->table = NULL;
648 obj->values = NULL;
649 obj->names = NULL;
650 obj->refCount = 1;
652 if (params->tableHeap == NULL) {
653 obj->tableHeap = ti_sdo_utils_NameServer_Object_heap();
654 }
655 else {
656 obj->tableHeap = params->tableHeap;
657 }
659 /* minimum value of maxValueLen is sizeof(UInt32) */
660 if (params->maxValueLen < sizeof(UInt32)) {
661 obj->maxValueLen = sizeof(UInt32);
662 }
663 else {
664 obj->maxValueLen = params->maxValueLen;
665 }
667 /* Construct the free and name lists */
668 List_construct(List_struct(freeList), NULL);
669 List_construct(List_struct(nameList), NULL);
671 /* Allocate the entry table. */
672 if (obj->numDynamic != NameServer_ALLOWGROWTH) {
673 obj->table = Memory_alloc(obj->tableHeap,
674 sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic, 0, eb);
676 if (obj->table == NULL) {
677 return (3);
678 }
680 /*
681 * Allocate one big buffer that will be used for a copy of the values.
682 * Allocate not done when size == UInt32 because we copy the value
683 * to obj->values directly and do not need the extra space.
684 */
685 if (!(obj->maxValueLen == sizeof(UInt32))) {
686 obj->values = Memory_alloc(obj->tableHeap,
687 obj->maxValueLen * obj->numDynamic, 0, eb);
689 if (obj->values == NULL) {
690 return (2);
691 }
692 }
694 /* Allocate one big buffer that will be used for a copy of the names */
695 obj->names = Memory_alloc(obj->tableHeap,
696 params->maxNameLen * obj->numDynamic, 0, eb);
697 if (obj->names == NULL) {
698 return (1);
699 }
701 /* Finish the rest of the object init */
702 NameServer_postInit(obj);
703 }
705 return(0);
706 }
708 /*
709 * ======== ti_sdo_utils_NameServer_Instance_finalize ========
710 */
711 Void ti_sdo_utils_NameServer_Instance_finalize(
712 ti_sdo_utils_NameServer_Object *obj, Int status)
713 {
714 List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
715 List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
716 ti_sdo_utils_NameServer_TableEntry *tableEntry;
717 ti_sdo_utils_NameServer_TableEntry *tableEntryNext;
719 if (obj->numDynamic != NameServer_ALLOWGROWTH) {
720 if (obj->names != NULL) {
721 Memory_free(obj->tableHeap, obj->names,
722 obj->maxNameLen * obj->numDynamic);
723 }
725 if (obj->values != NULL && !(obj->maxValueLen == sizeof(UInt32))) {
726 Memory_free(obj->tableHeap, obj->values,
727 obj->maxValueLen * obj->numDynamic);
728 }
730 if (obj->table != NULL) {
731 Memory_free(obj->tableHeap, obj->table,
732 sizeof(ti_sdo_utils_NameServer_TableEntry) * obj->numDynamic);
733 }
734 }
735 else {
736 tableEntryNext = List_next(nameList, NULL);
737 while (tableEntryNext != NULL) {
738 tableEntry = tableEntryNext;
739 tableEntryNext = List_next(nameList, (List_Elem*)tableEntryNext);
741 /* Free the value if not UInt32 */
742 if (!(obj->maxValueLen == sizeof(UInt32))) {
743 Memory_free(obj->tableHeap, (Ptr)(tableEntry->value),
744 obj->maxValueLen);
745 }
747 /* Free the name */
748 Memory_free(obj->tableHeap, tableEntry->name,
749 strlen(tableEntry->name) + 1);
751 /* Free the entry */
752 Memory_free(obj->tableHeap, tableEntry,
753 sizeof(ti_sdo_utils_NameServer_TableEntry));
754 }
755 }
757 List_destruct(List_struct(freeList));
758 List_destruct(List_struct(nameList));
759 }
765 /*
766 * ======== ti_sdo_utils_NameServer_removeLocal ========
767 */
768 Void ti_sdo_utils_NameServer_removeLocal(ti_sdo_utils_NameServer_Object *obj,
769 ti_sdo_utils_NameServer_TableEntry *entry)
770 {
771 IArg key;
772 List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
773 List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
775 /* Remove it from the nameList and add to the freeList or free it */
776 if (obj->numDynamic == NameServer_ALLOWGROWTH) {
778 key = GateSwi_enter(NameServer_module->gate);
779 List_remove(nameList, (List_Elem *)entry);
780 GateSwi_leave(NameServer_module->gate, key);
782 if (!(obj->maxValueLen == sizeof(UInt32))) {
783 Memory_free(obj->tableHeap, (Ptr)entry->value,
784 obj->maxValueLen);
785 }
787 Memory_free(obj->tableHeap, entry->name,
788 strlen(entry->name) + 1);
790 Memory_free(obj->tableHeap, entry,
791 sizeof(ti_sdo_utils_NameServer_TableEntry));
792 }
793 else {
794 key = GateSwi_enter(NameServer_module->gate);
795 List_remove(nameList, (List_Elem *)entry);
796 GateSwi_leave(NameServer_module->gate, key);
798 List_put(freeList, (List_Elem *)entry);
799 }
800 }
802 /*
803 * ======== ti_sdo_utils_NameServer_getKey ========
804 */
805 Ptr ti_sdo_utils_NameServer_getKey(ti_sdo_utils_NameServer_Object *obj,
806 UInt32 val)
807 {
808 IArg key;
809 ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
810 List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
812 /* Need to assume the value length is sizeof(UInt32) */
813 Assert_isTrue(obj->maxValueLen == sizeof(UInt32), NULL);
815 key = GateSwi_enter(NameServer_module->gate);
817 while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
818 != NULL) {
819 /* Do the comparison */
820 if (tableEntry->value == val) {
821 break;
822 }
823 }
825 GateSwi_leave(NameServer_module->gate, key);
827 return (tableEntry);
828 }
831 /*
832 *************************************************************************
833 * Module functions
834 *************************************************************************
835 */
837 /*
838 * ======== ti_sdo_utils_NameServer_Module_startup ========
839 */
840 Int ti_sdo_utils_NameServer_Module_startup( Int phase )
841 {
842 Int i;
843 ti_sdo_utils_NameServer_Object *obj;
845 /* Finish setting up the freeList */
846 for (i = 0; i < ti_sdo_utils_NameServer_Object_count(); i++) {
847 obj = ti_sdo_utils_NameServer_Object_get(NULL, i);
848 if ((obj->numDynamic != 0) &&
849 (obj->numDynamic != NameServer_ALLOWGROWTH)) {
850 NameServer_postInit(obj);
851 }
852 }
854 return (Startup_DONE);
855 }
858 /*
859 * ======== ti_sdo_utils_NameServer_isRegistered ========
860 */
861 Bool ti_sdo_utils_NameServer_isRegistered(UInt16 procId)
862 {
863 Bool registered;
864 UInt16 index;
866 Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
867 ti_sdo_utils_NameServer_A_invArgument);
869 switch (ti_sdo_utils_MultiProc_procAddrMode) {
870 case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
871 index = procId;
872 break;
874 case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
875 index = procId - MultiProc_getBaseIdOfCluster();
876 break;
878 default:
879 Assert_isTrue(FALSE, NULL);
880 break;
881 }
883 Assert_isTrue(index < NameServer_module->nsRemoteHandle.length,
884 ti_sdo_utils_NameServer_A_invArgument);
886 registered = (NameServer_module->nsRemoteHandle.elem[index] != NULL);
888 return (registered);
889 }
891 /*
892 * ======== ti_sdo_utils_NameServer_registerRemoteDriver ========
893 */
894 Int ti_sdo_utils_NameServer_registerRemoteDriver(INameServerRemote_Handle
895 nsrHandle, UInt16 procId)
896 {
897 Int status;
898 UInt16 index;
899 UInt key;
901 Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
902 ti_sdo_utils_NameServer_A_invArgument);
904 switch (ti_sdo_utils_MultiProc_procAddrMode) {
905 case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
906 index = procId;
907 break;
909 case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
910 index = procId - MultiProc_getBaseIdOfCluster();
911 break;
913 default:
914 Assert_isTrue(FALSE, NULL);
915 break;
916 }
918 Assert_isTrue(index < NameServer_module->nsRemoteHandle.length,
919 ti_sdo_utils_NameServer_A_invArgument);
921 key = Hwi_disable();
923 if (NameServer_module->nsRemoteHandle.elem[index] != NULL) {
924 status = NameServer_E_FAIL;
925 }
926 else {
927 NameServer_module->nsRemoteHandle.elem[index] = nsrHandle;
928 status = NameServer_S_SUCCESS;
929 }
931 Hwi_restore(key);
933 return (status);
934 }
936 /*
937 * ======== ti_sdo_utils_NameServer_unregisterRemoteDriver ========
938 */
939 Void ti_sdo_utils_NameServer_unregisterRemoteDriver(UInt16 procId)
940 {
941 UInt16 index;
942 UInt key;
944 Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors,
945 ti_sdo_utils_NameServer_A_invArgument);
947 switch (ti_sdo_utils_MultiProc_procAddrMode) {
948 case ti_sdo_utils_MultiProc_ProcAddrMode_Global:
949 index = procId;
950 break;
952 case ti_sdo_utils_MultiProc_ProcAddrMode_Cluster:
953 index = procId - MultiProc_getBaseIdOfCluster();
954 break;
956 default:
957 Assert_isTrue(FALSE, NULL);
958 break;
959 }
961 Assert_isTrue(index < NameServer_module->nsRemoteHandle.length,
962 ti_sdo_utils_NameServer_A_invArgument);
964 key = Hwi_disable();
966 NameServer_module->nsRemoteHandle.elem[index] = NULL;
968 Hwi_restore(key);
969 }
971 /*
972 *************************************************************************
973 * Internal functions
974 *************************************************************************
975 */
977 /*
978 * ======== ti_sdo_utils_NameServer_findLocal ========
979 * Searches the local instance table.
980 */
981 ti_sdo_utils_NameServer_TableEntry *NameServer_findLocal(
982 ti_sdo_utils_NameServer_Object *obj, String name)
983 {
984 IArg key;
985 ti_sdo_utils_NameServer_TableEntry *tableEntry = NULL;
987 List_Handle nameList = ti_sdo_utils_NameServer_Instance_State_nameList(obj);
989 /* Search the table in a thread safe manner */
990 key = GateSwi_enter(NameServer_module->gate);
992 while ((tableEntry = List_next(nameList, (List_Elem *)tableEntry))
993 != NULL) {
994 /* Do the comparison */
995 if (strcmp(tableEntry->name, name) == 0) {
996 break;
997 }
998 }
1000 GateSwi_leave(NameServer_module->gate, key);
1002 return (tableEntry);
1003 }
1005 /*
1006 * ======== ti_sdo_utils_NameServer_postInit ========
1007 * Function to be called during
1008 * 1. module startup to complete the initialization of all static instances
1009 * 2. instance_init to complete the initialization of a dynamic instance
1010 *
1011 * The empty entries are added into the freeList. There can be non-empty
1012 * entries on statically created instances. The instance$static$init already
1013 * put those entries onto the nameList.
1014 */
1015 Int ti_sdo_utils_NameServer_postInit(ti_sdo_utils_NameServer_Object *obj)
1016 {
1017 UInt i;
1018 List_Handle freeList = ti_sdo_utils_NameServer_Instance_State_freeList(obj);
1019 ti_sdo_utils_NameServer_TableEntry *tableEntry;
1020 String name;
1022 name = obj->names;
1023 for (i = 0; i < obj->numDynamic; i++) {
1024 tableEntry = &(obj->table[i + obj->numStatic]);
1026 /* Carve out some room for the dynamically added names */
1027 tableEntry->name = name;
1028 name += obj->maxNameLen;
1030 /* Carve out some room for the dynamically added values */
1031 if (obj->maxValueLen > sizeof(UInt32)) {
1032 tableEntry->value = (UArg)((UInt32)obj->values +
1033 (i * obj->maxValueLen));
1034 tableEntry->len = obj->maxValueLen;
1035 }
1037 /* Put the entry onto the freeList */
1038 List_put(freeList, (List_Elem *)(tableEntry));
1039 }
1041 return (0);
1042 }