logic: multithreaded parsing

* modified the TaskParseCxx to be able to run multiple times in parallel
* made FileRegister threadsafe and changed a lot of its mechanisms
* added TaskGroupParallel that runs all children in parallel
* added TaskParseWrapper that acts as a decorator to execute some code before and after parsing.
* implemented task setup in project with 4 parsing threads
* removed SimpleTask as it was only used as interface for the LambdaTask
This commit is contained in:
malte_langkabel
2016-05-13 13:23:54 +02:00
parent 245cafdc7b
commit c61efbbcde
27 changed files with 535 additions and 317 deletions
+19 -1
View File
@@ -9,7 +9,25 @@ LambdaTask::~LambdaTask()
{
}
void LambdaTask::perform()
void LambdaTask::enter()
{
}
Task::TaskState LambdaTask::update()
{
m_func();
return Task::STATE_FINISHED;
}
void LambdaTask::exit()
{
}
void LambdaTask::interrupt()
{
}
void LambdaTask::revert()
{
}
+8 -3
View File
@@ -3,16 +3,21 @@
#include <functional>
#include "utility/scheduling/SimpleTask.h"
#include "utility/scheduling/Task.h"
class LambdaTask
: public SimpleTask
: public Task
{
public:
LambdaTask(std::function<void()> func);
virtual ~LambdaTask();
virtual void perform();
virtual void enter();
virtual TaskState update();
virtual void exit();
virtual void interrupt();
virtual void revert();
private:
std::function<void()> m_func;
-28
View File
@@ -1,28 +0,0 @@
#include "utility/scheduling/SimpleTask.h"
void SimpleTask::enter()
{
}
Task::TaskState SimpleTask::update()
{
perform();
return Task::STATE_FINISHED;
}
void SimpleTask::exit()
{
}
void SimpleTask::interrupt()
{
}
void SimpleTask::revert()
{
}
-20
View File
@@ -1,20 +0,0 @@
#ifndef SIMPLE_TASK_H
#define SIMPLE_TASK_H
#include "utility/scheduling/Task.h"
class SimpleTask
: public Task
{
public:
virtual void enter();
virtual TaskState update();
virtual void exit();
virtual void interrupt();
virtual void revert();
virtual void perform() = 0;
};
#endif // SIMPLE_TASK_H
@@ -0,0 +1,75 @@
#include "utility/scheduling/TaskGroupParallel.h"
#include <thread>
TaskGroupParallel::TaskGroupParallel()
{
}
TaskGroupParallel::~TaskGroupParallel()
{
}
void TaskGroupParallel::enter()
{
m_interrupt = false;
m_running = false;
m_activeTaskCount = 0;
}
Task::TaskState TaskGroupParallel::update()
{
if (!m_running)
{
for (size_t i = 0; i < m_tasks.size(); i++)
{
std::thread(&TaskGroupParallel::processTask, this, m_tasks[i]).detach();
std::lock_guard<std::mutex> lock(m_activeTaskCountMutex);
m_activeTaskCount++;
}
m_running = true;
}
int activeTaskCount = 0;
{
std::lock_guard<std::mutex> lock(m_activeTaskCountMutex);
activeTaskCount = m_activeTaskCount;
}
if (activeTaskCount == 0)
{
return (m_interrupt ? STATE_CANCELED : STATE_FINISHED);
}
return Task::STATE_RUNNING;
}
void TaskGroupParallel::exit()
{
}
void TaskGroupParallel::interrupt()
{
m_interrupt = true;
}
void TaskGroupParallel::revert()
{
m_interrupt = true;
}
void TaskGroupParallel::processTask(std::shared_ptr<Task> task)
{
Task::TaskState state = Task::STATE_NEW;
while (state != Task::STATE_FINISHED && state != Task::STATE_CANCELED)
{
state = task->process(m_interrupt);
}
{
std::lock_guard<std::mutex> lock(m_activeTaskCountMutex);
m_activeTaskCount--; // not safe! if exception hits this thread before this point the count is not decremented.
}
}
@@ -0,0 +1,30 @@
#ifndef TASK_GROUP_PARALLEL_H
#define TASK_GROUP_PARALLEL_H
#include "utility/scheduling/TaskGroup.h"
#include <mutex>
class TaskGroupParallel
: public TaskGroup
{
public:
TaskGroupParallel();
virtual ~TaskGroupParallel();
virtual void enter();
virtual TaskState update();
virtual void exit();
virtual void interrupt();
virtual void revert();
private:
void processTask(std::shared_ptr<Task> task);
volatile bool m_interrupt;
bool m_running;
volatile int m_activeTaskCount;
std::mutex m_activeTaskCountMutex;
};
#endif // TASK_GROUP_PARALLEL_H