CMSDK 2.0.1
Cross-platform C++ base library and SDK for the Psyclone AIOS platform
Loading...
Searching...
No Matches
ComponentMemory.cpp
Go to the documentation of this file.
1
8
9#include "ComponentMemory.h"
10#include "UnitTestFramework.h"
11
12namespace cmlabs {
13
15 mutex = NULL;
16 this->master = master;
17 header = NULL;
18 memorySize = 0;
19 port = 0;
20 serial = 0;
21}
22
24 if (mutex)
25 mutex->enter(5000, __FUNCTION__);
26 if (memorySize)
27 utils::CloseSharedMemorySegment((char*) header, memorySize);
28 header = NULL;
29 if (mutex)
30 mutex->leave();
31 delete(mutex);
32 mutex = NULL;
33}
34
35bool ComponentMemory::getMemoryUsage(uint64& alloc, uint64& usage) {
36 if (!mutex || !mutex->enter(5000, __FUNCTION__))
37 return false;
39
40 alloc = memorySize;
41 usage = header->usage;
42
43 mutex->leave();
44 return true;
45}
46
47bool ComponentMemory::addLocalPerformanceStats(std::list<PerfStats> &perfStats) {
48 if (!mutex || !mutex->enter(5000, __FUNCTION__))
49 return false;
51
52 PerfStats stats;
54 for (uint32 n=0; n<=header->maxID; n++) {
55 if (info = GETCOMPDATA(header, n)) {
56 memset(&stats, 0, sizeof(PerfStats));
57 stats.compID = n;
58 stats.spaceID = info->procID;
59 stats.nodeID = info->nodeID;
60 stats.type = info->type;
61 stats.status = info->status;
62 stats.currentCPUTicks = info->stats.usageCPUTicks;
63 stats.currentMemoryBytes = info->size;
64 stats.totalInputBytes = info->stats.msgInBytes;
65 stats.totalInputCount = info->stats.msgInCount;
66 stats.totalOutputBytes = info->stats.msgOutBytes;
67 stats.totalOutputCount = info->stats.msgOutCount;
68 stats.runCount = info->stats.runCount;
69 //stats.totalQueueBytes = 0;
70 //stats.totalQueueCount = 0;
71 stats.currentRunStartTime = info->stats.currentRunStartTime;
72 stats.firstRunStartTime = info->stats.firstRunStartTime;
73 stats.totalCycleCount = info->stats.cycleCount;
74 stats.totalRunCount = info->stats.runCount;
75 stats.migrationCount = info->stats.migrationCount;
76 perfStats.push_back(stats);
77 }
78 }
79 mutex->leave();
80 return true;
81}
82
84 std::vector<ComponentInfoStruct>* list = getAllComponents();
85 if (!list)
86 return "No components registered";
87 else if (!list->size()) {
88 delete(list);
89 return "No components registered";
90 }
91
92 std::string str = utils::StringFormat("Components count %u intcount %u indexSize %u maxID %u memsize %u memuse %u\n",
93 list->size(), header->count, header->indexSize, header->maxID, header->size, header->usage);
94 std::vector<ComponentInfoStruct>::iterator i = list->begin(), e = list->end();
95 while (i != e) {
96 str += utils::StringFormat("Comp %u: '%s' node %u proc %u type %u, %u params %u data %u runs %u msgIn %u msgOut\n",
97 (*i).id, (*i).name, (*i).nodeID, (*i).procID, (*i).type, (*i).paramCount, (*i).dataCount,
98 (*i).stats.runCount, (*i).stats.msgInCount, (*i).stats.msgOutCount);
99 i++;
100 }
101
102 delete(list);
103 return str;
104}
105
106
107std::string ComponentMemory::toXML(bool stats) {
108 std::vector<ComponentInfoStruct>* list = getAllComponents();
109 if (!list)
110 return "<components count=\"0\" />\n";
111 else if (!list->size()) {
112 delete(list);
113 return "<components count=\"0\" />\n";
114 }
115
116 std::string str = utils::StringFormat("<components count=\"%u\" indexsize=\"%u\" maxid=\"%u\" memsize=\"%u\" memuse=\"%u\">\n",
117 header->count, header->indexSize, header->maxID, header->size, header->usage);
118 std::vector<ComponentInfoStruct>::iterator i = list->begin(), e = list->end();
119 while (i != e) {
120 str += (*i).toXML(stats);
121 i++;
122 }
123 delete(list);
124 str += "</components>\n";
125 return str;
126}
127
128
129std::vector<ComponentInfoStruct>* ComponentMemory::getAllComponents() {
130 std::vector<ComponentInfoStruct>* list = new std::vector<ComponentInfoStruct>;
131 if (!mutex || !mutex->enter(5000, __FUNCTION__))
132 return list;
134
136 for (uint32 n=0; n<=header->maxID; n++) {
137 if (info = GETCOMPDATA(header, n))
138 list->push_back(*info);
139 }
140 mutex->leave();
141 return list;
142}
143
144std::vector<ComponentInfoStruct>* ComponentMemory::getAllLocalComponents() {
145 std::vector<ComponentInfoStruct>* list = new std::vector<ComponentInfoStruct>;
146 if (!mutex || !mutex->enter(5000, __FUNCTION__))
147 return list;
149
151 for (uint32 n=0; n<=header->maxID; n++) {
152 if ((info = GETCOMPDATA(header, n)) && (info->nodeID == master->getNodeID()))
153 list->push_back(*info);
154 }
155 mutex->leave();
156 return list;
157}
158
159std::vector<ComponentInfoStruct>* ComponentMemory::getAllLocalComponents(uint8 type) {
160 std::vector<ComponentInfoStruct>* list = new std::vector<ComponentInfoStruct>;
161 if (!mutex || !mutex->enter(5000, __FUNCTION__))
162 return list;
164
166 for (uint32 n=0; n<=header->maxID; n++) {
167 if ((info = GETCOMPDATA(header, n)) && (info->nodeID == master->getNodeID()) && (info->type == type))
168 list->push_back(*info);
169 }
170 mutex->leave();
171 return list;
172}
173
174std::vector<ComponentInfoStruct>* ComponentMemory::getAllModules() {
175 std::vector<ComponentInfoStruct>* list = new std::vector<ComponentInfoStruct>;
176 if (!mutex || !mutex->enter(5000, __FUNCTION__))
177 return list;
179
181 for (uint32 n=0; n<=header->maxID; n++) {
182 if ((info = GETCOMPDATA(header, n)) && (info->nodeID == master->getNodeID())
183 && ( (info->type == COMP_INTERNAL) || (info->type == COMP_EXTERNAL) ) )
184 list->push_back(*info);
185 }
186 mutex->leave();
187 return list;
188}
189
190std::vector<ComponentInfoStruct>* ComponentMemory::getAllCatalogs() {
191 std::vector<ComponentInfoStruct>* list = new std::vector<ComponentInfoStruct>;
192 if (!mutex || !mutex->enter(5000, __FUNCTION__))
193 return list;
195
197 for (uint32 n=0; n<=header->maxID; n++) {
198 if ((info = GETCOMPDATA(header, n)) && (info->nodeID == master->getNodeID())
199 && ( (info->type == COMP_WHITEBOARD) || (info->type == COMP_CATALOG) ) )
200 list->push_back(*info);
201 }
202 mutex->leave();
203 return list;
204}
205
206bool ComponentMemory::create(uint32 indexSize) {
207 serial = master->incrementComponentShmemSerial();
208 port = master->port;
209
210 mutex = new utils::Mutex(utils::StringFormat("PsycloneComponentMemoryMutex_%u", port).c_str(), true);
211 if (!mutex->enter(5000, __FUNCTION__))
212 return false;
213
214 // add initial 256b average per component for parameters and data.
215 memorySize = sizeof(ComponentMemoryStruct) + indexSize * (sizeof(uint64) + sizeof(ComponentInfoStruct) + 256);
216
217 //header = (ComponentMemoryStruct*) utils::OpenSharedMemorySegment(utils::StringFormat("PsycloneComponentMemory_%u_%u", port, serial).c_str(), memorySize);
218 //if (header) {
219 // utils::CloseSharedMemorySegment((char*)header, memorySize);
220 // LogPrint(0,LOG_SYSTEM,2,"ComponentMemory removing stale shared memory (%u/%u)...", port, serial);
221 //}
222
223 header = (ComponentMemoryStruct*) utils::CreateSharedMemorySegment(utils::StringFormat("PsycloneComponentMemory_%u_%u", port, serial).c_str(), memorySize, true);
224 if (!header) {
225 mutex->leave();
226 return false;
227 }
228 memset(header, 0, (size_t)memorySize);
229 header->size = memorySize;
230 header->cid = COMPONENTMEMORYID;
231 header->createdTime = GetTimeNow();
232 header->indexSize = indexSize;
233 header->usage = sizeof(ComponentMemoryStruct) + (indexSize * sizeof(uint64));
234 // this->port = port;
235 master->setComponentShmemSize(memorySize);
236 mutex->leave();
237 return true;
238}
239
241 serial = master->getComponentShmemSerial();
242 uint64 size = master->getComponentShmemSize();
243 this->port = master->port;
244
245 bool createdMutex = false;
246 if (!mutex) {
247 mutex = new utils::Mutex(utils::StringFormat("PsycloneComponentMemoryMutex_%u", port).c_str());
248 createdMutex = true;
249 if (!mutex->enter(5000, __FUNCTION__))
250 return false;
251 }
252
253 ComponentMemoryStruct* newHeader = (ComponentMemoryStruct*) utils::OpenSharedMemorySegment(utils::StringFormat("PsycloneComponentMemory_%u_%u", port, serial).c_str(), size);
254 if (!newHeader) {
255 if (createdMutex)
256 mutex->leave();
257 return false;
258 }
259 if (newHeader->cid != COMPONENTMEMORYID) {
260 utils::CloseSharedMemorySegment((char*)newHeader, size);
261 if (createdMutex)
262 mutex->leave();
263 return false;
264 }
265
266 memorySize = size;
267 if (header)
268 utils::CloseSharedMemorySegment((char*)header, header->size);
269 header = newHeader;
270 if (createdMutex)
271 mutex->leave();
272 // else leave mutex locked as we are calling from within the object
273 return true;
274}
275
276
277
278
279bool ComponentMemory::resize(uint64 newMemorySize) {
280
281 if (newMemorySize > 100000000) {
282 LogPrint(0,LOG_MEMORY,0,"Memory Error: Component Memory requested size %s denied...", utils::BytifySize((double)newMemorySize).c_str());
283 return false;
284 }
285 else if (newMemorySize > 50000000) {
286 LogPrint(0,LOG_MEMORY,1,"Memory Warning: Component Memory now %s...", utils::BytifySize((double)newMemorySize).c_str());
287 }
288
289 serial = master->incrementComponentShmemSerial();
290
291 if (!mutex || !mutex->enter(5000, __FUNCTION__))
292 return false;
293
294 //ComponentMemoryStruct* newHeader = (ComponentMemoryStruct*) utils::OpenSharedMemorySegment(utils::StringFormat("PsycloneComponentMemory_%u_%u", port, serial).c_str(), newMemorySize);
295 //if (newHeader) {
296 // utils::CloseSharedMemorySegment((char*)newHeader, newMemorySize);
297 // LogPrint(0,LOG_MEMORY,2,"ComponentMemory removing stale shared memory (%u/%u)...", port, serial);
298 //}
299
300 ComponentMemoryStruct* newHeader = (ComponentMemoryStruct*) utils::CreateSharedMemorySegment(utils::StringFormat("PsycloneComponentMemory_%u_%u", port, serial).c_str(), newMemorySize, true);
301 if (!newHeader) {
302 mutex->leave();
303 return false;
304 }
305 memcpy(newHeader, header, (size_t)header->usage);
306 newHeader->size = newMemorySize;
307
308 utils::CloseSharedMemorySegment((char*)header, memorySize);
309 header = newHeader;
310 memorySize = newMemorySize;
311 master->setComponentShmemSize(memorySize);
312// utils::Sleep(10);
313 mutex->leave();
314 return true;
315}
316
317bool ComponentMemory::resizeIndex(uint32 newIndexSize) {
318
319 int32 difSize = (newIndexSize - header->indexSize) * sizeof(uint64);
320 if (difSize <= 0)
321 return true;
322 if ((uint32)difSize > header->size - header->usage)
323 if (!resize(memorySize * 2))
324 return false;
325
326 //LogPrint(0, 0, 0, "Component list before resizeIndex\n%s...", printFriendly().c_str());
327
328 uint32 oldDataOffset = sizeof(ComponentMemoryStruct) + (header->indexSize*sizeof(uint64));
329 uint32 newDataOffset = sizeof(ComponentMemoryStruct) + (newIndexSize*sizeof(uint64));
330 memmove(((char*)header) + newDataOffset, ((char*)header) + oldDataOffset, (size_t)(header->usage - oldDataOffset));
331 memset(((char*)header) + oldDataOffset, 0, newDataOffset - oldDataOffset);
332
333 header->indexSize = newIndexSize;
334 header->usage += newDataOffset - oldDataOffset;
335
336 //LogPrint(0, 0, 0, "Component list after resizeIndex\n%s...", printFriendly().c_str());
337 return true;
338}
339
340bool ComponentMemory::growComponent(uint32 id, uint64 addSize) {
341 ComponentInfoStruct* info = GETCOMPDATA(header,id);
342 if (!info)
343 return false;
344 return resizeComponent(id, info->size + addSize);
345}
346
347bool ComponentMemory::resizeComponent(uint32 id, uint64 newSize) {
348 ComponentInfoStruct* info = NULL;
349
350 uint64 difSize;
351 uint64* index = GETCOMPOFFSETP(header,id);
352 if (!*index) {
353 // we are inserting a new component
354 difSize = newSize;
355 }
356 else {
357 info = GETCOMPDATA(header,id);
358 if (info->id != id)
359 return false;
360 if (info->size > newSize)
361 return true;
362 difSize = newSize - info->size;
363 }
364 if (header->size - header->usage < difSize) {
365 if (!resize(memorySize * 2))
366 return false;
367 return resizeComponent(id, newSize);
368 }
369
370 uint32 nextID = 0;
371 uint32 n;
372 uint64* i = index + 1;
373 for (n=id+1; n<=header->maxID; n++, i++) {
374 if (*i) {
375 nextID = n;
376 break;
377 }
378 }
379
380 // shift qID > id up by difsize
381 if (nextID) {
382 // Push every subsequent component up by difSize
383 uint64 oldOffset = *i;
384 char* data = (char*)GETCOMPDATA(header,nextID);
385 if (!data) {
386 LogPrint(0, LOG_MEMORY, 0, "Couldn't shift component %u memory when inserting component %u...", nextID, id);
387 return false;
388 }
389 // Bytes from nextID's block to the end of used data. Offsets are relative
390 // to (header + indexSize*8) while usage is header-relative, so convert the
391 // offset before subtracting (the old code over-copied by indexSize*8 bytes,
392 // which could write past the segment end when nearly full).
393 uint64 nextStart = (header->indexSize * sizeof(uint64)) + oldOffset;
394 uint64 sizeMove = header->usage - nextStart;
395 memmove(data+difSize, data, (size_t)sizeMove);
396 // Adjust indexes
397 for (n=nextID; n<=header->maxID; n++, i++) {
398 if (*i) {
399 // printf("Moving index %u offset %u '%s' by %u\n", n, *i, (GETCOMPDATA(header, n))->name, difSize);
400 *i += difSize;
401 }
402 }
403
404 if (!info) {
405 GETCOMPOFFSET(header, id) = oldOffset;
406 info = (ComponentInfoStruct*) data;
407 memset(info, 0, sizeof(ComponentInfoStruct));
408 info->id = id;
409 info->createdTime = info->lastUpdateTime = GetTimeNow();
410 }
411
412 }
413 else if (!info) {
414 GETCOMPOFFSET(header,id) = header->usage - (header->indexSize * sizeof(uint64));
415 info = GETCOMPDATA(header, id);
416 memset(info, 0, sizeof(ComponentInfoStruct));
417 info->id = id;
418 info->createdTime = info->lastUpdateTime = GetTimeNow();
419 }
420
421 info->size = newSize;
422 header->usage += difSize;
423 return true;
424}
425
426
427
428
429
430
431
432
433
434// ************************************************************************************************
435
437 if (!mutex || !mutex->enter(5000, __FUNCTION__))
438 return false;
440 if (id >= header->indexSize) {
441 mutex->leave();
442 return false;
443 }
444 ComponentInfoStruct* info = GETCOMPDATA(header, id);
445 if (!info || (info->syncStatus < 1)) {
446 mutex->leave();
447 return false;
448 }
449 if (!info->type)
450 info->syncStatus = 2;
451 else
452 info->syncStatus = 3;
453 mutex->leave();
454 return true;
455}
456
458 if (!mutex || !mutex->enter(5000, __FUNCTION__))
459 return false;
461 if (id >= header->indexSize) {
462 mutex->leave();
463 return false;
464 }
465 ComponentInfoStruct* info = GETCOMPDATA(header, id);
466 if (!info || (info->syncStatus != 1)) {
467 mutex->leave();
468 return false;
469 }
470 info->syncStatus = 0;
471 info->type = 0;
472 info->nodeID = 0;
473 info->procID = 0;
474 info->createdTime = 0;
475 mutex->leave();
476 return true;
477}
478
480 std::vector<ComponentInfoStruct>* list = getAllComponents();
481 if (!list)
482 return true;
483 else if (!list->size()) {
484 delete(list);
485 return true;
486 }
487
488 std::vector<ComponentInfoStruct>::iterator i = list->begin(), e = list->end();
489 while (i != e) {
490 msg->setString((*i).id, "component", (*i).name);
491 i++;
492 }
493 delete(list);
494 return true;
495}
496
498 std::vector<ComponentInfoStruct>* list = getAllComponents();
499 if (!list)
500 return true;
501 else if (!list->size()) {
502 delete(list);
503 return true;
504 }
505
506 uint32 n = 0;
507 std::vector<ComponentInfoStruct>::iterator i = list->begin(), e = list->end();
508 while (i != e) {
509 if (!(*i).writeToMsg(n, msg)) {
510 delete(list);
511 return false;
512 }
513 i++;
514 n++;
515 }
516 delete(list);
517 return true;
518}
519
521 int64 n = 0;
522 uint16 id, nodeID, procID;
523 uint8 type, policy, selfTrigger;
524 const char* name;
525 uint64 time, size;
526 uint32 exID;
527 while (
528 (id = (uint16)msg->getInt(n, "ID")) &&
529 (type = (uint8)msg->getInt(n, "Type")) &&
530 (size = (uint64)msg->getInt(n, "Size")) &&
531 (nodeID = (uint16)msg->getInt(n, "NodeID")) &&
532 (procID = (uint16)msg->getInt(n, "ProcID")) &&
533 (name = msg->getString(n, "Name")) &&
534 (time = msg->getTime(n, "CreatedTime"))) {
535 policy = (uint8)msg->getInt(n, "Policy");
536 selfTrigger = (uint8)msg->getInt(n, "SelfTrigger");
537 if (!createComponent(id, type, policy, selfTrigger, name, size, nodeID, procID, time, exID))
538 return false;
540 n++;
541 }
542 return true;
543}
544
545// Static
546bool ComponentMemory::createComponent(uint32 id, uint8 type, uint8 policy, uint8 selfTrigger, const char* name, uint64 size, uint16 nodeID, uint16 procID, uint64 time, uint32& existingID) {
547
548 existingID = 0;
549 if (!mutex || !mutex->enter(5000, __FUNCTION__))
550 return false;
552
553 if (getComponentID(name, existingID) && (id != existingID)) {
554 mutex->leave();
555 return false;
556 }
557
558 if (id >= header->indexSize)
559 resizeIndex(header->indexSize + id + 1024);
560
561 ComponentInfoStruct* info = GETCOMPDATA(header, id);
562
563 if (info) {
564 if (master->getNodeID() == nodeID)
565 LogPrint(0, LOG_MEMORY, 1, "Updating local component %u (proc %u)...", id, procID);
566 else
567 LogPrint(0, LOG_MEMORY, 1, "Updating remote component %u (node %u proc %u)...", id, nodeID, procID);
568 if ((stricmp(name, info->name) != 0) ||
569 ((nodeID != info->nodeID) && (info->nodeID)) ||
570 ((procID != info->procID) && (info->procID)) ) {
571 mutex->leave();
572 return false;
573 }
574 info->type = type;
575 info->policy = policy;
576 info->selfTrigger = selfTrigger;
577 info->nodeID = nodeID;
578 info->procID = procID;
579 if (size > info->size)
580 if (!resizeComponent(id, size + sizeof(ComponentInfoStruct))) {
581 mutex->leave();
582 return false;
583 }
584 }
585 else {
586 if (master->getNodeID() == nodeID)
587 LogPrint(0, LOG_MEMORY, 2, "Creating new local component %u (proc %u)...", id, procID);
588 else
589 LogPrint(0, LOG_MEMORY, 2, "Registering remote component %u (node %u proc %u)...", id, nodeID, procID);
590 if (!resizeComponent(id, size + sizeof(ComponentInfoStruct))) {
591 mutex->leave();
592 return false;
593 }
594 info = GETCOMPDATA(header, id);
595 info->type = type;
596 info->policy = policy;
597 info->selfTrigger = selfTrigger;
598 info->nodeID = nodeID;
599 info->procID = procID;
600 if (time)
601 info->createdTime = time;
602 else
603 info->createdTime = GetTimeNow();
604 header->count++;
605 utils::strcpyavail(info->name, name, MAXKEYNAMELEN-1, false);
606 }
607
608 if (id > header->maxID)
609 header->maxID = id;
610
611 if (info->syncStatus < 1)
612 info->syncStatus = 1;
613
614 // LogPrint(0, 0, 0, "New component list\n%s...", printFriendly().c_str());
615
616 // Do not unlock the data, ComponentData destructor will do this
617 mutex->leave();
618 return true;
619}
620
621// static
622bool ComponentMemory::addComponentStats(uint32 cid, uint8 status, uint64 usageCPUTicks, DataMessage* inputMsg,
623 DataMessage* outputMsg, uint32 runCount, uint32 cycleCount) {
624 if (!mutex || !mutex->enter(5000, __FUNCTION__))
625 return false;
627
628 if (cid >= header->indexSize) {
629 mutex->leave();
630 return false;
631 }
632
633 uint32 size = 0;
634 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
635 if (!info) {
636 mutex->leave();
637 return false;
638 }
639
640 info->status = status;
641 info->stats.time = GetTimeNow();
642 if (status == COMPSTATUS_STARTING) {
643 info->stats.currentRunStartTime = info->stats.time;
644 if (!info->stats.firstRunStartTime)
645 info->stats.firstRunStartTime = info->stats.time;
646 }
647 info->stats.cycleCount += cycleCount;
648 info->stats.runCount += runCount;
649 info->stats.usageCPUTicks += usageCPUTicks;
650 DataMessage* draft;
651 if (inputMsg) {
652 info->stats.msgInCount++;
653 info->stats.msgInBytes += inputMsg->getSize();
654 // Circular ring: write the newest draft to the head slot and advance the
655 // head, instead of memmove-shifting the whole 10-deep ring (9*DRAFTMSGSIZE
656 // = 36KB) down by one slot on every message. Readers (toXML, PsyProbe)
657 // iterate all slots, so slot order doesn't matter to them.
658 char* inSlot = info->stats.recentInMsg + ((info->stats.recentInPos % 10) * DRAFTMSGSIZE);
659 if (inputMsg->data->size < DRAFTMSGSIZE)
660 memcpy(inSlot, inputMsg->data, inputMsg->data->size);
661 else {
662 draft = new DataMessage(*inputMsg, DRAFTMSGSIZE);
663 memcpy(inSlot, draft->data, draft->data->size);
664 delete(draft);
665 }
666 info->stats.recentInPos = (info->stats.recentInPos + 1) % 10;
667 }
668 if (outputMsg) {
669 info->stats.msgOutCount++;
670 info->stats.msgOutBytes += outputMsg->getSize();
671 char* outSlot = info->stats.recentOutMsg + ((info->stats.recentOutPos % 10) * DRAFTMSGSIZE);
672 if (outputMsg->data->size < DRAFTMSGSIZE)
673 memcpy(outSlot, outputMsg->data, outputMsg->data->size);
674 else {
675 draft = new DataMessage(*outputMsg, DRAFTMSGSIZE);
676 memcpy(outSlot, draft->data, draft->data->size);
677 delete(draft);
678 }
679 info->stats.recentOutPos = (info->stats.recentOutPos + 1) % 10;
680 }
681
682 mutex->leave();
683 return true;
684}
685
686
687// Static
689 if (!mutex || !mutex->enter(5000, __FUNCTION__))
690 return false;
692
693 if (cid >= header->indexSize) {
694 mutex->leave();
695 return false;
696 }
697
698 uint64* index = GETCOMPOFFSETP(header, cid);
699 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
700 if (!info) {
701 mutex->leave();
702 return false;
703 }
704 uint64 size = info->size;
705
706 // Check if any data comes after this component; if so, shift it down to
707 // reclaim this component's block and fix up the affected offsets.
708 if (cid < header->maxID) {
709 uint32 nextID = 0;
710 // Iterate the index slots for ids AFTER cid (start at cid+1, not cid).
711 uint64* i = GETCOMPOFFSETP(header, cid + 1);
712 for (uint32 n=cid+1; n<=header->maxID; n++, i++) {
713 if (*i) {
714 if (!nextID) {
715 nextID = n;
716 // Bytes from the next component's block to the end of used data.
717 // Offsets are relative to (header + indexSize*8) while usage is
718 // header-relative, so convert the offset before subtracting.
719 uint64 nextStart = (header->indexSize * sizeof(uint64)) + *i;
720 memmove(info, ((char*)info)+size, (size_t)(header->usage - nextStart));
721 }
722 *i -= size;
723 }
724 }
725 }
726
727 // Free this component's own slot (index still points at cid's slot).
728 *index = 0;
729 header->usage -= size;
730 header->count--;
731
732 mutex->leave();
733 return true;
734}
735
736bool ComponentMemory::updateComponentLocation(uint32 cid, uint16 nodeID, uint16 procID) {
737 if (!mutex || !mutex->enter(5000, __FUNCTION__))
738 return false;
740
741 if (cid >= header->indexSize) {
742 mutex->leave();
743 return false;
744 }
745
746 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
747 if (!info) {
748 mutex->leave();
749 return false;
750 }
751
752 info->nodeID = nodeID;
753 info->procID = procID;
754 mutex->leave();
755 return true;
756}
757
758char* ComponentMemory::getComponentData(uint32 cid, uint64& size) {
759 if (!mutex || !mutex->enter(5000, __FUNCTION__))
760 return NULL;
762
763 if (cid >= header->indexSize) {
764 mutex->leave();
765 return NULL;
766 }
767
768 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
769 if (!info) {
770 mutex->leave();
771 return NULL;
772 }
773
774 size = info->size;
775 char* data = new char[(size_t)size];
776 memcpy(data, info, (size_t)size);
777
778 mutex->leave();
779 return data;
780}
781
782bool ComponentMemory::setComponentData(uint32 cid, const char* data, uint64 size, bool wasMigrated) {
783 if (!mutex || !mutex->enter(5000, __FUNCTION__))
784 return false;
786
787 if (cid >= header->indexSize)
788 resizeIndex(header->indexSize + 256);
789
790 if (!resizeComponent(cid, size)) {
791 mutex->leave();
792 return false;
793 }
794
795 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
796 if (!info) {
797 mutex->leave();
798 return false;
799 }
800
801 uint64 oldsize = info->size;
802
803 memcpy(info, data, (size_t)size);
804 info->size = oldsize;
805
806 if (cid > header->maxID)
807 header->maxID = cid;
808
809 if (wasMigrated)
810 info->stats.migrationCount++;
811
812 // Do not unlock the data, ComponentData destructor will do this
813 mutex->leave();
814 return true;
815}
816
817
818std::list<uint16>* ComponentMemory::findProcessComponents(uint16 procID) {
819 if (!mutex || !mutex->enter(5000, __FUNCTION__))
820 return NULL;
822
824 uint16 localNodeID = master->getNodeID();
825 std::list<uint16>* comps = new std::list<uint16>;
826 for (uint32 n=0; n<=header->maxID; n++) {
827 if (info = GETCOMPDATA(header, n)) {
828 if ((info->nodeID == localNodeID) && (info->procID == procID))
829 comps->push_back(info->id);
830 }
831 }
832 mutex->leave();
833 return comps;
834}
835
839
841 if (!mutex || !mutex->enter(5000, __FUNCTION__))
842 return 0;
844
845 if (cid >= header->indexSize) {
846 mutex->leave();
847 return 0;
848 }
849
850 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
851 if (!info) {
852 mutex->leave();
853 return 0;
854 }
855
856 uint8 policy = info->policy;
857 mutex->leave();
858 return policy;
859}
860
861bool ComponentMemory::updateComponentInformation(uint32 cid, uint8 type, uint8 policy, uint8 selfTrigger, uint16 nodeID, uint16 procID) {
862 if (!mutex || !mutex->enter(5000, __FUNCTION__))
863 return false;
865
866 if (cid >= header->indexSize) {
867 mutex->leave();
868 return false;
869 }
870
871 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
872 if (!info) {
873 mutex->leave();
874 return false;
875 }
876
877 info->policy = policy;
878 info->selfTrigger = selfTrigger;
879 info->nodeID = nodeID;
880 info->procID = procID;
881 info->type = type;
882 if (info->syncStatus == 2)
883 info->syncStatus = 3;
884 mutex->leave();
885 return true;
886}
887
888bool ComponentMemory::setComponentPolicy(uint32 cid, uint8 policy) {
889 if (!mutex || !mutex->enter(5000, __FUNCTION__))
890 return false;
892
893 if (cid >= header->indexSize) {
894 mutex->leave();
895 return false;
896 }
897
898 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
899 if (!info) {
900 mutex->leave();
901 return false;
902 }
903
904 info->policy = policy;
905 mutex->leave();
906 return true;
907}
908
910 if (!mutex || !mutex->enter(5000, __FUNCTION__))
911 return 0;
913
914 if (cid >= header->indexSize) {
915 mutex->leave();
916 return 0;
917 }
918
919 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
920 if (!info) {
921 mutex->leave();
922 return 0;
923 }
924
925 uint8 selfTrigger = info->selfTrigger;
926 mutex->leave();
927 return selfTrigger;
928}
929
930bool ComponentMemory::setComponentSelfTrigger(uint32 cid, uint8 selfTrigger) {
931 if (!mutex || !mutex->enter(5000, __FUNCTION__))
932 return false;
934
935 if (cid >= header->indexSize) {
936 mutex->leave();
937 return false;
938 }
939
940 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
941 if (!info) {
942 mutex->leave();
943 return false;
944 }
945
946 info->selfTrigger = selfTrigger;
947 mutex->leave();
948 return true;
949}
950
951
952bool ComponentMemory::getComponentLocation(uint32 cid, uint16& nodeID, uint16& procID) {
953 nodeID = 0;
954 procID = 0;
955 if (!mutex || !mutex->enter(5000, __FUNCTION__))
956 return false;
958
959 if (cid >= header->indexSize) {
960 mutex->leave();
961 return false;
962 }
963
964 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
965 if (!info) {
966 mutex->leave();
967 return false;
968 }
969
970 nodeID = info->nodeID;
971 procID = info->procID;
972 mutex->leave();
973 return true;
974}
975
976// static
978 if (!mutex || !mutex->enter(5000, __FUNCTION__))
979 return 0;
981
982 if (cid >= header->indexSize) {
983 mutex->leave();
984 return 0;
985 }
986
987 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
988 if (!info) {
989 mutex->leave();
990 return 0;
991 }
992
993 uint16 nodeID = info->nodeID;
994 mutex->leave();
995 return nodeID;
996}
997
998// static
1000 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1001 return 0;
1003
1004 if (cid >= header->indexSize) {
1005 mutex->leave();
1006 return 0;
1007 }
1008
1009 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1010 if (!info) {
1011 mutex->leave();
1012 return 0;
1013 }
1014
1015 uint16 procID = info->procID;
1016 mutex->leave();
1017 return procID;
1018}
1019
1020
1021// static
1023 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1024 return 0;
1026
1027 if (cid >= header->indexSize) {
1028 mutex->leave();
1029 return false;
1030 }
1031
1032 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1033 if (!info) {
1034 mutex->leave();
1035 return false;
1036 }
1037
1038 if (master->getNodeID() == info->nodeID) {
1039 mutex->leave();
1040 return true;
1041 }
1042 else {
1043 mutex->leave();
1044 return false;
1045 }
1046}
1047
1048// static
1050 uint32 cid = 0;
1051 if (getComponentID(name, cid) && cid)
1052 return isComponentLocal(cid);
1053 else
1054 return false;
1055}
1056
1058 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1059 return "";
1061
1062 if (cid >= header->indexSize) {
1063 mutex->leave();
1064 return "";
1065 }
1066
1067 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1068 if (!info) {
1069 mutex->leave();
1070 return "";
1071 }
1072
1073 std::string str = info->name;
1074 mutex->leave();
1075 return str;
1076}
1077
1078// static
1079bool ComponentMemory::getComponentName(uint32 cid, char* name, uint32 maxNameLen) {
1080 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1081 return false;
1083
1084 if (cid >= header->indexSize) {
1085 mutex->leave();
1086 return false;
1087 }
1088
1089 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1090 if (!info) {
1091 mutex->leave();
1092 return false;
1093 }
1094
1095 utils::strcpyavail(name, info->name, maxNameLen, true);
1096 mutex->leave();
1097 return true;
1098}
1099
1101 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1102 return 0;
1104
1105 if (cid >= header->indexSize) {
1106 mutex->leave();
1107 return 0;
1108 }
1109
1110 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1111 if (!info) {
1112 mutex->leave();
1113 return 0;
1114 }
1115
1116 uint8 type = info->type;
1117 mutex->leave();
1118 return type;
1119}
1120
1121// static
1123 ComponentStats stats;
1124 memset(&stats, 0, sizeof(ComponentStats));
1125
1126 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1127 return stats;
1128 if (serial != master->getComponentShmemSerial()) {if (!open()) {mutex->leave();return stats;}}
1129
1130 if (cid >= header->indexSize) {
1131 mutex->leave();
1132 return stats;
1133 }
1134
1135 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1136 if (!info) {
1137 mutex->leave();
1138 return stats;
1139 }
1140
1141 memcpy(&stats, &info->stats, sizeof(ComponentStats));
1142 mutex->leave();
1143 return stats;
1144}
1145
1147 AveragePerfStats perfStats;
1148 memset(&perfStats, 0, sizeof(AveragePerfStats));
1149
1150 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1151 return perfStats;
1152 if (serial != master->getComponentShmemSerial()) {if (!open()) {mutex->leave();return perfStats;}}
1153
1154 if (cid >= header->indexSize) {
1155 mutex->leave();
1156 return perfStats;
1157 }
1158
1159 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1160 if (!info) {
1161 mutex->leave();
1162 return perfStats;
1163 }
1164
1165 memcpy(&perfStats, &info->perfStats, sizeof(AveragePerfStats));
1166 mutex->leave();
1167 return perfStats;
1168}
1169
1171 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1172 return false;
1174
1175 if (cid >= header->indexSize) {
1176 mutex->leave();
1177 return false;
1178 }
1179
1180 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1181 if (!info) {
1182 mutex->leave();
1183 return false;
1184 }
1185
1186 memcpy(&info->perfStats, &perfStruct, sizeof(AveragePerfStats));
1187 mutex->leave();
1188 return true;
1189}
1190
1191// static
1193 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1194 return false;
1196
1197 if (cid >= header->indexSize) {
1198 mutex->leave();
1199 return false;
1200 }
1201
1202 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1203 if (!info) {
1204 mutex->leave();
1205 return false;
1206 }
1207
1208 memcpy(&info->stats, &stats, sizeof(ComponentStats));
1209 mutex->leave();
1210 return true;
1211}
1212
1213// static
1214bool ComponentMemory::getComponentID(const char* name, uint32 &cid) {
1215 if (!mutex || !mutex->enter(5000, __FUNCTION__) || !name || !strlen(name))
1216 return false;
1218
1219 ComponentInfoStruct* info;
1220 for (uint32 n=0; n<=header->maxID; n++) {
1221 if ((info = GETCOMPDATA(header, n)) && (info->syncStatus > 1)) {
1222 if (stricmp(info->name, name) == 0) {
1223 cid = n;
1224 mutex->leave();
1225 return true;
1226 }
1227 }
1228 }
1229 mutex->leave();
1230 return false;
1231}
1232
1233// static
1234uint8 ComponentMemory::lookupComponentID(const char* name, uint32 &cid) {
1235 if (!mutex || !mutex->enter(5000, __FUNCTION__) || !name || !strlen(name))
1236 return false;
1238
1239 uint8 syncStatus;
1240 ComponentInfoStruct* info;
1241 for (uint32 n=0; n<=header->maxID; n++) {
1242 if ((info = GETCOMPDATA(header, n)) && (info->syncStatus > 0)) {
1243 if (stricmp(info->name, name) == 0) {
1244 cid = n;
1245 syncStatus = info->syncStatus;
1246 mutex->leave();
1247 return syncStatus;
1248 }
1249 }
1250 }
1251 mutex->leave();
1252 return 0;
1253}
1254
1255
1256
1257char* ComponentMemory::makeRoomForPrivateData(uint32 cid, uint64 newSize) {
1258 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1259 if (!info)
1260 return NULL;
1261 if (info->size - COMPINFOUSAGE(info) < newSize) {
1262 if (!growComponent(cid, newSize))
1263 return NULL;
1264 if (!(info = GETCOMPDATA(header, cid)))
1265 return NULL;
1266 }
1267 return ((char*)info) + sizeof(ComponentInfoStruct) + info->paramSize + info->dataSize;
1268}
1269
1270char* ComponentMemory::makeRoomForParameter(uint32 cid, uint64 newSize) {
1271 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1272 if (!info)
1273 return NULL;
1274 if (info->size - COMPINFOUSAGE(info) < newSize) {
1275 if (!growComponent(cid, newSize))
1276 return NULL;
1277 if (!(info = GETCOMPDATA(header, cid)))
1278 return NULL;
1279 }
1280
1281 // move private data
1282 char* paramSrc = (char*)info + sizeof(ComponentInfoStruct);
1283 char* dataSrc = paramSrc + info->paramSize;
1284 // space available after private data, so we need to move the private data down
1285 // to make a gap btw this and the parameter data
1286 memcpy(dataSrc+newSize, dataSrc, (size_t)info->dataSize);
1287 // fill the gap with 0s
1288 memset(dataSrc, 0, (size_t)newSize);
1289 // return pointer to the new gap
1290 return dataSrc;
1291}
1292
1293ParamHeader* ComponentMemory::getParameter(uint32 cid, const char* name) {
1294 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1295 if (!info)
1296 return NULL;
1297
1298 char* src = (char*)info + sizeof(ComponentInfoStruct);
1299 char* srcEnd = src + info->paramSize;
1300
1301 uint32 offset = 0;
1302 while ( src < srcEnd ) {
1303 if (stricmp(name, src + sizeof(ParamHeader)) == 0)
1304 return (ParamHeader*)src;
1305 offset += *(uint32*)src;
1306 src += *(uint32*)src;
1307 }
1308 return NULL;
1309}
1310
1311PrivateHeader* ComponentMemory::getPrivateData(uint32 cid, const char* name) {
1312 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1313 if (!info)
1314 return NULL;
1315
1316 char* src = (char*)info + sizeof(ComponentInfoStruct) + info->paramSize;
1317 char* srcEnd = src + info->dataSize;
1318
1319 while ( src < srcEnd ) {
1320 if (stricmp(name, src + sizeof(PrivateHeader)) == 0)
1321 return (PrivateHeader*)src;
1322 src += *(uint32*)src;
1323 }
1324 return NULL;
1325}
1326
1327
1328// Private Data
1329bool ComponentMemory::setPrivateData(uint32 cid, const char* name, const char* data, uint64 size, const char* mimetype) {
1330 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1331 return false;
1333
1334 if (cid >= header->indexSize) {
1335 mutex->leave();
1336 return false;
1337 }
1338
1339 std::string actualMimetype;
1340
1341 uint32 nameLen = (uint32)strlen(name);
1342 uint32 mimeLen = 0;
1343 if (mimetype) {
1344 if (stricmp(mimetype, "xml") == 0)
1345 actualMimetype = "text/xml";
1346 else if (stricmp(mimetype, "json") == 0)
1347 actualMimetype = "application/json";
1348 else if (stricmp(mimetype, "binary") == 0)
1349 actualMimetype = "application/octet-stream";
1350 else if (stricmp(mimetype, "html") == 0)
1351 actualMimetype = "text/html";
1352 else if (stricmp(mimetype, "bitmap") == 0)
1353 actualMimetype = "image/bmp";
1354 else if (stricmp(mimetype, "text") == 0)
1355 actualMimetype = "text/plain";
1356 else
1357 actualMimetype = mimetype;
1358 mimeLen = (uint32)actualMimetype.length();
1359 }
1360 uint64 totalSize = sizeof(PrivateHeader) + nameLen + 1 + mimeLen + 1 + size;
1361
1362 PrivateHeader* priv = getPrivateData(cid, name);
1363
1364 if (priv) {
1365 if (priv->size == totalSize) {
1366 if (mimeLen)
1367 memcpy(((char*)priv) + sizeof(PrivateHeader) + nameLen + 1, actualMimetype.c_str(), (size_t)mimeLen + 1);
1368 else
1369 memset(((char*)priv) + sizeof(PrivateHeader) + nameLen + 1, 0, 1); // Just the 0
1370 memcpy(((char*)priv) + sizeof(PrivateHeader) + nameLen + 1 + mimeLen + 1, data, (size_t)size);
1371
1372 //printf("\n$$$$$$$$$$$$$$$$$$$$ ResetData: '%s' [%s]: '%s'\n\n",
1373 // ((char*)priv + sizeof(PrivateHeader)),
1374 // ((char*)priv) + sizeof(PrivateHeader) + nameLen + 1,
1375 // ((char*)priv) + sizeof(PrivateHeader) + nameLen + 1 + mimeLen + 1);
1376
1377 mutex->leave();
1378 return true;
1379 }
1380 else {
1381 deletePrivateData(cid, name);
1382 }
1383 }
1384
1385 char* newData = makeRoomForPrivateData(cid, totalSize);
1386 if (newData == NULL) {
1387 mutex->leave();
1388 return false;
1389 }
1390
1391 // Copy in new data
1392 *(uint64*) newData = totalSize;
1393 memcpy(newData + sizeof(PrivateHeader), name, nameLen+1); // incl. 0 at the end of the string
1394 if (mimeLen)
1395 memcpy(newData + sizeof(PrivateHeader) + nameLen + 1, actualMimetype.c_str(), mimeLen + 1); // incl. 0 at the end of the string
1396 else
1397 memset(newData + sizeof(PrivateHeader) + nameLen + 1, 0, 1); // Just the 0
1398 memcpy(newData + sizeof(PrivateHeader) + nameLen+1 + mimeLen + 1, data, (size_t)size);
1399
1400 //printf("\n������������������� SetData: '%s' [%s]: '%s'\n\n",
1401 // newData + sizeof(PrivateHeader),
1402 // newData + sizeof(PrivateHeader) + nameLen + 1,
1403 // newData + sizeof(PrivateHeader) + nameLen + 1 + mimeLen + 1);
1404
1405 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1406 info->dataCount++;
1407 info->dataSize += totalSize;
1408 mutex->leave();
1409 return true;
1410}
1411
1412uint64 ComponentMemory::getPrivateDataSize(uint32 cid, const char* name) {
1413 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1414 return 0;
1416
1417 if (cid >= header->indexSize) {
1418 mutex->leave();
1419 return 0;
1420 }
1421
1422 PrivateHeader* priv = getPrivateData(cid, name);
1423 if (!priv) {
1424 mutex->leave();
1425 return 0;
1426 }
1427
1428 uint32 nameLen = (uint32)strlen(((char*)priv + sizeof(PrivateHeader)));
1429 uint32 mimeLen = (uint32)strlen(((char*)priv + sizeof(PrivateHeader) + nameLen+1));
1430
1431 uint64 size = priv->size - sizeof(PrivateHeader) - nameLen - mimeLen - 2;
1432 mutex->leave();
1433 return size;
1434}
1435
1436char* ComponentMemory::getPrivateDataCopy(uint32 cid, const char* name, uint64 &size) {
1437 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1438 return NULL;
1440
1441 if (cid >= header->indexSize) {
1442 mutex->leave();
1443 return NULL;
1444 }
1445
1446 PrivateHeader* priv = getPrivateData(cid, name);
1447 if (!priv) {
1448 mutex->leave();
1449 return NULL;
1450 }
1451
1452 uint32 nameLen = (uint32)strlen(((char*)priv + sizeof(PrivateHeader)));
1453 uint32 mimeLen = (uint32)strlen(((char*)priv + sizeof(PrivateHeader) + nameLen + 1));
1454
1455 uint64 offset = sizeof(PrivateHeader) + nameLen + mimeLen + 2;
1456 size = priv->size - offset;
1457 if (!size) {
1458 mutex->leave();
1459 return NULL;
1460 }
1461 char* data = new char[(size_t)size];
1462 memcpy((void*)data, ((char*)priv) + offset, (size_t)size);
1463 mutex->leave();
1464 return data;
1465}
1466
1467bool ComponentMemory::getPrivateData(uint32 cid, const char* name, char* data, uint64 maxSize) {
1468 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1469 return false;
1471
1472 if (cid >= header->indexSize) {
1473 mutex->leave();
1474 return false;
1475 }
1476
1477 PrivateHeader* priv = getPrivateData(cid, name);
1478 if (!priv) {
1479 mutex->leave();
1480 return false;
1481 }
1482
1483 uint32 nameLen = (uint32)strlen(((char*)priv + sizeof(PrivateHeader)));
1484 uint32 mimeLen = (uint32)strlen(((char*)priv + sizeof(PrivateHeader) + nameLen + 1));
1485
1486 uint64 offset = sizeof(PrivateHeader) + nameLen + mimeLen + 2;
1487 uint64 size = priv->size - offset;
1488 if (size > maxSize) {
1489 mutex->leave();
1490 return false;
1491 }
1492 memcpy((void*)data, ((char*)priv) + offset, (size_t)size);
1493 mutex->leave();
1494 return true;
1495}
1496
1497std::string ComponentMemory::getPrivateDataMimetype(uint32 cid, const char* name) {
1498 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1499 return "";
1501
1502 if (cid >= header->indexSize) {
1503 mutex->leave();
1504 return "";
1505 }
1506
1507 PrivateHeader* priv = getPrivateData(cid, name);
1508 if (!priv) {
1509 mutex->leave();
1510 return "";
1511 }
1512
1513 uint32 nameLen = (uint32)strlen(((char*)priv + sizeof(PrivateHeader)));
1514 std::string type = ((char*)priv + sizeof(PrivateHeader) + nameLen + 1);
1515
1516 mutex->leave();
1517 return type;
1518}
1519
1520std::map<std::string, std::string> ComponentMemory::getPrivateDataKeysAndTypes(uint32 cid) {
1521 std::map<std::string, std::string> map;
1522
1523 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1524 return map;
1526
1527 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1528 if (!info) {
1529 mutex->leave();
1530 return map;
1531 }
1532
1533 char* src = (char*)info + sizeof(ComponentInfoStruct) + info->paramSize;
1534 char* srcEnd = src + info->dataSize;
1535
1536 uint32 nameLen;
1537 uint32 mimeLen;
1538 PrivateHeader* priv;
1539
1540 while (src < srcEnd) {
1541 priv = (PrivateHeader*)src;
1542 nameLen = (uint32)strlen(((char*)priv + sizeof(PrivateHeader)));
1543 mimeLen = (uint32)strlen(((char*)priv + sizeof(PrivateHeader) + nameLen + 1));
1544
1545 if (nameLen) {
1546 if (mimeLen)
1547 map[((char*)priv + sizeof(PrivateHeader))] = ((char*)priv + sizeof(PrivateHeader) + nameLen + 1);
1548 else
1549 map[((char*)priv + sizeof(PrivateHeader))] = "";
1550 }
1551
1552 src += *(uint32*)src;
1553 }
1554
1555 mutex->leave();
1556 return map;
1557}
1558
1559std::list<std::string> ComponentMemory::getPrivateDataKeys(uint32 cid) {
1560 std::list<std::string> list;
1561
1562 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1563 return list;
1565
1566 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1567 if (!info) {
1568 mutex->leave();
1569 return list;
1570 }
1571
1572 char* src = (char*)info + sizeof(ComponentInfoStruct) + info->paramSize;
1573 char* srcEnd = src + info->dataSize;
1574
1575 uint32 nameLen;
1576 PrivateHeader* priv;
1577
1578 while (src < srcEnd) {
1579 priv = (PrivateHeader*)src;
1580 nameLen = (uint32)strlen(((char*)priv + sizeof(PrivateHeader)));
1581
1582 if (nameLen)
1583 list.push_back(((char*)priv + sizeof(PrivateHeader)));
1584
1585 src += *(uint32*)src;
1586 }
1587
1588 mutex->leave();
1589 return list;
1590}
1591
1592
1593
1594
1595
1596bool ComponentMemory::deletePrivateData(uint32 cid, const char* name) {
1597 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1598 return false;
1600
1601 if (cid >= header->indexSize) {
1602 mutex->leave();
1603 return false;
1604 }
1605
1606 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1607 PrivateHeader* priv = getPrivateData(cid, name);
1608 if (!priv) {
1609 mutex->leave();
1610 return false;
1611 }
1612
1613 uint64 delSize = priv->size;
1614 uint64 moveSize = (uint32)(((char*)info)+COMPINFOUSAGE(info)-((char*)priv)-priv->size);
1615 memmove(((char*)priv), ((char*)priv)+priv->size, (size_t)moveSize);
1616 info->dataCount--;
1617 info->dataSize -= delSize;
1618 mutex->leave();
1619 return true;
1620}
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631// Parameters
1632bool ComponentMemory::createParameter(uint32 cid, const char* name, const char* val, const char* defaultValue) {
1633 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1634 return false;
1636
1637 if (cid >= header->indexSize) {
1638 mutex->leave();
1639 return false;
1640 }
1641
1642 ParamHeader* param = getParameter(cid, name);
1643 if (param) {
1644 mutex->leave();
1645 return false;
1646 }
1647
1648 // Calculate required size
1649 uint32 nameLen = (uint32)strlen(name);
1650 uint32 newSize = nameLen + 1 + sizeof(ParamHeader) + (uint32)strlen(val) + 1;
1651 if (defaultValue != NULL)
1652 newSize += (uint32)strlen(defaultValue) + 1;
1653 else
1654 newSize += (uint32)strlen(val) + 1;
1655
1656 char* newData = makeRoomForParameter(cid, newSize);
1657 if (newData == NULL) {
1658 mutex->leave();
1659 return false;
1660 }
1661
1662 // Copy in new data
1663 param = (ParamHeader*) newData;
1664 param->size = newSize;
1665 param->type = PARAM_STRING;
1666 memcpy(newData + sizeof(ParamHeader), name, nameLen+1); // incl. 0 at the end of the string
1667 newData += sizeof(ParamHeader) + nameLen + 1;
1668 // copy in main value
1669 utils::strcpyavail(newData, val, newSize, true);
1670 newData += strlen(val) + 1;
1671 // copy in default value
1672 if (defaultValue != NULL)
1673 utils::strcpyavail(newData, defaultValue, newSize, true);
1674 else
1675 utils::strcpyavail(newData, val, newSize, true);
1676
1677 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1678 info->paramCount++;
1679 info->paramSize += newSize;
1680 mutex->leave();
1681 return true;
1682}
1683
1684bool ComponentMemory::createParameter(uint32 cid, const char* name, const char* val, uint32 count, uint32 defaultIndex) {
1685 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1686 return false;
1688
1689 if (cid >= header->indexSize) {
1690 mutex->leave();
1691 return false;
1692 }
1693
1694 ParamHeader* param = getParameter(cid, name);
1695 if (param) {
1696 mutex->leave();
1697 return false;
1698 }
1699
1700 // Calculate required size
1701 uint32 n, len;
1702 uint32 nameLen = (uint32)strlen(name);
1703 uint32 newSize = nameLen + 1 + sizeof(ParamHeader) + sizeof(ParamCollectionHeader);
1704 uint32 dataSize = 0;
1705 const char* pVal = val;
1706 for (n=0; n<count; n++) {
1707 len = (uint32)strlen(pVal) + 1;
1708 dataSize += len;
1709 pVal += len;
1710 }
1711 newSize += dataSize;
1712
1713 char* newData = makeRoomForParameter(cid, newSize);
1714 if (newData == NULL) {
1715 mutex->leave();
1716 return false;
1717 }
1718
1719 // Copy in new data
1720 param = (ParamHeader*) newData;
1721 param->size = newSize;
1722 param->type = PARAM_STRING_COLL;
1723 memcpy(newData + sizeof(ParamHeader), name, nameLen+1); // incl. 0 at the end of the string
1724
1725 ParamCollectionHeader* dHeader = (ParamCollectionHeader*) (newData + sizeof(ParamHeader) + nameLen + 1);
1726 dHeader->index = defaultIndex;
1727 dHeader->defaultIndex = defaultIndex;
1728 dHeader->count = count;
1729
1730 // copy in data values
1731 memcpy((char*)dHeader + sizeof(ParamCollectionHeader), val, dataSize);
1732
1733 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1734 info->paramCount++;
1735 info->paramSize += newSize;
1736 mutex->leave();
1737 return true;
1738}
1739
1740bool ComponentMemory::createParameter(uint32 cid, const char* name, std::vector<std::string> values, const char* defaultValue) {
1741 uint32 n, dlen, len = 0, dataSize = 0, defaultIndex = 0;
1742 uint32 count = (uint32)values.size();
1743 for (n=0; n<count; n++)
1744 dataSize += (uint32)values[n].size() + 1;
1745 char* val = new char[dataSize];
1746 for (n=0; n<count; n++) {
1747 dlen = (uint32)values[n].size()+1;
1748 memcpy(val+len, values[n].c_str(), dlen);
1749 len += dlen;
1750 if (values[n] == defaultValue)
1751 defaultIndex = n;
1752 }
1753 bool res = createParameter(cid, name, val, count, defaultIndex);
1754 delete [] val;
1755 return res;
1756}
1757
1758bool ComponentMemory::createParameter(uint32 cid, const char* name, std::vector<std::string> values, int64 defaultValue) {
1759 uint32 n, defaultIndex = 0;
1760 uint32 count = (uint32)values.size();
1761 int64* val = new int64[count];
1762 for (n=0; n<count; n++) {
1763 val[n] = utils::Ascii2Int64(values[n].c_str());
1764 if (val[n] == defaultValue)
1765 defaultIndex = n;
1766 }
1767 bool res = createParameter(cid, name, val, count, defaultIndex);
1768 delete [] val;
1769 return res;
1770}
1771
1772bool ComponentMemory::createParameter(uint32 cid, const char* name, std::vector<int64> values, int64 defaultValue) {
1773 uint32 n, defaultIndex = 0;
1774 uint32 count = (uint32)values.size();
1775 int64* val = new int64[count];
1776 for (n = 0; n<count; n++) {
1777 val[n] = values[n];
1778 if (val[n] == defaultValue)
1779 defaultIndex = n;
1780 }
1781 bool res = createParameter(cid, name, val, count, defaultIndex);
1782 delete[] val;
1783 return res;
1784}
1785
1786bool ComponentMemory::createParameter(uint32 cid, const char* name, std::vector<std::string> values, float64 defaultValue) {
1787 uint32 n, defaultIndex = 0;
1788 uint32 count = (uint32)values.size();
1789 float64* val = new float64[count];
1790 for (n=0; n<count; n++) {
1791 val[n] = utils::Ascii2Float64(values[n].c_str());
1792 if (val[n] == defaultValue)
1793 defaultIndex = n;
1794 }
1795 bool res = createParameter(cid, name, val, count, defaultIndex);
1796 delete [] val;
1797 return res;
1798}
1799
1800bool ComponentMemory::createParameter(uint32 cid, const char* name, std::vector<float64> values, float64 defaultValue) {
1801 uint32 n, defaultIndex = 0;
1802 uint32 count = (uint32)values.size();
1803 float64* val = new float64[count];
1804 for (n = 0; n<count; n++) {
1805 val[n] = values[n];
1806 if (val[n] == defaultValue)
1807 defaultIndex = n;
1808 }
1809 bool res = createParameter(cid, name, val, count, defaultIndex);
1810 delete[] val;
1811 return res;
1812}
1813
1814bool ComponentMemory::createParameter(uint32 cid, const char* name, int64* val, uint32 count, uint32 defaultIndex) {
1815 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1816 return false;
1818
1819 if (cid >= header->indexSize) {
1820 mutex->leave();
1821 return false;
1822 }
1823
1824 ParamHeader* param = getParameter(cid, name);
1825 if (param) {
1826 mutex->leave();
1827 return false;
1828 }
1829
1830 // Calculate required size
1831 uint32 nameLen = (uint32)strlen(name);
1832 uint32 newSize = nameLen + 1 + sizeof(ParamHeader) + sizeof(ParamCollectionHeader) + (count * sizeof(int64));
1833
1834 char* newData = makeRoomForParameter(cid, newSize);
1835 if (newData == NULL) {
1836 mutex->leave();
1837 return false;
1838 }
1839
1840 // Copy in new data
1841 ParamHeader* pHeader = (ParamHeader*) newData;
1842 pHeader->size = newSize;
1843 pHeader->type = PARAM_INTEGER_COLL;
1844 memcpy(newData + sizeof(ParamHeader), name, nameLen+1); // incl. 0 at the end of the string
1845
1846 ParamCollectionHeader* dHeader = (ParamCollectionHeader*) (newData + sizeof(ParamHeader) + nameLen + 1);
1847 dHeader->index = defaultIndex;
1848 dHeader->defaultIndex = defaultIndex;
1849 dHeader->count = count;
1850
1851 // copy in data values
1852 memcpy((char*)dHeader + sizeof(ParamCollectionHeader), val, count * sizeof(int64));
1853
1854 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1855 info->paramCount++;
1856 info->paramSize += newSize;
1857 mutex->leave();
1858 return true;
1859}
1860
1861bool ComponentMemory::createParameter(uint32 cid, const char* name, float64* val, uint32 count, uint32 defaultIndex) {
1862 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1863 return false;
1865
1866 if (cid >= header->indexSize) {
1867 mutex->leave();
1868 return false;
1869 }
1870
1871 ParamHeader* param = getParameter(cid, name);
1872 if (param) {
1873 mutex->leave();
1874 return false;
1875 }
1876
1877 // Calculate required size
1878 uint32 nameLen = (uint32)strlen(name);
1879 uint32 newSize = nameLen + 1 + sizeof(ParamHeader) + sizeof(ParamCollectionHeader) + (count * sizeof(float64));
1880
1881 char* newData = makeRoomForParameter(cid, newSize);
1882 if (newData == NULL) {
1883 mutex->leave();
1884 return false;
1885 }
1886
1887 // Copy in new data
1888 ParamHeader* pHeader = (ParamHeader*) newData;
1889 pHeader->size = newSize;
1890 pHeader->type = PARAM_FLOAT_COLL;
1891 memcpy(newData + sizeof(ParamHeader), name, nameLen+1); // incl. 0 at the end of the string
1892
1893 ParamCollectionHeader* dHeader = (ParamCollectionHeader*) (newData + sizeof(ParamHeader) + nameLen + 1);
1894 dHeader->index = defaultIndex;
1895 dHeader->defaultIndex = defaultIndex;
1896 dHeader->count = count;
1897
1898 // copy in data values
1899 memcpy((char*)dHeader + sizeof(ParamCollectionHeader), val, count * sizeof(float64));
1900
1901 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1902 info->paramCount++;
1903 info->paramSize += newSize;
1904 mutex->leave();
1905 return true;
1906}
1907
1908bool ComponentMemory::createParameter(uint32 cid, const char* name, int64 val, int64 min, int64 max, int64 interval) {
1909 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1910 return false;
1912
1913 if (cid >= header->indexSize) {
1914 mutex->leave();
1915 return false;
1916 }
1917
1918 ParamHeader* param = getParameter(cid, name);
1919 if (param) {
1920 mutex->leave();
1921 return false;
1922 }
1923
1924 // Calculate required size
1925 uint32 nameLen = (uint32)strlen(name);
1926 uint32 newSize = nameLen + 1 + sizeof(ParamHeader) + sizeof(ParamIntegerHeader);
1927
1928 char* newData = makeRoomForParameter(cid, newSize);
1929 if (newData == NULL) {
1930 mutex->leave();
1931 return false;
1932 }
1933
1934 // Copy in new data
1935 ParamHeader* pHeader = (ParamHeader*) newData;
1936 pHeader->size = newSize;
1937 pHeader->type = PARAM_INTEGER;
1938 memcpy(newData + sizeof(ParamHeader), name, nameLen+1); // incl. 0 at the end of the string
1939
1940 ParamIntegerHeader* dHeader = (ParamIntegerHeader*) (newData + sizeof(ParamHeader) + nameLen + 1);
1941
1942 // copy in values
1943 dHeader->val = val;
1944 dHeader->defaultVal = val;
1945 dHeader->minVal = min;
1946 dHeader->maxVal = max;
1947 dHeader->interval = interval;
1948
1949 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1950 info->paramCount++;
1951 info->paramSize += newSize;
1952 mutex->leave();
1953 return true;
1954}
1955
1956bool ComponentMemory::createParameter(uint32 cid, const char* name, float64 val, float64 min, float64 max, float64 interval) {
1957 if (!mutex || !mutex->enter(5000, __FUNCTION__))
1958 return false;
1960
1961 if (cid >= header->indexSize) {
1962 mutex->leave();
1963 return false;
1964 }
1965
1966 ParamHeader* param = getParameter(cid, name);
1967 if (param) {
1968 mutex->leave();
1969 return false;
1970 }
1971
1972 // Calculate required size
1973 uint32 nameLen = (uint32)strlen(name);
1974 uint32 newSize = nameLen + 1 + sizeof(ParamHeader) + sizeof(ParamFloatHeader);
1975
1976 char* newData = makeRoomForParameter(cid, newSize);
1977 if (newData == NULL) {
1978 mutex->leave();
1979 return false;
1980 }
1981
1982 // Copy in new data
1983 ParamHeader* pHeader = (ParamHeader*) newData;
1984 pHeader->size = newSize;
1985 pHeader->type = PARAM_FLOAT;
1986 memcpy(newData + sizeof(ParamHeader), name, nameLen+1); // incl. 0 at the end of the string
1987
1988 ParamFloatHeader* dHeader = (ParamFloatHeader*) (newData + sizeof(ParamHeader) + nameLen + 1);
1989
1990 // copy in values
1991 dHeader->val = val;
1992 dHeader->defaultVal = val;
1993 dHeader->minVal = min;
1994 dHeader->maxVal = max;
1995 dHeader->interval = interval;
1996
1997 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
1998 info->paramCount++;
1999 info->paramSize += newSize;
2000 mutex->leave();
2001 return true;
2002}
2003
2004bool ComponentMemory::hasParameter(uint32 cid, const char* name) {
2005 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2006 return false;
2008
2009 if (cid >= header->indexSize) {
2010 mutex->leave();
2011 return false;
2012 }
2013
2014 ParamHeader* param = getParameter(cid, name);
2015 if (!param) {
2016 mutex->leave();
2017 return false;
2018 }
2019 else {
2020 mutex->leave();
2021 return true;
2022 }
2023}
2024
2025bool ComponentMemory::deleteParameter(uint32 cid, const char* name) {
2026 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2027 return false;
2029
2030 if (cid >= header->indexSize) {
2031 mutex->leave();
2032 return false;
2033 }
2034
2035 ParamHeader* param = getParameter(cid, name);
2036 if (!param) {
2037 mutex->leave();
2038 return false;
2039 }
2040 ComponentInfoStruct* info = GETCOMPDATA(header, cid);
2041
2042 uint32 delSize = param->size;
2043 uint32 moveSize = (uint32)(((char*)info) + sizeof(ComponentInfoStruct) + COMPINFOUSAGE(info) - ((char*)param) - param->size);
2044 memmove(((char*)param), ((char*)param)+param->size, moveSize);
2045 info->paramCount--;
2046 info->paramSize -= delSize;
2047 mutex->leave();
2048 return true;
2049}
2050
2051uint8 ComponentMemory::getParameterDataType(uint32 cid, const char* name) {
2052 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2053 return 0;
2055
2056 if (cid >= header->indexSize) {
2057 mutex->leave();
2058 return false;
2059 }
2060
2061 ParamHeader* param = getParameter(cid, name);
2062 if (!param) {
2063 mutex->leave();
2064 return 0;
2065 }
2066
2067 uint8 type = param->type;
2068 mutex->leave();
2069 return type;
2070}
2071
2072uint32 ComponentMemory::getParameterValueSize(uint32 cid, const char* name) {
2073 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2074 return 0;
2076
2077 if (cid >= header->indexSize) {
2078 mutex->leave();
2079 return false;
2080 }
2081
2082 ParamHeader* param = getParameter(cid, name);
2083 if (!param) {
2084 mutex->leave();
2085 return 0;
2086 }
2087
2088 uint32 size;
2089 char* pSrc = ((char*)param) + sizeof(ParamHeader) + strlen(((char*)param) + sizeof(ParamHeader)) + 1;
2090 if ( (param->type == PARAM_INTEGER) || (param->type == PARAM_INTEGER_COLL) )
2091 size = sizeof(int64);
2092 else if ( (param->type == PARAM_FLOAT) || (param->type == PARAM_FLOAT_COLL) )
2093 size = sizeof(float64);
2094 else if (param->type == PARAM_STRING) {
2095 size = ((uint32)strlen(pSrc) + 1);
2096 }
2097 else {
2099 for (uint32 n=0; n<cHeader->index; n++)
2100 pSrc += strlen(pSrc) + 1;
2101 size = (uint32)strlen(pSrc) + 1;
2102 }
2103
2104 mutex->leave();
2105 return size;
2106}
2107
2108std::string ComponentMemory::getParameterString(uint32 cid, const char* name, uint32 maxSize) {
2109 char* val = new char[maxSize];
2110 if (!getParameter(cid, name, val, maxSize))
2111 return "";
2112 std::string valString = val;
2113 delete[] val;
2114 return valString;
2115}
2116
2117std::string ComponentMemory::getParameterString(uint32 cid, const char* name) {
2118 std::string result;
2119 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2120 return result;
2122
2123 if (cid >= header->indexSize) {
2124 mutex->leave();
2125 return result;
2126 }
2127
2128 ParamHeader* pHeader = getParameter(cid, name);
2129 if (!pHeader) {
2130 mutex->leave();
2131 return result;
2132 }
2133
2134 char* pSrc = ((char*)pHeader) + sizeof(ParamHeader) + strlen(((char*)pHeader) + sizeof(ParamHeader)) + 1;
2135
2136 if (pHeader->type == PARAM_STRING) {
2137 result = pSrc;
2138 mutex->leave();
2139 return result;
2140 }
2141 else if (pHeader->type == PARAM_STRING_COLL) {
2143 pSrc += sizeof(ParamCollectionHeader);
2144 for (uint32 n = 0; n<cHeader->index; n++)
2145 pSrc += strlen(pSrc) + 1;
2146 result = pSrc;
2147 mutex->leave();
2148 return result;
2149 }
2150 else {
2151 mutex->leave();
2152 return result;
2153 }
2154}
2155
2156int64 ComponentMemory::getParameterInt(uint32 cid, const char* name) {
2157 int64 val = 0;
2158 if (!getParameter(cid, name, val))
2159 return 0;
2160 return val;
2161}
2162
2163float64 ComponentMemory::getParameterFloat(uint32 cid, const char* name) {
2164 float64 val = 0;
2165 if (!getParameter(cid, name, val))
2166 return 0;
2167 return val;
2168}
2169
2170bool ComponentMemory::getParameterAsBool(uint32 cid, const char* name) {
2171 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2172 return false;
2174
2175 if (cid >= header->indexSize) {
2176 mutex->leave();
2177 return false;
2178 }
2179
2180 ParamHeader* pHeader = getParameter(cid, name);
2181 if (!pHeader) {
2182 mutex->leave();
2183 return 0;
2184 }
2185
2186 ParamCollectionHeader* cHeader;
2187 int64 ival;
2188 float64 fval;
2189 char* pSrc = ((char*)pHeader) + sizeof(ParamHeader) + strlen(((char*)pHeader) + sizeof(ParamHeader)) + 1;
2190
2191 if (pHeader->type == PARAM_STRING) {
2192 if (stricmp(pSrc, "Yes") == 0) {
2193 mutex->leave();
2194 return true;
2195 }
2196 else {
2197 mutex->leave();
2198 return false;
2199 }
2200 }
2201 else if (pHeader->type == PARAM_STRING_COLL) {
2202 cHeader = (ParamCollectionHeader*)pSrc;
2203 pSrc += sizeof(ParamCollectionHeader);
2204 for (uint32 n = 0; n<cHeader->index; n++)
2205 pSrc += strlen(pSrc) + 1;
2206 if (stricmp(pSrc, "yes") == 0) {
2207 mutex->leave();
2208 return true;
2209 }
2210 else {
2211 mutex->leave();
2212 return false;
2213 }
2214 }
2215 else if (pHeader->type == PARAM_INTEGER) {
2216 ival = *(int64*)(pSrc);
2217 mutex->leave();
2218 return (ival != 0);
2219 }
2220 else if (pHeader->type == PARAM_INTEGER_COLL) {
2221 cHeader = (ParamCollectionHeader*)pSrc;
2222 pSrc += sizeof(ParamCollectionHeader) + (cHeader->index * sizeof(int64));
2223 ival = *(int64*)pSrc;
2224 mutex->leave();
2225 return (ival != 0);
2226 }
2227 else if (pHeader->type == PARAM_FLOAT) {
2228 fval = *(float64*)(pSrc);
2229 mutex->leave();
2230 return (fval != 0);
2231 }
2232 else if (pHeader->type == PARAM_FLOAT_COLL) {
2233 cHeader = (ParamCollectionHeader*)pSrc;
2234 pSrc += sizeof(ParamCollectionHeader) + (cHeader->index * sizeof(float64));
2235 fval = *(float64*)pSrc;
2236 mutex->leave();
2237 return (fval != 0);
2238 }
2239 else {
2240 mutex->leave();
2241 return false;
2242 }
2243}
2244
2245
2246bool ComponentMemory::getParameter(uint32 cid, const char* name, char* val, uint32 maxSize) {
2247 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2248 return false;
2250
2251 if (cid >= header->indexSize) {
2252 mutex->leave();
2253 return false;
2254 }
2255
2256 ParamHeader* pHeader = getParameter(cid, name);
2257 if (!pHeader) {
2258 mutex->leave();
2259 return 0;
2260 }
2261
2262 char* pSrc = ((char*)pHeader) + sizeof(ParamHeader) + strlen(((char*)pHeader) + sizeof(ParamHeader)) + 1;
2263
2264 if (pHeader->type == PARAM_STRING) {
2265 if (maxSize < strlen(pSrc) + 1) {
2266 mutex->leave();
2267 return false;
2268 }
2269 utils::strcpyavail(val, pSrc, maxSize, true);
2270 mutex->leave();
2271 return true;
2272 }
2273 else if (pHeader->type == PARAM_STRING_COLL) {
2275 pSrc += sizeof(ParamCollectionHeader);
2276 for (uint32 n=0; n<cHeader->index; n++)
2277 pSrc += strlen(pSrc) + 1;
2278 if (maxSize < strlen(pSrc) + 1) {
2279 mutex->leave();
2280 return false;
2281 }
2282 utils::strcpyavail(val, pSrc, maxSize, true);
2283 mutex->leave();
2284 return true;
2285 }
2286 else {
2287 mutex->leave();
2288 return false;
2289 }
2290}
2291
2292bool ComponentMemory::getParameter(uint32 cid, const char* name, int64& val) {
2293 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2294 return false;
2296
2297 if (cid >= header->indexSize) {
2298 mutex->leave();
2299 return false;
2300 }
2301
2302 ParamHeader* pHeader = getParameter(cid, name);
2303 if (!pHeader) {
2304 mutex->leave();
2305 return 0;
2306 }
2307
2308 char* pSrc = ((char*)pHeader) + sizeof(ParamHeader) + strlen(((char*)pHeader) + sizeof(ParamHeader)) + 1;
2309
2310 if (pHeader->type == PARAM_INTEGER) {
2311 val = *(int64*)(pSrc);
2312 mutex->leave();
2313 return true;
2314 }
2315 else if (pHeader->type == PARAM_INTEGER_COLL) {
2317 pSrc += sizeof(ParamCollectionHeader) + (cHeader->index*sizeof(int64));
2318 val = *(int64*) pSrc;
2319 mutex->leave();
2320 return true;
2321 }
2322 else {
2323 mutex->leave();
2324 return false;
2325 }
2326}
2327
2328bool ComponentMemory::getParameter(uint32 cid, const char* name, float64& val) {
2329 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2330 return false;
2332
2333 if (cid >= header->indexSize) {
2334 mutex->leave();
2335 return false;
2336 }
2337
2338 ParamHeader* pHeader = getParameter(cid, name);
2339 if (!pHeader) {
2340 mutex->leave();
2341 return 0;
2342 }
2343
2344 char* pSrc = ((char*)pHeader) + sizeof(ParamHeader) + strlen(((char*)pHeader) + sizeof(ParamHeader)) + 1;
2345
2346 if (pHeader->type == PARAM_FLOAT) {
2347 val = *(float64*)(pSrc);
2348 mutex->leave();
2349 return true;
2350 }
2351 else if (pHeader->type == PARAM_FLOAT_COLL) {
2353 pSrc += sizeof(ParamCollectionHeader) + (cHeader->index*sizeof(float64));
2354 val = *(float64*) pSrc;
2355 mutex->leave();
2356 return true;
2357 }
2358 else {
2359 mutex->leave();
2360 return false;
2361 }
2362}
2363
2364
2365bool ComponentMemory::setParameter(uint32 cid, const char* name, const char* val) {
2366 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2367 return false;
2369
2370 if (cid >= header->indexSize) {
2371 mutex->leave();
2372 return false;
2373 }
2374
2375 ParamHeader* pHeader = getParameter(cid, name);
2376 if (!pHeader) {
2377 mutex->leave();
2378 return 0;
2379 }
2380
2381 uint32 oldSize;
2382 char* pSrc = ((char*)pHeader) + sizeof(ParamHeader) + strlen(((char*)pHeader) + sizeof(ParamHeader)) + 1;
2383 if (pHeader->type == PARAM_STRING) {
2384 oldSize = (uint32)strlen(pSrc);
2385 if (strlen(val) == oldSize) {
2386 utils::strcpyavail(pSrc, val, oldSize, true);
2387 mutex->leave();
2388 return true;
2389 }
2390 // we need to recreate the parameter with the new size
2391 uint32 defaultSize = (uint32)strlen(pSrc + oldSize + 1) + 1;
2392 char* defaultValue = new char[defaultSize];
2393 utils::strcpyavail(defaultValue, pSrc + oldSize + 1, defaultSize, true);
2394 // delete the old parameter
2395 if (!deleteParameter(cid, name)) {
2396 delete [] defaultValue;
2397 mutex->leave();
2398 return false;
2399 }
2400 // create the new one
2401 if (!createParameter(cid, name, val, defaultValue)) {
2402 delete [] defaultValue;
2403 mutex->leave();
2404 return false;
2405 }
2406 // clean up
2407 delete [] defaultValue;
2408 mutex->leave();
2409 return true;
2410 }
2411 else if (pHeader->type == PARAM_STRING_COLL) {
2412 // See if the requested value is in the list
2414 uint32 index = 0;
2415 pSrc += sizeof(ParamCollectionHeader);
2416 while (index < cHeader->count) {
2417 if (stricmp(val, pSrc) == 0) {
2418 // if so, set the index to the correct entry
2419 cHeader->index = index;
2420 mutex->leave();
2421 return true;
2422 }
2423 index++;
2424 pSrc += strlen(pSrc) + 1;
2425 }
2426 mutex->leave();
2427 return false;
2428 }
2429 else {
2430 mutex->leave();
2431 return false;
2432 }
2433}
2434
2435bool ComponentMemory::setParameter(uint32 cid, const char* name, int64 val) {
2436 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2437 return false;
2439
2440 if (cid >= header->indexSize) {
2441 mutex->leave();
2442 return false;
2443 }
2444
2445 ParamHeader* pHeader = getParameter(cid, name);
2446 if (!pHeader) {
2447 mutex->leave();
2448 return 0;
2449 }
2450
2451 char* pSrc = ((char*)pHeader) + sizeof(ParamHeader) + strlen(((char*)pHeader) + sizeof(ParamHeader)) + 1;
2452
2453 if (pHeader->type == PARAM_INTEGER) {
2454 ((ParamIntegerHeader*) pSrc)->val = val;
2455 mutex->leave();
2456 return true;
2457 }
2458 else if (*(uint8*)pSrc == PARAM_INTEGER_COLL) {
2459 // See if the requested value is in the list
2461 uint32 index = 0;
2462 pSrc += sizeof(ParamCollectionHeader);
2463 while (index < cHeader->count) {
2464 if (*(int64*)pSrc == val) {
2465 // if so, set the index to the correct entry
2466 cHeader->index = index;
2467 mutex->leave();
2468 return true;
2469 }
2470 index++;
2471 pSrc += sizeof(int64);
2472 }
2473 mutex->leave();
2474 return false;
2475 }
2476 else {
2477 mutex->leave();
2478 return false;
2479 }
2480}
2481
2482bool ComponentMemory::setParameter(uint32 cid, const char* name, float64 val) {
2483 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2484 return false;
2486
2487 if (cid >= header->indexSize) {
2488 mutex->leave();
2489 return false;
2490 }
2491
2492 ParamHeader* pHeader = getParameter(cid, name);
2493 if (!pHeader) {
2494 mutex->leave();
2495 return 0;
2496 }
2497
2498 char* pSrc = ((char*)pHeader) + sizeof(ParamHeader) + strlen(((char*)pHeader) + sizeof(ParamHeader)) + 1;
2499
2500 if (pHeader->type == PARAM_FLOAT) {
2501 ((ParamFloatHeader*) pSrc)->val = val;
2502 mutex->leave();
2503 return true;
2504 }
2505 else if (*(uint8*)pSrc == PARAM_FLOAT_COLL) {
2506 // See if the requested value is in the list
2508 uint32 index = 0;
2509 pSrc += sizeof(ParamCollectionHeader);
2510 while (index < cHeader->count) {
2511 if (*(float64*)pSrc == val) {
2512 // if so, set the index to the correct entry
2513 cHeader->index = index;
2514 mutex->leave();
2515 return true;
2516 }
2517 index++;
2518 pSrc += sizeof(float64);
2519 }
2520 mutex->leave();
2521 return false;
2522 }
2523 else {
2524 mutex->leave();
2525 return false;
2526 }
2527}
2528
2529
2530bool ComponentMemory::resetParameter(uint32 cid, const char* name) {
2531 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2532 return false;
2534
2535 if (cid >= header->indexSize) {
2536 mutex->leave();
2537 return false;
2538 }
2539
2540 ParamHeader* pHeader = getParameter(cid, name);
2541 if (!pHeader) {
2542 mutex->leave();
2543 return 0;
2544 }
2545
2546 char* pSrc = ((char*)pHeader) + sizeof(ParamHeader) + strlen(((char*)pHeader) + sizeof(ParamHeader)) + 1;
2547
2548 if (pHeader->type == PARAM_INTEGER) {
2549 ((ParamIntegerHeader*)pSrc)->val = ((ParamIntegerHeader*)pSrc)->defaultVal;
2550 mutex->leave();
2551 return true;
2552 }
2553 else if (*(uint8*)pSrc == PARAM_INTEGER_COLL) {
2554 // Set index to default index
2555 ((ParamCollectionHeader*)pSrc)->index = ((ParamCollectionHeader*)pSrc)->defaultIndex;
2556 mutex->leave();
2557 return true;
2558 }
2559 else if (*(uint8*)pSrc == PARAM_FLOAT) {
2560 ((ParamFloatHeader*)pSrc)->val = ((ParamFloatHeader*)pSrc)->defaultVal;
2561 mutex->leave();
2562 return true;
2563 }
2564 else if (*(uint8*)pSrc == PARAM_FLOAT_COLL) {
2565 // Set index to default index
2566 ((ParamCollectionHeader*)pSrc)->index = ((ParamCollectionHeader*)pSrc)->defaultIndex;
2567 mutex->leave();
2568 return true;
2569 }
2570 else if (*(uint8*)pSrc == PARAM_STRING) {
2571 if (setParameter(cid, name, pSrc + strlen(pSrc) + 1)) {
2572 mutex->leave();
2573 return true;
2574 }
2575 else {
2576 mutex->leave();
2577 return false;
2578 }
2579 }
2580 else if (*(uint8*)pSrc == PARAM_STRING_COLL) {
2581 // Set index to default index
2582 ((ParamCollectionHeader*)pSrc)->index = ((ParamCollectionHeader*)pSrc)->defaultIndex;
2583 mutex->leave();
2584 return true;
2585 }
2586 else {
2587 mutex->leave();
2588 return false;
2589 }
2590}
2591
2592bool ComponentMemory::tweakParameter(uint32 cid, const char* name, int32 tweak) {
2593 if (!mutex || !mutex->enter(5000, __FUNCTION__))
2594 return false;
2596
2597 if (cid >= header->indexSize) {
2598 mutex->leave();
2599 return false;
2600 }
2601
2602 ParamHeader* pHeader = getParameter(cid, name);
2603 if (!pHeader) {
2604 mutex->leave();
2605 return false;
2606 }
2607
2608 char* pSrc = ((char*)pHeader) + sizeof(ParamHeader) + strlen(((char*)pHeader) + sizeof(ParamHeader)) + 1;
2609
2610 if ( (pHeader->type == PARAM_INTEGER_COLL) || (pHeader->type == PARAM_FLOAT_COLL) || (pHeader->type == PARAM_STRING_COLL) ) {
2612 if ( (cHeader->index + tweak >= 0) && (cHeader->index + tweak < cHeader->count) ) {
2613 cHeader->index += tweak;
2614 mutex->leave();
2615 return true;
2616 }
2617 else {
2618 mutex->leave();
2619 return false;
2620 }
2621 }
2622 else if (pHeader->type == PARAM_INTEGER) {
2623 ParamIntegerHeader* iHeader = (ParamIntegerHeader*)pSrc;
2624 if (iHeader->interval == 0) {
2625 mutex->leave();
2626 return false;
2627 }
2628 int64 testInt = iHeader->val + (tweak * iHeader->interval);
2629 if ( (iHeader->minVal == iHeader->maxVal) || ((testInt >= iHeader->minVal) && (testInt <= iHeader->maxVal)) ) {
2630 iHeader->val = testInt;
2631 mutex->leave();
2632 return true;
2633 }
2634 }
2635 else if (pHeader->type == PARAM_FLOAT) {
2636 ParamFloatHeader* fHeader = (ParamFloatHeader*)pSrc;
2637 if (fHeader->interval == 0) {
2638 mutex->leave();
2639 return false;
2640 }
2641 float64 testFloat = fHeader->val + (tweak * fHeader->interval);
2642 if ( (fHeader->minVal == fHeader->maxVal) || ( (testFloat >= fHeader->minVal) && (testFloat <= fHeader->maxVal)) ) {
2643 fHeader->val = testFloat;
2644 mutex->leave();
2645 return true;
2646 }
2647 }
2648 mutex->leave();
2649 return false;
2650}
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2671
2672 // First create and initialise the MemoryManager
2673 unittest::progress(5, "memory manager init");
2674 MemoryManager* manager = new MemoryManager();
2675 //uint32 maxPageCount = 100;
2676 if (!manager->create(0)) {
2677 unittest::fail("MemoryManager init() failed");
2678 delete(manager);
2679 return false;
2680 }
2681
2682 // Component creation and lookup
2683 unittest::progress(15, "component create and lookup");
2684 uint32 cid = 1, existingID;
2685 char* name = new char[1024];
2686 utils::strcpyavail(name, "TestComponent", 1024, true);
2687 if (!manager->componentMemory->createComponent(cid, COMP_INTERNAL, 0, SELFTRIGGER_WARN, name, 1024, 0, 0, 0, existingID)) {
2688 unittest::fail("Could not create component data");
2689 delete(manager);
2690 return false;
2691 }
2692 manager->componentMemory->confirmComponentID(cid);
2693
2694 char* str = new char[1024];
2695 if (!manager->componentMemory->getComponentName(cid, str, 1024)) {
2696 unittest::fail("Could not get component name");
2697 delete(manager);
2698 return false;
2699 }
2700 if (strcmp(name, str) != 0) {
2701 unittest::fail("Component name mismatch ('%s' != '%s')", name, str);
2702 delete(manager);
2703 return false;
2704 }
2705 unittest::detail("Created component '%s' with id %u", str, cid);
2706
2707 uint32 cid2;
2708 if (!manager->componentMemory->getComponentID(name, cid2)) {
2709 unittest::fail("Could not get component id");
2710 delete(manager);
2711 return false;
2712 }
2713 if (cid != cid2) {
2714 unittest::fail("Component id mismatch ('%u' != '%u')", cid, cid2);
2715 delete(manager);
2716 return false;
2717 }
2718
2719 // Private data set/get/resize/delete
2720 unittest::progress(30, "private data");
2721 if (!manager->componentMemory->setPrivateData(cid, "Private0", "Test", 5)) {
2722 unittest::fail("Component set private data failed");
2723 delete(manager);
2724 return false;
2725 }
2726
2727 if (!manager->componentMemory->setPrivateData(cid, "Private1", "Test", 5)) {
2728 unittest::fail("Component set private data failed");
2729 delete(manager);
2730 return false;
2731 }
2732
2733 if (manager->componentMemory->getPrivateDataSize(cid, "Private1") != 5) {
2734 unittest::fail("Component get private data size failed");
2735 delete(manager);
2736 return false;
2737 }
2738
2739 char* test = new char[1024];
2740 if (!manager->componentMemory->getPrivateData(cid, "Private1", test, 1024)) {
2741 unittest::fail("Component get private data failed");
2742 delete(manager);
2743 return false;
2744 }
2745
2746 if (strcmp("Test", test) != 0) {
2747 unittest::fail("Component get private data comparison failed");
2748 delete(manager);
2749 return false;
2750 }
2751
2752 if (!manager->componentMemory->setPrivateData(cid, "Private1", "Test2", 6)) {
2753 unittest::fail("Component set private data 2 failed");
2754 delete(manager);
2755 return false;
2756 }
2757
2758 if (manager->componentMemory->getPrivateDataSize(cid, "Private1") != 6) {
2759 unittest::fail("Component get private data size 2 failed");
2760 delete(manager);
2761 return false;
2762 }
2763
2764 if (!manager->componentMemory->getPrivateData(cid, "Private1", test, 1024)) {
2765 unittest::fail("Component get private data 2 failed");
2766 delete(manager);
2767 return false;
2768 }
2769
2770 if (strcmp("Test2", test) != 0) {
2771 unittest::fail("Component get private data comparison 2 failed");
2772 delete(manager);
2773 return false;
2774 }
2775
2776 if (!manager->componentMemory->deletePrivateData(cid, "Private1")) {
2777 unittest::fail("Component delete private data failed");
2778 delete(manager);
2779 return false;
2780 }
2781
2782
2783 // Scalar parameters: create/get/delete
2784 unittest::progress(45, "scalar parameters");
2785 if (!manager->componentMemory->createParameter(cid, "Param1", "Test")) {
2786 unittest::fail("Component create string param failed");
2787 delete(manager);
2788 return false;
2789 }
2790
2791 if (manager->componentMemory->createParameter(cid, "Param1", (int64)5)) {
2792 unittest::fail("Component create duplicate name failed to fail");
2793 delete(manager);
2794 return false;
2795 }
2796
2797 if (!manager->componentMemory->createParameter(cid, "Param2", (int64)5)) {
2798 unittest::fail("Component create integer param failed");
2799 delete(manager);
2800 return false;
2801 }
2802
2803 if (!manager->componentMemory->createParameter(cid, "Param3", 5.5)) {
2804 unittest::fail("Component create float param failed");
2805 delete(manager);
2806 return false;
2807 }
2808
2809 // Check the value of each
2810 if (manager->componentMemory->getParameterValueSize(cid, "Param1") != 5) {
2811 unittest::fail("Component get string param size failed");
2812 delete(manager);
2813 return false;
2814 }
2815
2816 if (!manager->componentMemory->getParameter(cid, "Param1", test, 1024)) {
2817 unittest::fail("Component get string param failed");
2818 delete(manager);
2819 return false;
2820 }
2821
2822 if (strcmp("Test", test) != 0) {
2823 unittest::fail("Component get string parameter comparison 2 failed");
2824 delete(manager);
2825 return false;
2826 }
2827
2828 int64 ival;
2829 if (!manager->componentMemory->getParameter(cid, "Param2", ival)) {
2830 unittest::fail("Component get integer param failed");
2831 delete(manager);
2832 return false;
2833 }
2834
2835 float64 fval;
2836 if (!manager->componentMemory->getParameter(cid, "Param3", fval)) {
2837 unittest::fail("Component get float param failed");
2838 delete(manager);
2839 return false;
2840 }
2841
2842 if (!manager->componentMemory->deleteParameter(cid, "Param2")) {
2843 unittest::fail("Component delete float param failed");
2844 delete(manager);
2845 return false;
2846 }
2847
2848 if (manager->componentMemory->getParameter(cid, "Param2", ival)) {
2849 unittest::fail("Component get integer param failed");
2850 delete(manager);
2851 return false;
2852 }
2853
2854 if (manager->componentMemory->getParameterValueSize(cid, "Param1") != 5) {
2855 unittest::fail("Component get string param size failed");
2856 delete(manager);
2857 return false;
2858 }
2859
2860 if (!manager->componentMemory->getParameter(cid, "Param3", fval)) {
2861 unittest::fail("Component get float param failed");
2862 delete(manager);
2863 return false;
2864 }
2865
2866 if (manager->componentMemory->getParameter(cid, "Param4", fval)) {
2867 unittest::fail("Component get non-existing param failed to fail");
2868 delete(manager);
2869 return false;
2870 }
2871
2872 // Create max min, tweak and check
2873 unittest::progress(60, "ranged and collection parameters");
2874 if (!manager->componentMemory->createParameter(cid, "Param4", (int64)5, 0, 10, 1)) {
2875 unittest::fail("Component create integer param 2 failed");
2876 delete(manager);
2877 return false;
2878 }
2879
2880 if (!manager->componentMemory->tweakParameter(cid, "Param4", 2)) {
2881 unittest::fail("Component tweak integer param failed");
2882 delete(manager);
2883 return false;
2884 }
2885
2886 if (!manager->componentMemory->getParameter(cid, "Param4", ival)) {
2887 unittest::fail("Component get integer param 2 failed");
2888 delete(manager);
2889 return false;
2890 }
2891
2892 if (ival != 7) {
2893 unittest::fail("Component tweak integer param result failed");
2894 delete(manager);
2895 return false;
2896 }
2897
2898 if (!manager->componentMemory->tweakParameter(cid, "Param4", -4)) {
2899 unittest::fail("Component tweak integer param 2 failed");
2900 delete(manager);
2901 return false;
2902 }
2903
2904 if (!manager->componentMemory->getParameter(cid, "Param4", ival)) {
2905 unittest::fail("Component get integer param 3 failed");
2906 delete(manager);
2907 return false;
2908 }
2909
2910 if (ival != 3) {
2911 unittest::fail("Component tweak integer param result 2 failed");
2912 delete(manager);
2913 return false;
2914 }
2915
2916 if (manager->componentMemory->tweakParameter(cid, "Param4", 8)) {
2917 unittest::fail("Component tweak integer param 2 failed to fail");
2918 delete(manager);
2919 return false;
2920 }
2921
2922 // Create collection, tweak and check
2923 int64 i64[] = {1,2,3,4,5};
2924 if (!manager->componentMemory->createParameter(cid, "Param5", i64, 5, 2)) {
2925 unittest::fail("Component create integer coll param failed");
2926 delete(manager);
2927 return false;
2928 }
2929
2930 if (!manager->componentMemory->getParameter(cid, "Param5", ival)) {
2931 unittest::fail("Component get integer param coll failed");
2932 delete(manager);
2933 return false;
2934 }
2935
2936 if (ival != 3) {
2937 unittest::fail("Component tweak integer coll param result failed");
2938 delete(manager);
2939 return false;
2940 }
2941
2942 if (!manager->componentMemory->tweakParameter(cid, "Param5", 2)) {
2943 unittest::fail("Component tweak integer coll param failed");
2944 delete(manager);
2945 return false;
2946 }
2947
2948 if (!manager->componentMemory->getParameter(cid, "Param5", ival)) {
2949 unittest::fail("Component get integer param coll 2 failed");
2950 delete(manager);
2951 return false;
2952 }
2953
2954 if (ival != 5) {
2955 unittest::fail("Component tweak integer coll param result 2 failed");
2956 delete(manager);
2957 return false;
2958 }
2959
2960 if (manager->componentMemory->tweakParameter(cid, "Param5", -5)) {
2961 unittest::fail("Component tweak integer coll param failed to fail");
2962 delete(manager);
2963 return false;
2964 }
2965
2966
2967 utils::strcpyavail(test, "Test1", 1024, true);
2968 utils::strcpyavail(test+6, "Test2", 1024, true);
2969 utils::strcpyavail(test+12, "Test3", 1024, true);
2970 utils::strcpyavail(test+18, "Test4", 1024, true);
2971 utils::strcpyavail(test+24, "Test5", 1024, true);
2972
2973 if (!manager->componentMemory->createParameter(cid, "Param6", test, 5, 2)) {
2974 unittest::fail("Component create string coll param failed");
2975 delete(manager);
2976 return false;
2977 }
2978
2979 if (!manager->componentMemory->getParameter(cid, "Param6", test, 1024)) {
2980 unittest::fail("Component get string param coll failed");
2981 delete(manager);
2982 return false;
2983 }
2984
2985 if (strcmp(test, "Test3") != 0) {
2986 unittest::fail("Component tweak string coll param result failed");
2987 delete(manager);
2988 return false;
2989 }
2990
2991 if (!manager->componentMemory->tweakParameter(cid, "Param6", 2)) {
2992 unittest::fail("Component tweak string coll param failed");
2993 delete(manager);
2994 return false;
2995 }
2996
2997 if (!manager->componentMemory->getParameter(cid, "Param6", test, 1024)) {
2998 unittest::fail("Component get string param coll 2 failed");
2999 delete(manager);
3000 return false;
3001 }
3002
3003 if (strcmp(test, "Test5") != 0) {
3004 unittest::fail("Component tweak string coll param result 2 failed");
3005 delete(manager);
3006 return false;
3007 }
3008
3009 if (manager->componentMemory->tweakParameter(cid, "Param6", -5)) {
3010 unittest::fail("Component tweak string coll param failed to fail");
3011 delete(manager);
3012 return false;
3013 }
3014
3015
3016
3017 if (!manager->componentMemory->deleteParameter(cid, "Param3")) {
3018 unittest::fail("Component delete float param failed");
3019 delete(manager);
3020 return false;
3021 }
3022
3023 if (!manager->componentMemory->destroyComponent(cid)) {
3024 unittest::fail("Could not destroy component");
3025 delete(manager);
3026 return false;
3027 }
3028
3029
3030 // ---- Location, flags and bounds accessors ----
3031 unittest::progress(66, "location/flags/bounds accessors");
3032 {
3033 uint32 lexisting;
3034 if (!manager->componentMemory->createComponent(7, COMP_INTERNAL, COMPONENT_CAN_MIGRATE, SELFTRIGGER_ALLOW, "LocComp", 256, 3, 4, 0, lexisting)) {
3035 unittest::fail("Loc: create failed"); delete(manager); return false;
3036 }
3038 uint16 nID = 99, pID = 99;
3039 if (!manager->componentMemory->getComponentLocation(7, nID, pID) || nID != 3 || pID != 4) {
3040 unittest::fail("Loc: getComponentLocation got node=%u proc=%u (want 3/4)", nID, pID); delete(manager); return false;
3041 }
3042 if (manager->componentMemory->getComponentNodeID(7) != 3 || manager->componentMemory->getComponentProcessID(7) != 4) {
3043 unittest::fail("Loc: node/proc id accessors mismatch"); delete(manager); return false;
3044 }
3046 unittest::fail("Loc: selfTrigger mismatch"); delete(manager); return false;
3047 }
3048 if (manager->componentMemory->getComponentType(7) != COMP_INTERNAL) {
3049 unittest::fail("Loc: type mismatch"); delete(manager); return false;
3050 }
3051 if (!manager->componentMemory->updateComponentLocation(7, 5, 6)) {
3052 unittest::fail("Loc: updateComponentLocation failed"); delete(manager); return false;
3053 }
3054 if (manager->componentMemory->getComponentProcessID(7) != 6 || manager->componentMemory->getComponentNodeID(7) != 5) {
3055 unittest::fail("Loc: location not updated"); delete(manager); return false;
3056 }
3057 // Out-of-range / unknown ids must fail gracefully (no crash / no false hit)
3058 uint16 bn, bp;
3059 if (manager->componentMemory->getComponentLocation(999999, bn, bp)) {
3060 unittest::fail("Loc: out-of-range id returned success"); delete(manager); return false;
3061 }
3062 if (manager->componentMemory->getComponentSelfTrigger(0) != 0) {
3063 unittest::fail("Loc: id 0 returned a self-trigger"); delete(manager); return false;
3064 }
3065 if (manager->componentMemory->getComponentName(999999, str, 1024)) {
3066 unittest::fail("Loc: out-of-range getComponentName returned success"); delete(manager); return false;
3067 }
3068 manager->componentMemory->destroyComponent(7);
3069 }
3070
3071
3072 // ---- Multi-component arena integrity: grow + middle-destroy shifts ----
3073 unittest::progress(70, "multi-component arena integrity");
3074 {
3075 const int NCOMP = 6;
3076 const uint32 baseID = 10;
3077 char cname[64], buf[4096], expect[64];
3078
3079 // Create several components, each with distinct private data of varying size
3080 for (int k = 0; k < NCOMP; k++) {
3081 snprintf(cname, sizeof(cname), "Comp%d", k);
3082 if (!manager->componentMemory->createComponent(baseID + k, COMP_INTERNAL, 0, SELFTRIGGER_ALLOW, cname, 512, 0, 0, 0, existingID)) {
3083 unittest::fail("Multi: create %s failed", cname); delete(manager); return false;
3084 }
3085 manager->componentMemory->confirmComponentID(baseID + k);
3086 snprintf(buf, sizeof(buf), "DATA-%d", k);
3087 if (!manager->componentMemory->setPrivateData(baseID + k, "P", buf, 64 + k * 24)) {
3088 unittest::fail("Multi: setPrivateData %s failed", cname); delete(manager); return false;
3089 }
3090 }
3091 // All names + private data intact
3092 for (int k = 0; k < NCOMP; k++) {
3093 snprintf(cname, sizeof(cname), "Comp%d", k);
3094 snprintf(expect, sizeof(expect), "DATA-%d", k);
3095 if (!manager->componentMemory->getComponentName(baseID + k, str, 1024) || strcmp(str, cname) != 0) {
3096 unittest::fail("Multi: name check Comp%d got '%s'", k, str); delete(manager); return false;
3097 }
3098 if (!manager->componentMemory->getPrivateData(baseID + k, "P", buf, sizeof(buf)) || strncmp(buf, expect, strlen(expect)) != 0) {
3099 unittest::fail("Multi: data check Comp%d got '%s' want '%s'", k, buf, expect); delete(manager); return false;
3100 }
3101 }
3102
3103 // Grow an EARLY component's private data -> forces resizeComponent to shift later blocks up
3104 memset(buf, 'Z', sizeof(buf));
3105 snprintf(buf, sizeof(buf), "BIGDATA-1");
3106 if (!manager->componentMemory->setPrivateData(baseID + 1, "P", buf, 2000)) {
3107 unittest::fail("Multi: grow Comp1 private data failed"); delete(manager); return false;
3108 }
3109 // Every component must still be intact after the shift
3110 for (int k = 0; k < NCOMP; k++) {
3111 snprintf(cname, sizeof(cname), "Comp%d", k);
3112 if (!manager->componentMemory->getComponentName(baseID + k, str, 1024) || strcmp(str, cname) != 0) {
3113 unittest::fail("Multi: post-grow name check Comp%d got '%s'", k, str); delete(manager); return false;
3114 }
3115 if (k == 1) snprintf(expect, sizeof(expect), "BIGDATA-1");
3116 else snprintf(expect, sizeof(expect), "DATA-%d", k);
3117 if (!manager->componentMemory->getPrivateData(baseID + k, "P", buf, sizeof(buf)) || strncmp(buf, expect, strlen(expect)) != 0) {
3118 unittest::fail("Multi: post-grow data check Comp%d got '%s' want '%s'", k, buf, expect); delete(manager); return false;
3119 }
3120 }
3121
3122 // Destroy a MIDDLE component (id 12, with higher-id components after it)
3123 if (!manager->componentMemory->destroyComponent(baseID + 2)) {
3124 unittest::fail("Multi: destroy middle component failed"); delete(manager); return false;
3125 }
3126 if (manager->componentMemory->getComponentName(baseID + 2, str, 1024)) {
3127 unittest::fail("Multi: destroyed Comp2 still present"); delete(manager); return false;
3128 }
3129 // All remaining components - especially those AFTER the destroyed one - must be intact
3130 for (int k = 0; k < NCOMP; k++) {
3131 if (k == 2) continue;
3132 snprintf(cname, sizeof(cname), "Comp%d", k);
3133 if (!manager->componentMemory->getComponentName(baseID + k, str, 1024) || strcmp(str, cname) != 0) {
3134 unittest::fail("Multi: post-destroy name check Comp%d got '%s'", k, str); delete(manager); return false;
3135 }
3136 if (k == 1) snprintf(expect, sizeof(expect), "BIGDATA-1");
3137 else snprintf(expect, sizeof(expect), "DATA-%d", k);
3138 if (!manager->componentMemory->getPrivateData(baseID + k, "P", buf, sizeof(buf)) || strncmp(buf, expect, strlen(expect)) != 0) {
3139 unittest::fail("Multi: post-destroy data check Comp%d got '%s' want '%s'", k, buf, expect); delete(manager); return false;
3140 }
3141 }
3142 // Cleanup remaining
3143 for (int k = 0; k < NCOMP; k++)
3144 if (k != 2) manager->componentMemory->destroyComponent(baseID + k);
3145 }
3146
3147
3148 // ---- addComponentStats: counters + recent-message ring retention ----
3149 unittest::progress(73, "component stats ring");
3150 {
3151 uint32 sexisting;
3152 if (!manager->componentMemory->createComponent(20, COMP_INTERNAL, 0, SELFTRIGGER_ALLOW, "StatComp", 256, 0, 0, 0, sexisting)) {
3153 unittest::fail("Stats: create failed"); delete(manager); return false;
3154 }
3155 manager->componentMemory->confirmComponentID(20);
3156
3157 DataMessage inMsg, outMsg;
3158 inMsg.setString("K", "in");
3159 outMsg.setString("K", "out");
3160 uint32 inBytes = inMsg.getSize(), outBytes = outMsg.getSize();
3161
3162 manager->componentMemory->addComponentStats(20, COMPSTATUS_RUNNING, 100, &inMsg, &outMsg, 1, 2);
3164 if (s.msgInCount != 1 || s.msgOutCount != 1 || s.runCount != 1 || s.cycleCount != 2 ||
3165 s.usageCPUTicks != 100 || s.msgInBytes != inBytes || s.msgOutBytes != outBytes) {
3166 unittest::fail("Stats: counters wrong (in=%llu out=%llu run=%llu cyc=%llu cpu=%llu)",
3168 delete(manager); return false;
3169 }
3170
3171 // Push 12 more input messages with a unique sequence id each (ring depth is 10)
3172 for (int k = 1; k <= 12; k++) {
3173 DataMessage m;
3174 m.setInt("Seq", (int64)k);
3175 manager->componentMemory->addComponentStats(20, COMPSTATUS_RUNNING, 0, &m, NULL, 0, 0);
3176 }
3177 s = manager->componentMemory->getComponentStats(20);
3178 if (s.msgInCount != 13) {
3179 unittest::fail("Stats: msgInCount %llu (want 13)", s.msgInCount); delete(manager); return false;
3180 }
3181 // The 10 most recent input messages must be retained: Seq 3..12 present, 1/2 evicted, newest present.
3182 bool seen[13]; for (int k = 0; k < 13; k++) seen[k] = false;
3183 int present = 0;
3184 for (int n = 0; n < 10; n++) {
3185 char* slot = s.recentInMsg + (n * DRAFTMSGSIZE);
3186 if (!((DataMessageHeader*)slot)->time)
3187 continue;
3188 present++;
3189 DataMessage m(slot, true);
3190 bool ok = false;
3191 int64 seq = m.getInt("Seq", ok);
3192 if (ok && seq >= 1 && seq <= 12)
3193 seen[seq] = true;
3194 }
3195 if (present != 10) {
3196 unittest::fail("Stats: ring holds %d messages (want 10)", present); delete(manager); return false;
3197 }
3198 if (seen[1] || seen[2]) {
3199 unittest::fail("Stats: ring did not evict oldest (Seq 1/2 still present)"); delete(manager); return false;
3200 }
3201 for (int k = 3; k <= 12; k++) {
3202 if (!seen[k]) {
3203 unittest::fail("Stats: ring missing recent message Seq %d", k); delete(manager); return false;
3204 }
3205 }
3206 manager->componentMemory->destroyComponent(20);
3207 }
3208
3209
3210 // ---- Name lookup across multiple components ----
3211 unittest::progress(74, "name lookup");
3212 {
3213 uint32 nexisting, gotID;
3214 manager->componentMemory->createComponent(30, COMP_INTERNAL, 0, SELFTRIGGER_ALLOW, "Alpha", 128, 0, 0, 0, nexisting);
3215 manager->componentMemory->confirmComponentID(30);
3216 manager->componentMemory->createComponent(31, COMP_INTERNAL, 0, SELFTRIGGER_ALLOW, "Beta", 128, 0, 0, 0, nexisting);
3217 manager->componentMemory->confirmComponentID(31);
3218 if (!manager->componentMemory->getComponentID("Beta", gotID) || gotID != 31) {
3219 unittest::fail("Name: lookup 'Beta' got %u (want 31)", gotID); delete(manager); return false;
3220 }
3221 if (!manager->componentMemory->getComponentID("Alpha", gotID) || gotID != 30) {
3222 unittest::fail("Name: lookup 'Alpha' got %u (want 30)", gotID); delete(manager); return false;
3223 }
3224 if (manager->componentMemory->getComponentID("DoesNotExist", gotID)) {
3225 unittest::fail("Name: lookup of missing name returned success"); delete(manager); return false;
3226 }
3227 manager->componentMemory->destroyComponent(30);
3228 manager->componentMemory->destroyComponent(31);
3229 }
3230
3231
3232 // Type levels
3233 unittest::progress(75, "type levels");
3234 uint16 tidt, existingID16;
3235 if (!manager->dataMapsMemory->createNewTypeLevel(1, "Type1", 0, existingID16)) {
3236 unittest::fail("Could not create new type");
3237 delete(manager);
3238 return false;
3239 }
3241
3242 if (!manager->dataMapsMemory->createNewTypeLevel(2, "Type2", 0, existingID16)) {
3243 unittest::fail("Could not create new type 2");
3244 delete(manager);
3245 return false;
3246 }
3248
3249 if (!manager->dataMapsMemory->getTypeLevelID("Type2", tidt)) {
3250 unittest::fail("Could not get type id");
3251 delete(manager);
3252 return false;
3253 }
3254
3255 if (2 != tidt) {
3256 unittest::fail("Type id mismatch");
3257 delete(manager);
3258 return false;
3259 }
3260
3261 if (!manager->dataMapsMemory->getTypeLevelName(2, test, 1024)) {
3262 unittest::fail("Could not get type name");
3263 delete(manager);
3264 return false;
3265 }
3266
3267 if (strcmp(test, "Type2")) {
3268 unittest::fail("Type name mismatch");
3269 delete(manager);
3270 return false;
3271 }
3272
3273
3274
3275 // Tags
3276 unittest::progress(88, "tags");
3277 uint32 idt;
3278 if (!manager->dataMapsMemory->createNewTag(1, "Tag1", 0, existingID)) {
3279 unittest::fail("Could not create new tag");
3280 delete(manager);
3281 return false;
3282 }
3283 manager->dataMapsMemory->confirmTagID(1);
3284
3285 if (!manager->dataMapsMemory->createNewTag(2, "Tag2", 0, existingID)) {
3286 unittest::fail("Could not create new tag 2");
3287 delete(manager);
3288 return false;
3289 }
3290 manager->dataMapsMemory->confirmTagID(2);
3291
3292 if (!manager->dataMapsMemory->getTagID("Tag2", idt)) {
3293 unittest::fail("Could not get tag id");
3294 delete(manager);
3295 return false;
3296 }
3297
3298 if (2 != idt) {
3299 unittest::fail("Tag id mismatch");
3300 delete(manager);
3301 return false;
3302 }
3303
3304 if (!manager->dataMapsMemory->getTagName(2, test, 1024)) {
3305 unittest::fail("Could not get tag name");
3306 delete(manager);
3307 return false;
3308 }
3309
3310 if (strcmp(test, "Tag2")) {
3311 unittest::fail("Tag name mismatch");
3312 delete(manager);
3313 return false;
3314 }
3315
3316 delete [] str;
3317 delete [] test;
3318 delete [] name;
3319 delete(manager);
3320 unittest::progress(100, "done");
3321 return true;
3322}
3323
3326 "Component memory: components, private data, parameters, type levels, tags", "memory");
3327}
3328
3329
3330
3331} // namespace cmlabs
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
#define PARAM_FLOAT_COLL
#define PARAM_STRING_COLL
#define PARAM_INTEGER_COLL
#define PARAM_INTEGER
#define PARAM_STRING
#define PARAM_FLOAT
Shared-memory component registry: identity, location, parameters, private data and statistics for eve...
#define COMPSTATUS_STARTING
Component is starting up.
#define CHECKCOMPONENTMEMORYSERIALRETURN(a)
#define SELFTRIGGER_ALLOW
Explicitly allowed.
#define COMPONENT_CAN_MIGRATE
Migration-policy flag: component may be moved to another process/node.
#define GETCOMPOFFSET(header, id)
Offset value for component id (0 = not present).
#define SELFTRIGGER_WARN
Allowed but logged as a warning.
#define GETCOMPDATA(header, id)
Record pointer for component id, or NULL.
#define COMPINFOUSAGE(info)
Total bytes used by a component record including its parameter and private-data areas.
#define COMPSTATUS_RUNNING
Component is executing a run.
#define GETCOMPOFFSETP(header, id)
Pointer to the offset slot for component id.
#define CHECKCOMPONENTMEMORYSERIAL
Re-open the component segment if the master's resize serial no longer matches ours; bails out of the ...
#define DRAFTMSGSIZE
Fixed byte size of the per-message draft slots used in the recent-message rings of ComponentStats / P...
#define COMPONENTMEMORYID
Definition ObjectIDs.h:50
#define COMP_WHITEBOARD
Whiteboard: publish/subscribe message store with retention.
#define COMP_EXTERNAL
External module running outside the node process.
#define COMP_INTERNAL
Internal module (same id as COMP_MODULE).
#define COMP_CATALOG
Catalog: keyed/queryable data store.
Small, dependency-free unit test harness used by all CMSDK object tests.
#define MAXKEYNAMELEN
Definition Utils.h:85
#define stricmp
Definition Utils.h:132
#define LOG_MEMORY
Definition Utils.h:199
#define LogPrint
Definition Utils.h:313
bool setParameter(uint32 cid, const char *name, const char *val)
bool writeComponentsToMsg(DataMessage *msg)
Serialize all component records into msg.
bool create(uint32 indexSize)
Create the component segment (master only).
uint16 getComponentNodeID(uint32 cid)
bool getComponentName(uint32 cid, char *name, uint32 maxNameLen)
Copy the component name into name.
bool open()
Attach to the existing component segment.
bool getParameterAsBool(uint32 cid, const char *name)
bool syncComponents(DataMessage *msg)
Merge component records received from a remote node.
std::string getComponentNameString(uint32 cid)
bool updateComponentInformation(uint32 cid, uint8 type, uint8 policy, uint8 selfTrigger, uint16 nodeID, uint16 procID)
Update type/policy/self-trigger/location in one call.
bool deletePrivateData(uint32 cid, const char *name)
Delete blob name.
bool updateComponentLocation(uint32 cid, uint16 nodeID, uint16 procID)
Record a new location (after migration).
std::vector< ComponentInfoStruct > * getAllModules()
Snapshot all module components.
uint8 getParameterDataType(uint32 cid, const char *name)
bool deleteParameter(uint32 cid, const char *name)
Remove the parameter.
bool setComponentStats(uint32 cid, ComponentStats &stats)
Overwrite the component's stats.
bool cancelComponentID(uint32 id)
Release a provisionally reserved component id.
bool getComponentID(const char *name, uint32 &cid)
Look up a component id by name.
AveragePerfStats getComponentPerfStats(uint32 cid)
uint16 getComponentProcessID(uint32 cid)
bool setComponentData(uint32 cid, const char *data, uint64 size, bool wasMigrated)
Replace a component's data area (after migration).
bool addLocalPerformanceStats(std::list< PerfStats > &perfStats)
Append PerfStats for all local components.
bool tweakParameter(uint32 cid, const char *name, int32 tweak)
Step the value by tweak * interval (or collection index).
char * getPrivateDataCopy(uint32 cid, const char *name, uint64 &size)
ComponentMemory(MasterMemory *master)
std::list< std::string > getPrivateDataKeys(uint32 cid)
uint8 lookupComponentID(const char *name, uint32 &id)
Look up a component by name without filtering on readiness.
bool destroyComponent(uint32 cid)
Remove a component record and free its space.
float64 getParameterFloat(uint32 cid, const char *name)
uint32 getParameterValueSize(uint32 cid, const char *name)
uint8 getComponentPolicy(uint32 cid)
bool confirmComponentID(uint32 id)
Mark a provisionally reserved component id as ready (syncStatus 2).
bool getPrivateData(uint32 cid, const char *name, char *data, uint64 maxSize)
Copy blob into caller buffer data (max maxSize).
bool canComponentMigrate(uint32 cid)
std::string getPrivateDataMimetype(uint32 cid, const char *name)
bool getComponentLocation(uint32 cid, uint16 &nodeID, uint16 &procID)
Get the node/process the component runs in.
std::list< uint16 > * findProcessComponents(uint16 procID)
List ids of components in process procID.
std::vector< ComponentInfoStruct > * getAllComponents()
Snapshot all components.
uint64 getPrivateDataSize(uint32 cid, const char *name)
std::vector< ComponentInfoStruct > * getAllCatalogs()
Snapshot all catalog components.
bool setComponentPerfStats(uint32 cid, AveragePerfStats &perfStruct)
Store new performance averages.
char * getComponentData(uint32 cid, uint64 &size)
Copy a component's whole data area (for migration).
static bool UnitTest()
Self-test.
bool hasParameter(uint32 cid, const char *name)
std::map< std::string, std::string > getPrivateDataKeysAndTypes(uint32 cid)
uint8 getComponentSelfTrigger(uint32 cid)
bool createComponent(uint32 id, uint8 type, uint8 policy, uint8 selfTrigger, const char *name, uint64 size, uint16 nodeID, uint16 procID, uint64 time, uint32 &existingID)
Register a component record.
bool isComponentLocal(uint32 cid)
bool addComponentStats(uint32 cid, uint8 status, uint64 usageCPUTicks, DataMessage *inputMsg, DataMessage *outputMsg, uint32 runCount, uint32 cycleCount)
Fold a run's activity into the component's stats (counters, rings, CPU ticks).
bool setComponentPolicy(uint32 cid, uint8 policy)
Set the migration policy.
bool getParameter(uint32 cid, const char *name, char *val, uint32 maxSize)
bool resetParameter(uint32 cid, const char *name)
Restore the parameter's default value/index.
std::vector< ComponentInfoStruct > * getAllLocalComponents()
Snapshot components on this node.
uint8 getComponentType(uint32 cid)
ComponentStats getComponentStats(uint32 cid)
bool setPrivateData(uint32 cid, const char *name, const char *data, uint64 size, const char *mimetype=NULL)
Create/replace blob name.
std::string toXML(bool stats=true)
int64 getParameterInt(uint32 cid, const char *name)
std::string getParameterString(uint32 cid, const char *name, uint32 maxSize)
bool createParameter(uint32 cid, const char *name, const char *val, const char *defaultValue=NULL)
bool writeComponentNamesToMsg(DataMessage *msg)
Write just the component names into msg.
bool setComponentSelfTrigger(uint32 cid, uint8 selfTrigger)
Set the self-trigger policy.
bool getMemoryUsage(uint64 &alloc, uint64 &usage)
Report allocation/usage of the component segment.
bool getTypeLevelID(const char *name, uint16 &id)
bool createNewTag(uint32 id, const char *name, uint64 time, uint32 &existingID)
bool getTagName(uint32 id, char *name, uint32 maxSize)
bool getTagID(const char *name, uint32 &id)
bool confirmTypeLevelID(uint16 id)
bool createNewTypeLevel(uint16 id, const char *name, uint64 time, uint16 &existingID)
bool confirmTagID(uint32 id)
bool getTypeLevelName(uint16 id, char *name, uint32 maxSize)
The central Psyclone data container: a self-contained binary message with typed, named user entries.
bool setString(const char *key, const char *value)
setString(const char* key, const char* value)
bool getInt(const char *key, int64 &value)
getInt(const char* key, int64& value)
bool setInt(const char *key, int64 value)
setInt(const char* key, int64 value)
DataMessageHeader * data
Pointer to the message's flat memory block (header + user entries).
uint32 getSize()
getSize() Get message size Many types of data of any size can be put into a message as user entries; ...
uint64 getTime(const char *key)
getTime(const char* key)
const char * getString(const char *key)
getString(const char* key)
Handle to the node's master shared-memory segment (MemoryMasterStruct).
Top-level facade of the shared-memory subsystem for one process.
ComponentMemory * componentMemory
Accessor for the component registry.
bool create(uint16 sysID, uint32 slotCount=100000, uint16 binCount=2, uint32 minBlockSize=1024, uint32 maxBlockSize=64 *1024, uint64 initSize=50000000L, uint64 maxSize=1000000000L, bool force=false)
Create all shared segments for a new node instance (master process only).
DataMapsMemory * dataMapsMemory
Accessor for the type/context/tag/crank/request maps.
static UnitTestRunner & instance()
Access the singleton (created on first use).
void registerTest(const char *name, UnitTestFunc func, const char *description="", const char *category="", bool inDefaultRun=true)
Register a test with the runner.
Recursive mutual-exclusion lock, optionally named for cross-process use.
Definition Utils.h:463
uint64 GetTimeNow()
Return the current absolute time (µs since year 0) according to the TMC.
Definition PsyTime.cpp:69
char * OpenSharedMemorySegment(const char *name, uint64 size)
Open and map an existing named shared memory segment.
Definition Utils.cpp:2259
char * CreateSharedMemorySegment(const char *name, uint64 size, bool force=false)
Create a named shared memory segment and map it into this process.
Definition Utils.cpp:2156
bool CloseSharedMemorySegment(char *data, uint64 size)
Unmap a segment previously created/opened here.
Definition Utils.cpp:2374
std::string BytifySize(double val)
Format a byte count with binary units, e.g.
Definition Utils.cpp:7724
std::string StringFormat(const char *format,...)
printf into a std::string.
Definition Utils.cpp:6626
int64 Ascii2Int64(const char *ascii, uint32 start=0, uint32 end=0)
Parse a signed 64-bit decimal integer from a substring.
Definition Utils.cpp:7462
uint32 strcpyavail(char *dst, const char *src, uint32 maxlen, bool copyAvailable)
Bounded strcpy that always NUL-terminates.
Definition Utils.cpp:6056
float64 Ascii2Float64(const char *ascii, uint32 start=0, uint32 end=0)
Parse a 64-bit float from a substring (decimal point, not locale dependent).
Definition Utils.cpp:7546
void fail(const char *fmt,...)
Set an explanatory reason shown on the FAIL line.
void detail(const char *fmt,...)
Verbose-only indented diagnostic line (shown only when verbose=1).
void progress(int percent, const char *action)
Report progress with a short description of the current action.
void Register_ComponentMemory_Tests()
Sliding-window averages derived from successive PerfStats snapshots.
One component's registry record in shared memory.
uint16 nodeID
Node the component currently runs on.
uint8 policy
Migration policy (COMPONENT_CAN_MIGRATE flag).
uint64 size
Total record size in bytes including parameter and data areas.
uint8 type
Component type (Whiteboard, Catalog, Module, ...).
uint8 selfTrigger
SELFTRIGGER_* policy.
char name[MAXKEYNAMELEN]
Component name (unique per system).
uint64 createdTime
Creation timestamp (µs).
uint16 procID
Process (space) the component currently runs in.
uint8 status
COMPSTATUS_* run status.
uint8 syncStatus
Cluster sync status (0: not there, 1: in-sync, 2: ready).
Root header of the component-memory segment.
uint32 cid
Check/magic id validated on attach.
Legacy per-component throughput counters (DataMessageHeader-based rings).
uint64 usageCPUTicks
Cumulative CPU ticks consumed.
uint32 migrationCount
Times this component has migrated.
uint64 msgInBytes
Total bytes received.
uint64 msgInCount
Total messages received.
uint64 cycleCount
Total processing cycles.
uint64 time
Timestamp of the last update (µs).
uint64 currentRunStartTime
Timestamp the current/last run started (µs).
uint64 runCount
Total runs.
uint64 msgOutBytes
Total bytes posted.
DataMessageHeader recentInMsg[10]
uint64 firstRunStartTime
Timestamp of the first run (µs).
DataMessageHeader recentOutMsg[10]
uint64 msgOutCount
Total messages posted.
The current (version 10) DataMessage wire/shared-memory header.
uint32 size
Total size of the whole message block in bytes (header + all entries).
Value block of a PARAM_*_COLL parameter; followed by the packed collection values.
uint32 defaultIndex
Entry restored by resetParameter().
uint32 index
Currently selected entry.
uint32 count
Number of entries in the collection.
Value block of a PARAM_FLOAT parameter.
float64 interval
Step used by tweakParameter().
float64 minVal
Inclusive lower bound.
float64 maxVal
Inclusive upper bound.
float64 defaultVal
Value restored by resetParameter().
float64 val
Current value.
Size- and type-prefixed parameter entry stored after a component record.
uint32 size
Total entry size in bytes including this header.
uint8 type
PARAM_* data type.
Value block of a PARAM_INTEGER parameter.
int64 defaultVal
Value restored by resetParameter().
int64 maxVal
Inclusive upper bound.
int64 interval
Step used by tweakParameter().
int64 minVal
Inclusive lower bound (0 = unbounded when max also 0).
Raw per-component performance counters sampled inside shared memory.
Size-prefixed private-data entry stored after a component record.
uint64 size
Total entry size in bytes including this header.