major improvements for big apps
This commit is contained in:
@@ -180,6 +180,8 @@ DebugServiceBase::DebugServiceBase() : ReferenceContainer() {
|
||||
isPaused = false;
|
||||
stepRemaining = 0u;
|
||||
manualConfigSet = false;
|
||||
discoverCacheValid = false;
|
||||
treeCacheValid = false;
|
||||
}
|
||||
|
||||
DebugServiceBase::~DebugServiceBase() {
|
||||
@@ -256,6 +258,9 @@ DebugSignalInfo *DebugServiceBase::RegisterSignal(void *memoryAddress,
|
||||
res->breakOp = BREAK_OFF;
|
||||
res->breakThreshold = 0.0;
|
||||
signals.Append(res);
|
||||
// Invalidate caches — new signal registered after the last build.
|
||||
discoverCacheValid = false;
|
||||
treeCacheValid = false;
|
||||
}
|
||||
if (sigIdx != 0xFFFFFFFFu) {
|
||||
bool found = false;
|
||||
@@ -716,54 +721,102 @@ void DebugServiceBase::GetSignalValue(const char8 *name, StreamString &out) {
|
||||
}
|
||||
|
||||
void DebugServiceBase::Discover(StreamString &out) {
|
||||
out += "{\"Signals\":[\n";
|
||||
if (!discoverCacheValid)
|
||||
BuildDiscoverCache();
|
||||
out += discoverCache;
|
||||
}
|
||||
|
||||
void DebugServiceBase::BuildDiscoverCache() {
|
||||
discoverCacheValid = false;
|
||||
discoverCache = "";
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Phase 1 — snapshot signal metadata under the mutex (fast, no allocs on
|
||||
// the RT path because this runs only during initialisation).
|
||||
// -----------------------------------------------------------------------
|
||||
Vector<StreamString> enames;
|
||||
Vector<uint32> eids;
|
||||
Vector<const char8*> etypes;
|
||||
Vector<uint8> edims;
|
||||
Vector<uint32> eelems;
|
||||
|
||||
mutex.FastLock();
|
||||
uint32 total = 0u;
|
||||
for (uint32 i = 0u; i < aliases.GetNumberOfElements(); i++) {
|
||||
if (total > 0u)
|
||||
out += ",\n";
|
||||
DebugSignalInfo *sig = signals[aliases[i].signalIndex];
|
||||
const char8 *tn = TypeDescriptor::GetTypeNameFromTypeDescriptor(sig->type);
|
||||
out.Printf(" {\"name\":\"%s\",\"id\":%u,\"type\":\"%s\","
|
||||
"\"dimensions\":%u,\"elements\":%u",
|
||||
aliases[i].name.Buffer(), sig->internalID, tn ? tn : "Unknown",
|
||||
sig->numberOfDimensions, sig->numberOfElements);
|
||||
EnrichWithConfig(aliases[i].name.Buffer(), out);
|
||||
out += "}";
|
||||
total++;
|
||||
enames.Append(aliases[i].name);
|
||||
eids.Append(sig->internalID);
|
||||
etypes.Append(TypeDescriptor::GetTypeNameFromTypeDescriptor(sig->type));
|
||||
edims.Append(sig->numberOfDimensions);
|
||||
eelems.Append(sig->numberOfElements);
|
||||
}
|
||||
for (uint32 i = 0u; i < monitoredSignals.GetNumberOfElements(); i++) {
|
||||
bool found = false;
|
||||
for (uint32 j = 0u; j < aliases.GetNumberOfElements(); j++) {
|
||||
if (aliases[j].name == monitoredSignals[i].path) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (aliases[j].name == monitoredSignals[i].path) { found = true; break; }
|
||||
}
|
||||
if (!found) {
|
||||
if (total > 0u)
|
||||
out += ",\n";
|
||||
const char8 *tn = TypeDescriptor::GetTypeNameFromTypeDescriptor(
|
||||
monitoredSignals[i].dataSource->GetSignalType(
|
||||
monitoredSignals[i].signalIdx));
|
||||
uint8 dims = 0u;
|
||||
uint8 dims = 0u;
|
||||
uint32 elems = 1u;
|
||||
(void)monitoredSignals[i].dataSource->GetSignalNumberOfDimensions(
|
||||
monitoredSignals[i].signalIdx, dims);
|
||||
(void)monitoredSignals[i].dataSource->GetSignalNumberOfElements(
|
||||
monitoredSignals[i].signalIdx, elems);
|
||||
out.Printf(" {\"name\":\"%s\",\"id\":%u,\"type\":\"%s\","
|
||||
"\"dimensions\":%u,\"elements\":%u",
|
||||
monitoredSignals[i].path.Buffer(),
|
||||
monitoredSignals[i].internalID, tn ? tn : "Unknown", dims,
|
||||
elems);
|
||||
EnrichWithConfig(monitoredSignals[i].path.Buffer(), out);
|
||||
out += "}";
|
||||
total++;
|
||||
enames.Append(monitoredSignals[i].path);
|
||||
eids.Append(monitoredSignals[i].internalID);
|
||||
etypes.Append(TypeDescriptor::GetTypeNameFromTypeDescriptor(
|
||||
monitoredSignals[i].dataSource->GetSignalType(
|
||||
monitoredSignals[i].signalIdx)));
|
||||
edims.Append(dims);
|
||||
eelems.Append(elems);
|
||||
}
|
||||
}
|
||||
mutex.FastUnLock();
|
||||
out += "\n]}\nOK DISCOVER\n";
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Phase 2 — build chunked response (no mutex; fullConfig is single-threaded
|
||||
// at initialisation time when this is called from SetFullConfig).
|
||||
// -----------------------------------------------------------------------
|
||||
uint32 total = enames.GetNumberOfElements();
|
||||
|
||||
if (total == 0u) {
|
||||
discoverCache = "{\"Signals\":[]}\nOK DISCOVER\n";
|
||||
discoverCacheValid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32 start = 0u; start < total; start += DISCOVER_CHUNK_SIGNALS) {
|
||||
uint32 end = start + DISCOVER_CHUNK_SIGNALS;
|
||||
if (end > total) end = total;
|
||||
bool isFinal = (end >= total);
|
||||
|
||||
discoverCache += "{\"Signals\":[\n";
|
||||
for (uint32 idx = start; idx < end; idx++) {
|
||||
if (idx > start) discoverCache += ",\n";
|
||||
discoverCache.Printf(
|
||||
" {\"name\":\"%s\",\"id\":%u,\"type\":\"%s\","
|
||||
"\"dimensions\":%u,\"elements\":%u",
|
||||
enames[idx].Buffer(), eids[idx],
|
||||
etypes[idx] ? etypes[idx] : "Unknown",
|
||||
edims[idx], eelems[idx]);
|
||||
EnrichWithConfig(enames[idx].Buffer(), discoverCache);
|
||||
discoverCache += "}";
|
||||
}
|
||||
discoverCache += "\n]}";
|
||||
discoverCache += isFinal ? "\nOK DISCOVER\n" : "\nOK DISCOVER_PART\n";
|
||||
}
|
||||
|
||||
discoverCacheValid = true;
|
||||
}
|
||||
|
||||
void DebugServiceBase::BuildTreeCache() {
|
||||
treeCacheValid = false;
|
||||
treeCache = "";
|
||||
treeCache += "{\"Name\":\"Root\",\"Class\":\"ObjectRegistryDatabase\","
|
||||
"\"Children\":[\n";
|
||||
(void)ExportTree(ObjectRegistryDatabase::Instance(), treeCache,
|
||||
NULL_PTR(const char8 *));
|
||||
treeCache += "\n]}\nOK TREE\n";
|
||||
treeCacheValid = true;
|
||||
}
|
||||
|
||||
void DebugServiceBase::InfoNode(const char8 *path, StreamString &out) {
|
||||
@@ -868,6 +921,8 @@ void DebugServiceBase::SetFullConfig(ConfigurationDatabase &config) {
|
||||
config.MoveToRoot();
|
||||
config.Copy(fullConfig);
|
||||
manualConfigSet = true;
|
||||
BuildDiscoverCache();
|
||||
BuildTreeCache();
|
||||
}
|
||||
|
||||
void DebugServiceBase::RebuildConfigFromRegistry() {
|
||||
@@ -1234,11 +1289,9 @@ void DebugServiceBase::HandleCommand(const StreamString &cmdIn,
|
||||
} else if (token == "DISCOVER") {
|
||||
Discover(out);
|
||||
} else if (token == "TREE") {
|
||||
out += "{\"Name\":\"Root\",\"Class\":\"ObjectRegistryDatabase\","
|
||||
"\"Children\":[\n";
|
||||
(void)ExportTree(ObjectRegistryDatabase::Instance(), out,
|
||||
NULL_PTR(const char8 *));
|
||||
out += "\n]}\nOK TREE\n";
|
||||
if (!treeCacheValid)
|
||||
BuildTreeCache();
|
||||
out += treeCache;
|
||||
} else if (token == "INFO") {
|
||||
StreamString path;
|
||||
if (cmd.GetToken(path, delims, term))
|
||||
@@ -1415,5 +1468,6 @@ void DebugServiceBase::HandleCommand(const StreamString &cmdIn,
|
||||
// Out-of-class constant definitions (C++98 ODR requirement)
|
||||
// ---------------------------------------------------------------------------
|
||||
const uint32 DebugServiceBase::GET_VALUE_MAX_ELEMENTS;
|
||||
const uint32 DebugServiceBase::DISCOVER_CHUNK_SIGNALS;
|
||||
|
||||
} // namespace MARTe
|
||||
|
||||
Reference in New Issue
Block a user