Adjusted WriteTargetMemory insight worker task to support writing non-contiguous blocks in a single task
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
namespace Bloom
|
namespace Bloom
|
||||||
{
|
{
|
||||||
@@ -17,36 +18,51 @@ namespace Bloom
|
|||||||
* This allows the TargetController to service other commands in-between reads, reducing the likelihood of
|
* This allows the TargetController to service other commands in-between reads, reducing the likelihood of
|
||||||
* command timeouts when we're writing lots of data.
|
* command timeouts when we're writing lots of data.
|
||||||
*/
|
*/
|
||||||
const auto blockSize = std::max(
|
const auto maxBlockSize = std::max(
|
||||||
TargetMemorySize(256),
|
TargetMemorySize(256),
|
||||||
memoryDescriptor.pageSize.value_or(TargetMemorySize(0))
|
memoryDescriptor.pageSize.value_or(TargetMemorySize(0))
|
||||||
);
|
);
|
||||||
const auto totalBytes = this->data.size();
|
|
||||||
|
|
||||||
TargetMemorySize bytesWritten = 0;
|
const TargetMemorySize totalBytesToWrite = std::accumulate(
|
||||||
|
this->blocks.begin(),
|
||||||
|
this->blocks.end(),
|
||||||
|
TargetMemorySize{0},
|
||||||
|
[] (TargetMemorySize bytes, const Block& block) {
|
||||||
|
return bytes + block.data.size();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
while (bytesWritten < totalBytes) {
|
TargetMemorySize totalBytesWritten = 0;
|
||||||
const auto bytesToWrite = std::min(
|
|
||||||
blockSize,
|
|
||||||
static_cast<decltype(blockSize)>(totalBytes - bytesWritten)
|
|
||||||
);
|
|
||||||
|
|
||||||
targetControllerService.writeMemory(
|
for (const auto& block : this->blocks) {
|
||||||
this->memoryDescriptor.type,
|
const auto totalBytes = block.data.size();
|
||||||
this->startAddress + bytesWritten,
|
|
||||||
Targets::TargetMemoryBuffer(
|
|
||||||
this->data.begin() + bytesWritten,
|
|
||||||
this->data.begin() + bytesWritten + bytesToWrite
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
bytesWritten += bytesToWrite;
|
TargetMemorySize bytesWritten = 0;
|
||||||
|
|
||||||
this->setProgressPercentage(static_cast<std::uint8_t>(
|
while (bytesWritten < totalBytes) {
|
||||||
(static_cast<float>(bytesWritten) + 1) / (static_cast<float>(totalBytes) / 100)
|
const auto bytesToWrite = std::min(
|
||||||
));
|
maxBlockSize,
|
||||||
|
static_cast<decltype(maxBlockSize)>(totalBytes - bytesWritten)
|
||||||
|
);
|
||||||
|
|
||||||
|
targetControllerService.writeMemory(
|
||||||
|
this->memoryDescriptor.type,
|
||||||
|
block.startAddress + bytesWritten,
|
||||||
|
Targets::TargetMemoryBuffer(
|
||||||
|
block.data.begin() + bytesWritten,
|
||||||
|
block.data.begin() + bytesWritten + bytesToWrite
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
bytesWritten += bytesToWrite;
|
||||||
|
totalBytesWritten += bytesToWrite;
|
||||||
|
|
||||||
|
this->setProgressPercentage(static_cast<std::uint8_t>(
|
||||||
|
(static_cast<float>(totalBytesWritten) + 1) / (static_cast<float>(totalBytesToWrite) / 100)
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit this->targetMemoryWritten(bytesWritten);
|
emit this->targetMemoryWritten(totalBytesWritten);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "InsightWorkerTask.hpp"
|
#include "InsightWorkerTask.hpp"
|
||||||
|
|
||||||
#include "src/Targets/TargetMemory.hpp"
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
@@ -11,14 +13,37 @@ namespace Bloom
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/*
|
||||||
|
* A Block is just a block of contiguous data to write. A single WriteTargetMemory task can write multiple
|
||||||
|
* blocks to a particular memory.
|
||||||
|
*/
|
||||||
|
struct Block {
|
||||||
|
Targets::TargetMemoryAddress startAddress;
|
||||||
|
const Targets::TargetMemoryBuffer data;
|
||||||
|
|
||||||
|
Block(
|
||||||
|
Targets::TargetMemoryAddress startAddress,
|
||||||
|
const Targets::TargetMemoryBuffer& data
|
||||||
|
)
|
||||||
|
: startAddress(startAddress)
|
||||||
|
, data(data)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
WriteTargetMemory(
|
||||||
|
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
||||||
|
std::vector<Block>&& blocks
|
||||||
|
)
|
||||||
|
: memoryDescriptor(memoryDescriptor)
|
||||||
|
, blocks(std::move(blocks))
|
||||||
|
{}
|
||||||
|
|
||||||
WriteTargetMemory(
|
WriteTargetMemory(
|
||||||
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
const Targets::TargetMemoryDescriptor& memoryDescriptor,
|
||||||
Targets::TargetMemoryAddress startAddress,
|
Targets::TargetMemoryAddress startAddress,
|
||||||
const Targets::TargetMemoryBuffer& data
|
const Targets::TargetMemoryBuffer& data
|
||||||
)
|
)
|
||||||
: memoryDescriptor(memoryDescriptor)
|
: WriteTargetMemory(memoryDescriptor, std::vector<Block>({{startAddress, data}}))
|
||||||
, startAddress(startAddress)
|
|
||||||
, data(data)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QString brief() const override {
|
QString brief() const override {
|
||||||
@@ -31,7 +56,7 @@ namespace Bloom
|
|||||||
return TaskGroups({
|
return TaskGroups({
|
||||||
TaskGroup::USES_TARGET_CONTROLLER,
|
TaskGroup::USES_TARGET_CONTROLLER,
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void targetMemoryWritten(Targets::TargetMemorySize bytesWritten);
|
void targetMemoryWritten(Targets::TargetMemorySize bytesWritten);
|
||||||
@@ -41,7 +66,6 @@ namespace Bloom
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Targets::TargetMemoryDescriptor memoryDescriptor;
|
Targets::TargetMemoryDescriptor memoryDescriptor;
|
||||||
Targets::TargetMemoryAddress startAddress;
|
std::vector<Block> blocks;
|
||||||
Targets::TargetMemoryBuffer data;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user