From 99db00c0cc8602a988602d3d6f609581ba6c710f Mon Sep 17 00:00:00 2001 From: Nav Date: Tue, 30 Aug 2022 20:26:29 +0100 Subject: [PATCH] Split target memory reads (via InsightWorker task) to numerous reads, in order to prevent occupying the TargetController for too long (which can result in GDB timeouts) --- .../InsightWorker/Tasks/ReadTargetMemory.cpp | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/Insight/InsightWorker/Tasks/ReadTargetMemory.cpp b/src/Insight/InsightWorker/Tasks/ReadTargetMemory.cpp index 6cffdff6..f793bf04 100644 --- a/src/Insight/InsightWorker/Tasks/ReadTargetMemory.cpp +++ b/src/Insight/InsightWorker/Tasks/ReadTargetMemory.cpp @@ -1,17 +1,40 @@ #include "ReadTargetMemory.hpp" +#include + +#include "src/Targets/TargetMemory.hpp" + namespace Bloom { using TargetController::TargetControllerConsole; void ReadTargetMemory::run(TargetControllerConsole& targetControllerConsole) { - emit this->targetMemoryRead( - targetControllerConsole.readMemory( - this->memoryType, - this->startAddress, - this->size, - this->excludedAddressRanges - ) + /* + * To prevent locking up the TargetController for too long, we split the read into numerous reads. + * + * This allows the TargetController to service other commands in-between reads, reducing the likelihood of + * command timeouts when we're reading lots of data. + */ + constexpr auto readSize = 256; + const auto readsRequired = static_cast( + std::ceil(static_cast(this->size) / static_cast(readSize)) ); + + Targets::TargetMemoryBuffer data; + + for (auto i = 0; i < readsRequired; i++) { + auto dataSegment = targetControllerConsole.readMemory( + this->memoryType, + this->startAddress + static_cast(readSize * i), + (this->size - data.size()) >= readSize + ? readSize + : static_cast(this->size - data.size()), + this->excludedAddressRanges + ); + + std::move(dataSegment.begin(), dataSegment.end(), std::back_inserter(data)); + } + + emit this->targetMemoryRead(data); } }