summaryrefslogtreecommitdiffstats
path: root/src/server/Task.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/Task.cpp')
-rw-r--r--src/server/Task.cpp67
1 files changed, 32 insertions, 35 deletions
diff --git a/src/server/Task.cpp b/src/server/Task.cpp
index 497f7895..48a82085 100644
--- a/src/server/Task.cpp
+++ b/src/server/Task.cpp
@@ -19,31 +19,25 @@
#include <boost/variant/get.hpp>
+#include <xmmintrin.h>
+
namespace Ingen {
namespace Server {
-static Task*
-get_task(ParTask& task, RunContext& context)
+static Job
+get_job(ParTask& task, RunContext& context)
{
// Attempt to "steal" a task from ourselves
- Task* t = steal(task, context);
- if (t) {
- return t;
+ Job job = steal(task, context);
+ if (job.task) {
+ return job;
}
- while (true) {
- // Push done end index as forward as possible
- while (task.done_end < task.children.size() && task.children[task.done_end].done()) {
- ++task.done_end;
- }
-
- if (task.done_end >= task.children.size()) {
- return nullptr; // All child tasks are finished
- }
-
+ while (task.done < task.children.size()) {
// All child tasks claimed, but some are unfinished, steal a task
- if ((t = context.steal_task())) {
- return t;
+ job = context.steal_task();
+ if (job.task) {
+ return job;
}
/* All child tasks are claimed, and we failed to steal any tasks. Spin
@@ -51,7 +45,10 @@ get_task(ParTask& task, RunContext& context)
signal in non-main threads, and maybe even in the main thread
depending on your real-time safe philosophy... more experimentation
here is needed. */
+ _mm_pause();
}
+
+ return Job{nullptr, nullptr};
}
struct Runner
@@ -64,50 +61,50 @@ struct Runner
void operator()(SeqTask& task) {
for (auto& child : task.children) {
- run(child, context);
+ Job job{&child, nullptr};
+ run(job, context);
}
}
void operator()(ParTask& task) {
- // Initialize (not) done state of sub-tasks
- // for (const auto& child : task.children) {
- // child.done = false;
- // }
-
// Grab the first sub-task
- task.next = 0;
- task.done_end = 0;
- Task* t = steal(task, context);
+ task.next = 1;
+ task.done = 0;
+ Job job{&task.children[0], &task};
// Allow other threads to steal sub-tasks
context.claim_task(&task);
// Run available tasks until this task is finished
- for (; t; t = get_task(task, context)) {
- run(*t, context);
+ for (; job.task; job = get_job(task, context)) {
+ run(job, context);
}
context.claim_task(nullptr);
}
- RunContext context;
+ RunContext& context;
+ ParTask* parent;
};
void
-run(Task& task, RunContext& context)
+run(Job& job, RunContext& context)
{
- Runner runner{context};
- boost::apply_visitor(runner, task);
+ Runner runner{context, job.parent};
+ boost::apply_visitor(runner, *job.task);
+ if (job.parent) {
+ ++job.parent->done;
+ }
}
-Task*
+Job
steal(ParTask& task, RunContext& context)
{
const unsigned i = task.next++;
if (i < task.children.size()) {
- return &task.children[i];
+ return Job{&task.children[i], &task};
}
- return nullptr;
+ return Job{nullptr, nullptr};
}
static bool empty(Task& task)