Added support for grouping InsightWorker tasks
This commit is contained in:
@@ -12,49 +12,76 @@ namespace Bloom
|
|||||||
using Bloom::Targets::TargetState;
|
using Bloom::Targets::TargetState;
|
||||||
|
|
||||||
void InsightWorker::startup() {
|
void InsightWorker::startup() {
|
||||||
QObject::connect(
|
auto* insightSignals = InsightSignals::instance();
|
||||||
InsightSignals::instance(),
|
|
||||||
&InsightSignals::taskQueued,
|
QObject::connect(insightSignals, &InsightSignals::taskQueued, this, &InsightWorker::executeTasks);
|
||||||
this,
|
QObject::connect(insightSignals, &InsightSignals::taskProcessed, this, &InsightWorker::executeTasks);
|
||||||
&InsightWorker::executeTasks
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("InsightWorker" + std::to_string(this->id) + " thread ready");
|
Logger::debug("InsightWorker" + std::to_string(this->id) + " thread ready");
|
||||||
emit this->ready();
|
emit this->ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsightWorker::queueTask(InsightWorkerTask* task) {
|
void InsightWorker::queueTask(InsightWorkerTask* task) {
|
||||||
|
static std::atomic<QueuedTaskId> lastQueuedTaskId = 0;
|
||||||
task->moveToThread(nullptr);
|
task->moveToThread(nullptr);
|
||||||
|
|
||||||
{
|
{
|
||||||
const auto taskQueueLock = InsightWorker::queuedTasks.acquireLock();
|
const auto taskQueueLock = InsightWorker::queuedTasksById.acquireLock();
|
||||||
InsightWorker::queuedTasks.getValue().push(task);
|
InsightWorker::queuedTasksById.getValue().insert(std::pair(++(lastQueuedTaskId), task));
|
||||||
}
|
}
|
||||||
|
|
||||||
emit InsightSignals::instance()->taskQueued();
|
emit InsightSignals::instance()->taskQueued();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<InsightWorkerTask*> InsightWorker::getQueuedTask() {
|
|
||||||
auto taskQueueLock = InsightWorker::queuedTasks.acquireLock();
|
|
||||||
auto& queuedTasks = InsightWorker::queuedTasks.getValue();
|
|
||||||
|
|
||||||
if (!queuedTasks.empty()) {
|
|
||||||
auto* task = queuedTasks.front();
|
|
||||||
queuedTasks.pop();
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InsightWorker::executeTasks() {
|
void InsightWorker::executeTasks() {
|
||||||
|
static const auto getQueuedTask = [] () -> std::optional<InsightWorkerTask*> {
|
||||||
|
const auto taskQueueLock = InsightWorker::queuedTasksById.acquireLock();
|
||||||
|
auto& queuedTasks = InsightWorker::queuedTasksById.getValue();
|
||||||
|
|
||||||
|
if (!queuedTasks.empty()) {
|
||||||
|
const auto taskGroupsLock = InsightWorker::taskGroupsInExecution.acquireLock();
|
||||||
|
auto& taskGroupsInExecution = InsightWorker::taskGroupsInExecution.getValue();
|
||||||
|
|
||||||
|
const auto canExecuteTask = [&taskGroupsInExecution] (InsightWorkerTask* task) {
|
||||||
|
for (const auto taskGroup : task->getTaskGroups()) {
|
||||||
|
if (taskGroupsInExecution.contains(taskGroup)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto [queuedTaskId, task] : queuedTasks) {
|
||||||
|
if (canExecuteTask(task)) {
|
||||||
|
const auto taskGroups = task->getTaskGroups();
|
||||||
|
taskGroupsInExecution.insert(taskGroups.begin(), taskGroups.end());
|
||||||
|
queuedTasks.erase(queuedTaskId);
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
auto queuedTask = std::optional<InsightWorkerTask*>();
|
auto queuedTask = std::optional<InsightWorkerTask*>();
|
||||||
|
|
||||||
while ((queuedTask = InsightWorker::getQueuedTask()).has_value()) {
|
while ((queuedTask = getQueuedTask())) {
|
||||||
auto* task = queuedTask.value();
|
auto* task = queuedTask.value();
|
||||||
task->moveToThread(this->thread());
|
task->moveToThread(this->thread());
|
||||||
task->setParent(this);
|
task->setParent(this);
|
||||||
task->execute(this->targetControllerConsole);
|
task->execute(this->targetControllerConsole);
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto taskGroupsLock = InsightWorker::taskGroupsInExecution.acquireLock();
|
||||||
|
auto& taskGroupsInExecution = InsightWorker::taskGroupsInExecution.getValue();
|
||||||
|
|
||||||
|
for (const auto& taskGroup : task->getTaskGroups()) {
|
||||||
|
taskGroupsInExecution.erase(taskGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
task->deleteLater();
|
task->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "Tasks/InsightWorkerTask.hpp"
|
#include "Tasks/InsightWorkerTask.hpp"
|
||||||
|
|
||||||
@@ -33,12 +34,15 @@ namespace Bloom
|
|||||||
void ready();
|
void ready();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using QueuedTaskId = std::uint64_t;
|
||||||
|
static_assert(std::atomic<QueuedTaskId>::is_always_lock_free);
|
||||||
|
|
||||||
static inline std::atomic<std::uint8_t> lastWorkerId = 0;
|
static inline std::atomic<std::uint8_t> lastWorkerId = 0;
|
||||||
static inline SyncSafe<std::queue<InsightWorkerTask*>> queuedTasks = {};
|
static inline SyncSafe<std::map<QueuedTaskId, InsightWorkerTask*>> queuedTasksById = {};
|
||||||
|
static inline SyncSafe<TaskGroups> taskGroupsInExecution = {};
|
||||||
|
|
||||||
TargetController::TargetControllerConsole targetControllerConsole = TargetController::TargetControllerConsole();
|
TargetController::TargetControllerConsole targetControllerConsole = TargetController::TargetControllerConsole();
|
||||||
|
|
||||||
static std::optional<InsightWorkerTask*> getQueuedTask();
|
|
||||||
void executeTasks();
|
void executeTasks();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include "TaskGroup.hpp"
|
||||||
#include "src/TargetController/TargetControllerConsole.hpp"
|
#include "src/TargetController/TargetControllerConsole.hpp"
|
||||||
|
|
||||||
namespace Bloom
|
namespace Bloom
|
||||||
@@ -24,6 +25,10 @@ namespace Bloom
|
|||||||
|
|
||||||
InsightWorkerTask(): QObject(nullptr) {};
|
InsightWorkerTask(): QObject(nullptr) {};
|
||||||
|
|
||||||
|
virtual TaskGroups getTaskGroups() const {
|
||||||
|
return TaskGroups();
|
||||||
|
};
|
||||||
|
|
||||||
void execute(TargetController::TargetControllerConsole& targetControllerConsole);
|
void execute(TargetController::TargetControllerConsole& targetControllerConsole);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|||||||
12
src/Insight/InsightWorker/Tasks/TaskGroup.hpp
Normal file
12
src/Insight/InsightWorker/Tasks/TaskGroup.hpp
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace Bloom
|
||||||
|
{
|
||||||
|
enum class TaskGroup: std::uint16_t
|
||||||
|
{};
|
||||||
|
|
||||||
|
using TaskGroups = std::set<TaskGroup>;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user