better perf
This commit is contained in:
@@ -6,6 +6,9 @@
|
||||
#include "MemoryMapBroker.h"
|
||||
#include "ObjectRegistryDatabase.h"
|
||||
#include "ObjectBuilder.h"
|
||||
#include "Vector.h"
|
||||
#include "FastPollingMutexSem.h"
|
||||
#include "HighResolutionTimer.h"
|
||||
|
||||
// Original broker headers
|
||||
#include "MemoryMapInputBroker.h"
|
||||
@@ -17,39 +20,45 @@
|
||||
#include "MemoryMapMultiBufferOutputBroker.h"
|
||||
#include "MemoryMapSynchronisedMultiBufferInputBroker.h"
|
||||
#include "MemoryMapSynchronisedMultiBufferOutputBroker.h"
|
||||
#include "MemoryMapAsyncOutputBroker.h"
|
||||
#include "MemoryMapAsyncTriggerOutputBroker.h"
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
/**
|
||||
* @brief Base implementation for all debug brokers.
|
||||
* @brief Helper for optimized signal processing within brokers.
|
||||
*/
|
||||
class DebugBrokerHelper {
|
||||
public:
|
||||
static void Process(BrokerI* broker, DebugService* service, DebugSignalInfo** signalInfoPointers, uint32 numSignals) {
|
||||
static void Process(DebugService* service, DebugSignalInfo** signalInfoPointers, Vector<uint32>& activeIndices, Vector<uint32>& activeSizes, FastPollingMutexSem& activeMutex) {
|
||||
if (service == NULL_PTR(DebugService*)) return;
|
||||
|
||||
// Re-establish break logic
|
||||
while (service->IsPaused()) {
|
||||
Sleep::MSec(10);
|
||||
}
|
||||
|
||||
if (signalInfoPointers != NULL_PTR(DebugSignalInfo**)) {
|
||||
for (uint32 i = 0; i < numSignals; i++) {
|
||||
DebugSignalInfo *s = signalInfoPointers[i];
|
||||
if (s != NULL_PTR(DebugSignalInfo*)) {
|
||||
if (s->isTracing || s->isForcing) {
|
||||
uint32 size = broker->GetCopyByteSize(i);
|
||||
service->ProcessSignal(s, size);
|
||||
}
|
||||
}
|
||||
|
||||
activeMutex.FastLock();
|
||||
uint32 n = activeIndices.GetNumberOfElements();
|
||||
if (n > 0 && signalInfoPointers != NULL_PTR(DebugSignalInfo**)) {
|
||||
// Capture timestamp ONCE per broker cycle for lowest impact
|
||||
uint64 ts = (uint64)((float64)HighResolutionTimer::Counter() * HighResolutionTimer::Period() * 1000000.0);
|
||||
|
||||
for (uint32 i = 0; i < n; i++) {
|
||||
uint32 idx = activeIndices[i];
|
||||
uint32 size = activeSizes[i];
|
||||
DebugSignalInfo *s = signalInfoPointers[idx];
|
||||
service->ProcessSignal(s, size, ts);
|
||||
}
|
||||
}
|
||||
activeMutex.FastUnLock();
|
||||
}
|
||||
|
||||
static void InitSignals(MemoryMapBroker* broker, DataSourceI &dataSourceIn, DebugService* &service, DebugSignalInfo** &signalInfoPointers, uint32 &numSignals, MemoryMapBrokerCopyTableEntry* copyTable, const char8* functionName, SignalDirection direction) {
|
||||
numSignals = broker->GetNumberOfCopies();
|
||||
if (numSignals > 0) {
|
||||
signalInfoPointers = new DebugSignalInfo*[numSignals];
|
||||
for (uint32 i=0; i<numSignals; i++) signalInfoPointers[i] = NULL_PTR(DebugSignalInfo*);
|
||||
// Pass numCopies explicitly so we can mock it
|
||||
static void InitSignals(BrokerI* broker, DataSourceI &dataSourceIn, DebugService* &service, DebugSignalInfo** &signalInfoPointers, uint32 numCopies, MemoryMapBrokerCopyTableEntry* copyTable, const char8* functionName, SignalDirection direction, volatile bool* anyActiveFlag, Vector<uint32>* activeIndices, Vector<uint32>* activeSizes, FastPollingMutexSem* activeMutex) {
|
||||
if (numCopies > 0) {
|
||||
signalInfoPointers = new DebugSignalInfo*[numCopies];
|
||||
for (uint32 i=0; i<numCopies; i++) signalInfoPointers[i] = NULL_PTR(DebugSignalInfo*);
|
||||
}
|
||||
|
||||
ReferenceContainer *root = ObjectRegistryDatabase::Instance();
|
||||
@@ -61,21 +70,26 @@ public:
|
||||
if (service && (copyTable != NULL_PTR(MemoryMapBrokerCopyTableEntry*))) {
|
||||
StreamString dsPath;
|
||||
DebugService::GetFullObjectName(dataSourceIn, dsPath);
|
||||
MemoryMapBroker* mmb = dynamic_cast<MemoryMapBroker*>(broker);
|
||||
|
||||
for (uint32 i = 0; i < numSignals; i++) {
|
||||
for (uint32 i = 0; i < numCopies; i++) {
|
||||
void *addr = copyTable[i].dataSourcePointer;
|
||||
TypeDescriptor type = copyTable[i].type;
|
||||
|
||||
uint32 dsIdx = broker->GetDSCopySignalIndex(i);
|
||||
uint32 dsIdx = i;
|
||||
if (mmb != NULL_PTR(MemoryMapBroker*)) {
|
||||
dsIdx = mmb->GetDSCopySignalIndex(i);
|
||||
}
|
||||
|
||||
StreamString signalName;
|
||||
if (!dataSourceIn.GetSignalName(dsIdx, signalName)) signalName = "Unknown";
|
||||
|
||||
// 1. Register canonical DataSource name (Absolute, No Root prefix)
|
||||
// Register canonical name
|
||||
StreamString dsFullName;
|
||||
dsFullName.Printf("%s.%s", dsPath.Buffer(), signalName.Buffer());
|
||||
service->RegisterSignal(addr, type, dsFullName.Buffer());
|
||||
|
||||
// 2. Also register absolute GAM alias
|
||||
// Register alias
|
||||
if (functionName != NULL_PTR(const char8*)) {
|
||||
StreamString gamFullName;
|
||||
const char8* dirStr = (direction == InputSignals) ? "In" : "Out";
|
||||
@@ -92,73 +106,209 @@ public:
|
||||
signalInfoPointers[i] = service->RegisterSignal(addr, type, dsFullName.Buffer());
|
||||
}
|
||||
}
|
||||
|
||||
// Register broker in DebugService for optimized control
|
||||
service->RegisterBroker(signalInfoPointers, numCopies, mmb, anyActiveFlag, activeIndices, activeSizes, activeMutex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define DECLARE_DEBUG_BROKER_COMMON(BaseClass) \
|
||||
Debug##BaseClass() : BaseClass() { \
|
||||
service = NULL_PTR(DebugService*); \
|
||||
signalInfoPointers = NULL_PTR(DebugSignalInfo**); \
|
||||
numSignals = 0; \
|
||||
} \
|
||||
virtual ~Debug##BaseClass() { \
|
||||
if (signalInfoPointers) delete[] signalInfoPointers; \
|
||||
} \
|
||||
virtual bool Execute() { \
|
||||
bool ret = BaseClass::Execute(); \
|
||||
if (ret) DebugBrokerHelper::Process(this, service, signalInfoPointers, numSignals); \
|
||||
return ret; \
|
||||
} \
|
||||
private: \
|
||||
DebugService *service; \
|
||||
DebugSignalInfo **signalInfoPointers; \
|
||||
/**
|
||||
* @brief Template class to instrument any MARTe2 Broker.
|
||||
*/
|
||||
template <typename BaseClass>
|
||||
class DebugBrokerWrapper : public BaseClass {
|
||||
public:
|
||||
DebugBrokerWrapper() : BaseClass() {
|
||||
service = NULL_PTR(DebugService*);
|
||||
signalInfoPointers = NULL_PTR(DebugSignalInfo**);
|
||||
numSignals = 0;
|
||||
anyActive = false;
|
||||
}
|
||||
|
||||
virtual ~DebugBrokerWrapper() {
|
||||
if (signalInfoPointers) delete[] signalInfoPointers;
|
||||
}
|
||||
|
||||
virtual bool Execute() {
|
||||
bool ret = BaseClass::Execute();
|
||||
if (ret && (anyActive || (service && service->IsPaused()))) {
|
||||
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices, activeSizes, activeMutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual bool Init(SignalDirection direction, DataSourceI &ds, const char8 *const name, void *gamMem) {
|
||||
bool ret = BaseClass::Init(direction, ds, name, gamMem);
|
||||
if (ret) {
|
||||
numSignals = this->GetNumberOfCopies();
|
||||
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers, numSignals, this->copyTable, name, direction, &anyActive, &activeIndices, &activeSizes, &activeMutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual bool Init(SignalDirection direction, DataSourceI &ds, const char8 *const name, void *gamMem, const bool optim) {
|
||||
bool ret = BaseClass::Init(direction, ds, name, gamMem, optim);
|
||||
if (ret) {
|
||||
numSignals = this->GetNumberOfCopies();
|
||||
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers, numSignals, this->copyTable, name, direction, &anyActive, &activeIndices, &activeSizes, &activeMutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DebugService *service;
|
||||
DebugSignalInfo **signalInfoPointers;
|
||||
uint32 numSignals;
|
||||
|
||||
#define DECLARE_DEBUG_BROKER(BaseClass) \
|
||||
class Debug##BaseClass : public BaseClass { \
|
||||
public: \
|
||||
DECLARE_DEBUG_BROKER_COMMON(BaseClass) \
|
||||
virtual bool Init(SignalDirection direction, DataSourceI &ds, const char8 *const name, void *gamMem) { \
|
||||
bool ret = BaseClass::Init(direction, ds, name, gamMem); \
|
||||
if (ret) DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers, numSignals, this->copyTable, name, direction); \
|
||||
return ret; \
|
||||
} \
|
||||
virtual bool Init(SignalDirection direction, DataSourceI &ds, const char8 *const name, void *gamMem, const bool optim) { \
|
||||
bool ret = BaseClass::Init(direction, ds, name, gamMem, optim); \
|
||||
if (ret) DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers, numSignals, this->copyTable, name, direction); \
|
||||
return ret; \
|
||||
} \
|
||||
}; \
|
||||
class Debug##BaseClass##Builder : public ObjectBuilder { \
|
||||
public: \
|
||||
virtual Object *Build(HeapI* const heap) const { return new (heap) Debug##BaseClass(); } \
|
||||
volatile bool anyActive;
|
||||
Vector<uint32> activeIndices;
|
||||
Vector<uint32> activeSizes;
|
||||
FastPollingMutexSem activeMutex;
|
||||
};
|
||||
|
||||
#define DECLARE_DEBUG_BROKER_NO_OPTIM(BaseClass) \
|
||||
class Debug##BaseClass : public BaseClass { \
|
||||
public: \
|
||||
DECLARE_DEBUG_BROKER_COMMON(BaseClass) \
|
||||
virtual bool Init(SignalDirection direction, DataSourceI &ds, const char8 *const name, void *gamMem) { \
|
||||
bool ret = BaseClass::Init(direction, ds, name, gamMem); \
|
||||
if (ret) DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers, numSignals, this->copyTable, name, direction); \
|
||||
return ret; \
|
||||
} \
|
||||
}; \
|
||||
class Debug##BaseClass##Builder : public ObjectBuilder { \
|
||||
public: \
|
||||
virtual Object *Build(HeapI* const heap) const { return new (heap) Debug##BaseClass(); } \
|
||||
template <typename BaseClass>
|
||||
class DebugBrokerWrapperNoOptim : public BaseClass {
|
||||
public:
|
||||
DebugBrokerWrapperNoOptim() : BaseClass() {
|
||||
service = NULL_PTR(DebugService*);
|
||||
signalInfoPointers = NULL_PTR(DebugSignalInfo**);
|
||||
numSignals = 0;
|
||||
anyActive = false;
|
||||
}
|
||||
|
||||
virtual ~DebugBrokerWrapperNoOptim() {
|
||||
if (signalInfoPointers) delete[] signalInfoPointers;
|
||||
}
|
||||
|
||||
virtual bool Execute() {
|
||||
bool ret = BaseClass::Execute();
|
||||
if (ret && (anyActive || (service && service->IsPaused()))) {
|
||||
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices, activeSizes, activeMutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual bool Init(SignalDirection direction, DataSourceI &ds, const char8 *const name, void *gamMem) {
|
||||
bool ret = BaseClass::Init(direction, ds, name, gamMem);
|
||||
if (ret) {
|
||||
numSignals = this->GetNumberOfCopies();
|
||||
DebugBrokerHelper::InitSignals(this, ds, service, signalInfoPointers, numSignals, this->copyTable, name, direction, &anyActive, &activeIndices, &activeSizes, &activeMutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DebugService *service;
|
||||
DebugSignalInfo **signalInfoPointers;
|
||||
uint32 numSignals;
|
||||
volatile bool anyActive;
|
||||
Vector<uint32> activeIndices;
|
||||
Vector<uint32> activeSizes;
|
||||
FastPollingMutexSem activeMutex;
|
||||
};
|
||||
|
||||
DECLARE_DEBUG_BROKER(MemoryMapInputBroker)
|
||||
DECLARE_DEBUG_BROKER(MemoryMapOutputBroker)
|
||||
DECLARE_DEBUG_BROKER(MemoryMapSynchronisedInputBroker)
|
||||
DECLARE_DEBUG_BROKER(MemoryMapSynchronisedOutputBroker)
|
||||
DECLARE_DEBUG_BROKER_NO_OPTIM(MemoryMapInterpolatedInputBroker)
|
||||
DECLARE_DEBUG_BROKER(MemoryMapMultiBufferInputBroker)
|
||||
DECLARE_DEBUG_BROKER(MemoryMapMultiBufferOutputBroker)
|
||||
DECLARE_DEBUG_BROKER(MemoryMapSynchronisedMultiBufferInputBroker)
|
||||
DECLARE_DEBUG_BROKER(MemoryMapSynchronisedMultiBufferOutputBroker)
|
||||
class DebugMemoryMapAsyncOutputBroker : public MemoryMapAsyncOutputBroker {
|
||||
public:
|
||||
DebugMemoryMapAsyncOutputBroker() : MemoryMapAsyncOutputBroker() {
|
||||
service = NULL_PTR(DebugService*);
|
||||
signalInfoPointers = NULL_PTR(DebugSignalInfo**);
|
||||
numSignals = 0;
|
||||
anyActive = false;
|
||||
}
|
||||
virtual ~DebugMemoryMapAsyncOutputBroker() {
|
||||
if (signalInfoPointers) delete[] signalInfoPointers;
|
||||
}
|
||||
virtual bool Execute() {
|
||||
bool ret = MemoryMapAsyncOutputBroker::Execute();
|
||||
if (ret && (anyActive || (service && service->IsPaused()))) {
|
||||
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices, activeSizes, activeMutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
virtual bool InitWithBufferParameters(const SignalDirection direction, DataSourceI &dataSourceIn, const char8 * const functionName,
|
||||
void * const gamMemoryAddress, const uint32 numberOfBuffersIn, const ProcessorType& cpuMaskIn, const uint32 stackSizeIn) {
|
||||
bool ret = MemoryMapAsyncOutputBroker::InitWithBufferParameters(direction, dataSourceIn, functionName, gamMemoryAddress, numberOfBuffersIn, cpuMaskIn, stackSizeIn);
|
||||
if (ret) {
|
||||
numSignals = this->GetNumberOfCopies();
|
||||
DebugBrokerHelper::InitSignals(this, dataSourceIn, service, signalInfoPointers, numSignals, this->copyTable, functionName, direction, &anyActive, &activeIndices, &activeSizes, &activeMutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
DebugService *service;
|
||||
DebugSignalInfo **signalInfoPointers;
|
||||
uint32 numSignals;
|
||||
volatile bool anyActive;
|
||||
Vector<uint32> activeIndices;
|
||||
Vector<uint32> activeSizes;
|
||||
FastPollingMutexSem activeMutex;
|
||||
};
|
||||
|
||||
class DebugMemoryMapAsyncTriggerOutputBroker : public MemoryMapAsyncTriggerOutputBroker {
|
||||
public:
|
||||
DebugMemoryMapAsyncTriggerOutputBroker() : MemoryMapAsyncTriggerOutputBroker() {
|
||||
service = NULL_PTR(DebugService*);
|
||||
signalInfoPointers = NULL_PTR(DebugSignalInfo**);
|
||||
numSignals = 0;
|
||||
anyActive = false;
|
||||
}
|
||||
virtual ~DebugMemoryMapAsyncTriggerOutputBroker() {
|
||||
if (signalInfoPointers) delete[] signalInfoPointers;
|
||||
}
|
||||
virtual bool Execute() {
|
||||
bool ret = MemoryMapAsyncTriggerOutputBroker::Execute();
|
||||
if (ret && (anyActive || (service && service->IsPaused()))) {
|
||||
DebugBrokerHelper::Process(service, signalInfoPointers, activeIndices, activeSizes, activeMutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
virtual bool InitWithTriggerParameters(const SignalDirection direction, DataSourceI &dataSourceIn, const char8 * const functionName,
|
||||
void * const gamMemoryAddress, const uint32 numberOfBuffersIn, const uint32 preTriggerBuffersIn,
|
||||
const uint32 postTriggerBuffersIn, const ProcessorType& cpuMaskIn, const uint32 stackSizeIn) {
|
||||
bool ret = MemoryMapAsyncTriggerOutputBroker::InitWithTriggerParameters(direction, dataSourceIn, functionName, gamMemoryAddress, numberOfBuffersIn, preTriggerBuffersIn, postTriggerBuffersIn, cpuMaskIn, stackSizeIn);
|
||||
if (ret) {
|
||||
numSignals = this->GetNumberOfCopies();
|
||||
DebugBrokerHelper::InitSignals(this, dataSourceIn, service, signalInfoPointers, numSignals, this->copyTable, functionName, direction, &anyActive, &activeIndices, &activeSizes, &activeMutex);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
DebugService *service;
|
||||
DebugSignalInfo **signalInfoPointers;
|
||||
uint32 numSignals;
|
||||
volatile bool anyActive;
|
||||
Vector<uint32> activeIndices;
|
||||
Vector<uint32> activeSizes;
|
||||
FastPollingMutexSem activeMutex;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class DebugBrokerBuilder : public ObjectBuilder {
|
||||
public:
|
||||
virtual Object *Build(HeapI* const heap) const { return new (heap) T(); }
|
||||
};
|
||||
|
||||
typedef DebugBrokerWrapper<MemoryMapInputBroker> DebugMemoryMapInputBroker;
|
||||
// LCOV_EXCL_START
|
||||
typedef DebugBrokerWrapper<MemoryMapOutputBroker> DebugMemoryMapOutputBroker;
|
||||
typedef DebugBrokerWrapper<MemoryMapSynchronisedInputBroker> DebugMemoryMapSynchronisedInputBroker;
|
||||
typedef DebugBrokerWrapper<MemoryMapSynchronisedOutputBroker> DebugMemoryMapSynchronisedOutputBroker;
|
||||
typedef DebugBrokerWrapperNoOptim<MemoryMapInterpolatedInputBroker> DebugMemoryMapInterpolatedInputBroker;
|
||||
typedef DebugBrokerWrapper<MemoryMapMultiBufferInputBroker> DebugMemoryMapMultiBufferInputBroker;
|
||||
typedef DebugBrokerWrapper<MemoryMapMultiBufferOutputBroker> DebugMemoryMapMultiBufferOutputBroker;
|
||||
typedef DebugBrokerWrapper<MemoryMapSynchronisedMultiBufferInputBroker> DebugMemoryMapSynchronisedMultiBufferInputBroker;
|
||||
typedef DebugBrokerWrapper<MemoryMapSynchronisedMultiBufferOutputBroker> DebugMemoryMapSynchronisedMultiBufferOutputBroker;
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapInputBroker> DebugMemoryMapInputBrokerBuilder;
|
||||
// LCOV_EXCL_START
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapOutputBroker> DebugMemoryMapOutputBrokerBuilder;
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapSynchronisedInputBroker> DebugMemoryMapSynchronisedInputBrokerBuilder;
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapSynchronisedOutputBroker> DebugMemoryMapSynchronisedOutputBrokerBuilder;
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapInterpolatedInputBroker> DebugMemoryMapInterpolatedInputBrokerBuilder;
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapMultiBufferInputBroker> DebugMemoryMapMultiBufferInputBrokerBuilder;
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapMultiBufferOutputBroker> DebugMemoryMapMultiBufferOutputBrokerBuilder;
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapSynchronisedMultiBufferInputBroker> DebugMemoryMapSynchronisedMultiBufferInputBrokerBuilder;
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapSynchronisedMultiBufferOutputBroker> DebugMemoryMapSynchronisedMultiBufferOutputBrokerBuilder;
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapAsyncOutputBroker> DebugMemoryMapAsyncOutputBrokerBuilder;
|
||||
typedef DebugBrokerBuilder<DebugMemoryMapAsyncTriggerOutputBroker> DebugMemoryMapAsyncTriggerOutputBrokerBuilder;
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "CompilerTypes.h"
|
||||
#include "TypeDescriptor.h"
|
||||
#include "StreamString.h"
|
||||
#include <cstring> // For memcpy
|
||||
#include <cstring>
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
@@ -29,6 +29,10 @@ struct TraceHeader {
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
/**
|
||||
* @brief Ring buffer for high-frequency signal tracing.
|
||||
* @details New format per sample: [ID:4][Timestamp:8][Size:4][Data:N]
|
||||
*/
|
||||
class TraceRingBuffer {
|
||||
public:
|
||||
TraceRingBuffer() {
|
||||
@@ -55,12 +59,11 @@ public:
|
||||
return (buffer != NULL_PTR(uint8*));
|
||||
}
|
||||
|
||||
bool Push(uint32 signalID, void* data, uint32 size) {
|
||||
uint32 packetSize = 4 + 4 + size;
|
||||
bool Push(uint32 signalID, uint64 timestamp, void* data, uint32 size) {
|
||||
uint32 packetSize = 4 + 8 + 4 + size; // ID + TS + Size + Data
|
||||
uint32 read = readIndex;
|
||||
uint32 write = writeIndex;
|
||||
|
||||
// Calculate available space
|
||||
uint32 available = 0;
|
||||
if (read <= write) {
|
||||
available = bufferSize - (write - read) - 1;
|
||||
@@ -70,35 +73,31 @@ public:
|
||||
|
||||
if (available < packetSize) return false;
|
||||
|
||||
// Use temporary write index to ensure atomic update
|
||||
uint32 tempWrite = write;
|
||||
WriteToBuffer(&tempWrite, &signalID, 4);
|
||||
WriteToBuffer(&tempWrite, ×tamp, 8);
|
||||
WriteToBuffer(&tempWrite, &size, 4);
|
||||
WriteToBuffer(&tempWrite, data, size);
|
||||
|
||||
// Memory Barrier to ensure data is visible before index update
|
||||
// __sync_synchronize();
|
||||
|
||||
// Final atomic update
|
||||
writeIndex = tempWrite;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Pop(uint32 &signalID, void* dataBuffer, uint32 &size, uint32 maxSize) {
|
||||
bool Pop(uint32 &signalID, uint64 ×tamp, void* dataBuffer, uint32 &size, uint32 maxSize) {
|
||||
uint32 read = readIndex;
|
||||
uint32 write = writeIndex;
|
||||
if (read == write) return false;
|
||||
|
||||
uint32 tempRead = read;
|
||||
uint32 tempId = 0;
|
||||
uint64 tempTs = 0;
|
||||
uint32 tempSize = 0;
|
||||
|
||||
// Peek header
|
||||
ReadFromBuffer(&tempRead, &tempId, 4);
|
||||
ReadFromBuffer(&tempRead, &tempTs, 8);
|
||||
ReadFromBuffer(&tempRead, &tempSize, 4);
|
||||
|
||||
if (tempSize > maxSize) {
|
||||
// Error case: drop data up to writeIndex (resync)
|
||||
readIndex = write;
|
||||
return false;
|
||||
}
|
||||
@@ -106,11 +105,9 @@ public:
|
||||
ReadFromBuffer(&tempRead, dataBuffer, tempSize);
|
||||
|
||||
signalID = tempId;
|
||||
timestamp = tempTs;
|
||||
size = tempSize;
|
||||
|
||||
// Memory Barrier
|
||||
// __sync_synchronize();
|
||||
|
||||
readIndex = tempRead;
|
||||
return true;
|
||||
}
|
||||
@@ -126,7 +123,6 @@ private:
|
||||
void WriteToBuffer(uint32 *idx, void* src, uint32 count) {
|
||||
uint32 current = *idx;
|
||||
uint32 spaceToEnd = bufferSize - current;
|
||||
|
||||
if (count <= spaceToEnd) {
|
||||
std::memcpy(&buffer[current], src, count);
|
||||
*idx = (current + count) % bufferSize;
|
||||
@@ -141,7 +137,6 @@ private:
|
||||
void ReadFromBuffer(uint32 *idx, void* dst, uint32 count) {
|
||||
uint32 current = *idx;
|
||||
uint32 spaceToEnd = bufferSize - current;
|
||||
|
||||
if (count <= spaceToEnd) {
|
||||
std::memcpy(dst, &buffer[current], count);
|
||||
*idx = (current + count) % bufferSize;
|
||||
|
||||
@@ -13,13 +13,26 @@
|
||||
|
||||
namespace MARTe {
|
||||
|
||||
class MemoryMapBroker;
|
||||
|
||||
struct SignalAlias {
|
||||
StreamString name;
|
||||
uint32 signalIndex;
|
||||
};
|
||||
|
||||
struct BrokerInfo {
|
||||
DebugSignalInfo** signalPointers;
|
||||
uint32 numSignals;
|
||||
MemoryMapBroker* broker;
|
||||
volatile bool* anyActiveFlag;
|
||||
Vector<uint32>* activeIndices;
|
||||
Vector<uint32>* activeSizes;
|
||||
FastPollingMutexSem* activeMutex;
|
||||
};
|
||||
|
||||
class DebugService : public ReferenceContainer, public MessageI, public EmbeddedServiceMethodBinderI {
|
||||
public:
|
||||
friend class DebugServiceTest;
|
||||
CLASS_REGISTER_DECLARATION()
|
||||
|
||||
DebugService();
|
||||
@@ -28,7 +41,9 @@ public:
|
||||
virtual bool Initialise(StructuredDataI & data);
|
||||
|
||||
DebugSignalInfo* RegisterSignal(void* memoryAddress, TypeDescriptor type, const char8* name);
|
||||
void ProcessSignal(DebugSignalInfo* signalInfo, uint32 size);
|
||||
void ProcessSignal(DebugSignalInfo* signalInfo, uint32 size, uint64 timestamp);
|
||||
|
||||
void RegisterBroker(DebugSignalInfo** signalPointers, uint32 numSignals, MemoryMapBroker* broker, volatile bool* anyActiveFlag, Vector<uint32>* activeIndices, Vector<uint32>* activeSizes, FastPollingMutexSem* activeMutex);
|
||||
|
||||
virtual ErrorManagement::ErrorType Execute(ExecutionInfo & info);
|
||||
|
||||
@@ -41,11 +56,11 @@ public:
|
||||
uint32 UnforceSignal(const char8* name);
|
||||
uint32 TraceSignal(const char8* name, bool enable, uint32 decimation = 1);
|
||||
void Discover(BasicTCPSocket *client);
|
||||
void ListNodes(const char8* path, BasicTCPSocket *client);
|
||||
void InfoNode(const char8* path, BasicTCPSocket *client);
|
||||
|
||||
private:
|
||||
void HandleCommand(StreamString cmd, BasicTCPSocket *client);
|
||||
void UpdateBrokersActiveStatus();
|
||||
|
||||
uint32 ExportTree(ReferenceContainer *container, StreamString &json);
|
||||
void PatchRegistry();
|
||||
@@ -93,6 +108,10 @@ private:
|
||||
SignalAlias aliases[MAX_ALIASES];
|
||||
uint32 numberOfAliases;
|
||||
|
||||
static const uint32 MAX_BROKERS = 1024;
|
||||
BrokerInfo brokers[MAX_BROKERS];
|
||||
uint32 numberOfBrokers;
|
||||
|
||||
FastPollingMutexSem mutex;
|
||||
TraceRingBuffer traceBuffer;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user