CMSDK 2.0.1
Cross-platform C++ base library and SDK for the Psyclone AIOS platform
Loading...
Searching...
No Matches
MemoryMaps.tpl.h
Go to the documentation of this file.
1
25
26#include "Utils.h"
27
28namespace cmlabs {
29
45template <typename T, typename ID>
46T* GenericMemoryMap<T,ID>::CreateEntry(char* data, ID id, const char* name) {
47 T* entry = NULL;
48 if (data == NULL) {
49 fprintf(stderr, "CreateEntry %u no data provided\n", id);
50 return NULL;
51 }
52 GenericMapHeader* header = (GenericMapHeader*)data;
53
54 if (id >= header->maxID) {
55 fprintf(stderr, "CreateEntry bit location %u out of range\n", id);
56 return NULL;
57 }
58
59 //printf("{%X} {%X} {%X} {%X}\n",
60 // *(uint32*)((char*)header + sizeof(GenericMapHeader)),
61 // *(uint32*)((char*)header + sizeof(GenericMapHeader) + 4),
62 // *(uint32*)((char*)header + sizeof(GenericMapHeader) + 8),
63 // *(uint32*)((char*)header + sizeof(GenericMapHeader) + 12) ); fflush(stdout);
64
65 bit check;
66 if (!utils::GetBit(id, ((char*)header + sizeof(GenericMapHeader)), header->bitFieldSize, check) || (check == BITOCCUPIED)) {
67 //fprintf(stderr, "CreateEntry bit location %u already in use\n", id);
68 // Already in use, let's check if it is the same one
69 entry = GetEntry(data, id);
70 if (entry && (strcmp(name, entry->name) == 0)) {
71 // Same entry name, return this existing one
72 return entry;
73 }
74 else
75 return NULL;
76 }
77
78 // Reserve it
79 utils::SetBit(id, BITOCCUPIED, ((char*)header + sizeof(GenericMapHeader)), header->bitFieldSize);
80
81 // Calc offset
82 uint32 offset = sizeof(GenericMapHeader) + header->bitFieldSize + id * sizeof(T);
83 if (offset > header->size) {
84 fprintf(stderr, "CreateEntry offset error in Memory Map\n");
85 return NULL;
86 }
87 entry = (T*) (data+offset);
88 if ((entry->id == id) || (entry->time == 0)) {
89 entry->id = id;
90 entry->status = 1; // only assigned, not ready
91 entry->time = GetTimeNow();
92 if (name != NULL)
93 utils::strcpyavail(entry->name, name, MAXKEYNAMELEN, true);
94 header->count++;
95 return entry;
96 }
97 else {
98 fprintf(stderr, "CreateEntry entry error in Memory Map\n");
99 return NULL;
100 }
101}
102
103
116template <typename T, typename ID>
117T* GenericMemoryMap<T,ID>::CreateFirstFreeEntry(char* data, ID &id, const char* name) {
118 T* entry = NULL;
119 if (data == NULL)
120 return NULL;
121 GenericMapHeader* header = (GenericMapHeader*)data;
122
123 //printf("{%X} {%X} {%X} {%X}\n",
124 // *(uint32*)((char*)header + sizeof(GenericMapHeader)),
125 // *(uint32*)((char*)header + sizeof(GenericMapHeader) + 4),
126 // *(uint32*)((char*)header + sizeof(GenericMapHeader) + 8),
127 // *(uint32*)((char*)header + sizeof(GenericMapHeader) + 12) ); fflush(stdout);
128
129 uint32 loc;
130 if (!utils::GetFirstFreeBitLoc(((char*)header + sizeof(GenericMapHeader)), header->bitFieldSize, loc) || (loc >= header->maxID)) {
131 fprintf(stderr, "No more bit locations available\n");
132 return NULL;
133 }
134
135 // Reserve it
136 id = (ID)loc;
137 utils::SetBit(id, BITOCCUPIED, ((char*)header + sizeof(GenericMapHeader)), header->bitFieldSize);
138
139 // Calc offset
140 uint32 offset = sizeof(GenericMapHeader) + header->bitFieldSize + id * sizeof(T);
141 if (offset > header->size) {
142 fprintf(stderr, "Offset error in Memory Map\n");
143 return NULL;
144 }
145 entry = (T*) (data+offset);
146 if ((entry->id == id) || (entry->time == 0)) {
147 entry->id = id;
148 entry->status = 1; // only assigned, not ready
149 entry->time = GetTimeNow();
150 if (name != NULL)
151 utils::strcpyavail(entry->name, name, MAXKEYNAMELEN, true);
152 header->count++;
153 return entry;
154 }
155 else {
156 fprintf(stderr, "Entry error in Memory Map\n");
157 return NULL;
158 }
159}
160
170template <typename T, typename ID>
171bool GenericMemoryMap<T,ID>::DeleteEntry(char* data, ID id) {
172 T* entry = NULL;
173 if (data == NULL)
174 return false;
175 GenericMapHeader* header = (GenericMapHeader*)data;
176
177 // Calc offset
178 uint32 offset = sizeof(GenericMapHeader) + header->bitFieldSize + id * sizeof(T);
179 if (offset > header->size)
180 return false;
181 entry = (T*) (data+offset);
182 if ((entry->id != id) || (entry->time == 0))
183 return false;
184
185 // Free it
186 entry->time = 0;
187 header->count--;
188 utils::SetBit(id, BITFREE, ((char*)header + sizeof(GenericMapHeader)), header->bitFieldSize);
189 return true;
190}
191
192
195template <typename T, typename ID>
196uint64 GenericMemoryMap<T,ID>::GetEntryTime(char* data, ID id) {
197 T* entry = GetEntry(data, id);
198 if (entry == NULL)
199 return 0;
200 return entry->time;
201}
202
212template <typename T, typename ID>
213T* GenericMemoryMap<T,ID>::GetEntry(char* data, ID id) {
214 T* entry = NULL;
215 if (data == NULL)
216 return NULL;
217 GenericMapHeader* header = (GenericMapHeader*)data;
218
219 // Calc offset
220 uint32 offset = sizeof(GenericMapHeader) + header->bitFieldSize + id * sizeof(T);
221 if (offset > header->size)
222 return NULL;
223 entry = (T*) (data+offset);
224 if ((entry->id == id) && (entry->time != 0) && (entry->status > 1))
225 return entry;
226 else
227 return NULL;
228}
229
236template <typename T, typename ID>
238 T* entry = NULL;
239 if (data == NULL)
240 return false;
241 GenericMapHeader* header = (GenericMapHeader*)data;
242
243 // Calc offset
244 uint32 offset = sizeof(GenericMapHeader) + header->bitFieldSize + id * sizeof(T);
245 if (offset > header->size)
246 return false;
247 entry = (T*) (data+offset);
248 if ((entry->id == id) && entry->time && (entry->status >= 1)) {
249 entry->status = 2;
250 return true;
251 }
252 else
253 return false;
254}
255
264template <typename T, typename ID>
265bool GenericMemoryMap<T,ID>::CancelEntry(char* data, ID id) {
266 T* entry = NULL;
267 if (data == NULL)
268 return false;
269 GenericMapHeader* header = (GenericMapHeader*)data;
270
271 // Calc offset
272 uint32 offset = sizeof(GenericMapHeader) + header->bitFieldSize + id * sizeof(T);
273 if (offset > header->size)
274 return false;
275 entry = (T*) (data+offset);
276 if ((entry->id == id) && entry->time && (entry->status <= 1)) {
277 entry->status = 0;
278 entry->time = 0;
279 return true;
280 }
281 else if ((entry->id == 0) || (entry->status == 0))
282 return true;
283 else
284 return false;
285}
286
291template <typename T, typename ID>
292bool GenericMemoryMap<T,ID>::GetEntryName(char* data, ID id, char* name, uint32 maxSize) {
293 T* entry = GetEntry(data, id);
294 if (entry == NULL)
295 return false;
296 return (utils::strcpyavail(name, entry->name, maxSize, true) > 0);
297}
298
310template <typename T, typename ID>
311ID GenericMemoryMap<T,ID>::GetEntryID(char* data, const char* name, bool force) {
312 T* entry = NULL;
313 if (data == NULL)
314 return 0;
315 GenericMapHeader* header = (GenericMapHeader*)data;
316
317 entry = (T*) (data + sizeof(GenericMapHeader) + header->bitFieldSize);
318 while ((uint32)((char*)entry - data) < header->size) {
319 if (stricmp(name, entry->name) == 0) {
320 if ((entry->status > 1) || force)
321 return entry->id;
322 else
323 return 0;
324 }
325 entry = entry + 1; //sizeof(TypeMapEntry);
326 }
327 return 0;
328}
329
338template <typename T, typename ID>
339uint8 GenericMemoryMap<T,ID>::LookupEntryID(char* data, const char* name, ID& id) {
340 T* entry = NULL;
341 if (data == NULL)
342 return 0;
343 GenericMapHeader* header = (GenericMapHeader*)data;
344
345 uint32 n = 0;
346 entry = (T*) (data + sizeof(GenericMapHeader) + header->bitFieldSize);
347 while ((uint32)((char*)entry - data) < header->size) {
348 if (stricmp(name, entry->name) == 0) {
349 id = entry->id;
350 return entry->status;
351 }
352 n++;
353 entry = entry + 1; //sizeof(TypeMapEntry);
354 }
355 return 0;
356}
357
360template <typename T, typename ID>
362 std::string str;
363 T* entry = NULL;
364 if (data == NULL)
365 return 0;
366 GenericMapHeader* header = (GenericMapHeader*)data;
367
368 entry = (T*) (data + sizeof(GenericMapHeader) + header->bitFieldSize);
369 while ((uint32)((char*)entry - data) < header->size) {
370 if (entry->id) {
371 if (entry->status > 1)
372 str += utils::StringFormat("%u = %s (%s)\n", entry->id, entry->name, PrintTimeString(entry->time).c_str());
373 else
374 str += utils::StringFormat("*%u = %s (%s)\n", entry->id, entry->name, PrintTimeString(entry->time).c_str());
375 }
376 entry = entry + 1; //sizeof(TypeMapEntry);
377 }
378 return str;
379}
380
383template <typename T, typename ID>
385 std::string str;
386 T* entry = NULL;
387 if (data == NULL)
388 return 0;
389 GenericMapHeader* header = (GenericMapHeader*)data;
390
391 entry = (T*) (data + sizeof(GenericMapHeader) + header->bitFieldSize);
392 while ((uint32)((char*)entry - data) < header->size) {
393 if (entry->id) {
394 if (entry->status > 1)
395 str += utils::StringFormat("<tr><td>%u</td><td>%s</td><td>%s</td></tr>", entry->id, entry->name, PrintTimeString(entry->time).c_str());
396 else
397 str += utils::StringFormat("<tr><td>%**u</td><td>%s</td><td>%s</td></tr>\n", entry->id, entry->name, PrintTimeString(entry->time).c_str());
398 }
399 entry = entry + 1; //sizeof(TypeMapEntry);
400 }
401 return str;
402}
403
406template <typename T, typename ID>
407std::string GenericMemoryMap<T,ID>::ToXML(char* data) {
408 std::string str;
409 T* entry = NULL;
410 if (data == NULL)
411 return 0;
412 GenericMapHeader* header = (GenericMapHeader*)data;
413
414 uint32 count = 0;
415 entry = (T*) (data + sizeof(GenericMapHeader) + header->bitFieldSize);
416 while ((uint32)((char*)entry - data) < header->size) {
417 if (entry->id) {
418 str += entry->toXML();
419 count++;
420 }
421 entry = entry + 1; //sizeof(TypeMapEntry);
422 }
423 std::string outerName = T::GetOuterXMLName();
424 if (!count)
425 return utils::StringFormat("<%s count=\"%u\" />\n", outerName.c_str(), count);
426 else
427 return utils::StringFormat("<%s count=\"%u\">\n%s</%s>\n", outerName.c_str(), count, str.c_str(), outerName.c_str());
428}
429
433template <typename T, typename ID>
434bool GenericMemoryMap<T, ID>::WriteAllIDsToMsg(const char* arrayname, char* data, DataMessage* msg) {
435 T* entry = NULL;
436 if (data == NULL)
437 return false;
438 GenericMapHeader* header = (GenericMapHeader*)data;
439
440 uint32 n = 0;
441 entry = (T*)(data + sizeof(GenericMapHeader) + header->bitFieldSize);
442 while ((uint32)((char*)entry - data) < header->size) {
443 if (entry->id) {
444 if (!entry->writeIDToMsg(arrayname, n, msg))
445 return false;
446 n++;
447 }
448 entry = entry + 1; //sizeof(TypeMapEntry);
449 }
450 return true;
451}
452
453
457template <typename T, typename ID>
459 T* entry = NULL;
460 if (data == NULL)
461 return false;
462 GenericMapHeader* header = (GenericMapHeader*)data;
463
464 uint32 n = 0;
465 entry = (T*)(data + sizeof(GenericMapHeader) + header->bitFieldSize);
466 while ((uint32)((char*)entry - data) < header->size) {
467 if (entry->id) {
468 if (!entry->writeToMsg(n, msg))
469 return false;
470 n++;
471 }
472 entry = entry + 1; //sizeof(TypeMapEntry);
473 }
474 return true;
475}
476
477
479template <typename T, typename ID>
481 if (data == NULL)
482 return false;
483 return ((GenericMapHeader*)data)->count;
484}
485
488template <typename T, typename ID>
490 if (data == NULL)
491 return 0;
492 return ((GenericMapHeader*)data)->count * sizeof(T);
493}
494
495} // namespace cmlabs
#define BITOCCUPIED
Definition Types.h:34
#define BITFREE
Definition Types.h:33
Cross-platform utility toolbox for CMSDK: threading, synchronization, shared memory,...
#define MAXKEYNAMELEN
Definition Utils.h:85
#define stricmp
Definition Utils.h:132
The central Psyclone data container: a self-contained binary message with typed, named user entries.
static bool GetEntryName(char *data, ID id, char *name, uint32 maxSize)
Copy the entry name.
static T * CreateEntry(char *data, ID id, const char *name)
Reserve entry id with name (status 1).
static bool ConfirmEntry(char *data, ID id)
Mark entry ready (status 2).
static bool WriteAllEntriesToMsg(char *data, DataMessage *msg)
Serialize all entries into msg.
static ID GetEntryID(char *data, const char *name, bool force=false)
Case-insensitive reverse lookup: find the id registered under name.
static std::string ToXML(char *data)
Serialize all occupied entries as XML by delegating to each entry's toXML(), wrapped in the outer ele...
static T * CreateFirstFreeEntry(char *data, ID &id, const char *name)
Reserve the first free id.
static bool DeleteEntry(char *data, ID id)
Free the entry and its bit.
static uint32 GetCount(char *data)
Number of entries currently registered in the map (from the header's count field).
static uint32 GetUsage(char *data)
Approximate bytes in use by entry payloads (count * sizeof(T)); excludes the header and bitfield.
static uint8 LookupEntryID(char *data, const char *name, ID &id)
Case-insensitive lookup returning the entry's sync status rather than filtering by it.
static std::string PrintAllEntries(char *data)
Human-readable text dump of all occupied entries, one per line ("id = name (time)"; unconfirmed entri...
static T * GetEntry(char *data, ID id)
Fetch the confirmed entry at index id.
static bool WriteAllIDsToMsg(const char *arrayname, char *data, DataMessage *msg)
Write just names into msg under arrayname.
static uint64 GetEntryTime(char *data, ID id)
Creation timestamp of entry id.
static bool CancelEntry(char *data, ID id)
Roll back a reserved entry.
static std::string PrintAllEntriesHTML(char *data)
Dump all occupied entries as HTML table rows (no surrounding table element); used by the node's monit...
std::string PrintTimeString(uint64 t, bool local=true, bool us=true, bool ms=true)
Definition PsyTime.cpp:676
uint64 GetTimeNow()
Return the current absolute time (µs since year 0) according to the TMC.
Definition PsyTime.cpp:69
bool GetFirstFreeBitLoc(const char *bitfield, uint32 bytesize, uint32 &loc)
Find the first 0 (free) bit.
Definition Utils.cpp:2473
bool GetBit(uint32 loc, const char *bitfield, uint32 bytesize, bit &val)
Read bit loc.
Definition Utils.cpp:2692
bool SetBit(uint32 loc, bit value, char *bitfield, uint32 bytesize)
Set bit loc to value.
Definition Utils.cpp:2597
uint32 strcpyavail(char *dst, const char *src, uint32 maxlen, bool copyAvailable)
Bounded strcpy that always NUL-terminates.
Definition Utils.cpp:6463
std::string StringFormat(const char *format,...)
printf into a std::string.
Definition Utils.cpp:7033
Common header of every map inside the data-maps segment.