diff options
Diffstat (limited to 'src/server/Task.cpp')
-rw-r--r-- | src/server/Task.cpp | 133 |
1 files changed, 72 insertions, 61 deletions
diff --git a/src/server/Task.cpp b/src/server/Task.cpp index d2cb2683..0978e15d 100644 --- a/src/server/Task.cpp +++ b/src/server/Task.cpp @@ -17,76 +17,27 @@ #include "BlockImpl.hpp" #include "Task.hpp" +#include <boost/variant/get.hpp> + namespace Ingen { namespace Server { -void -Task::run(RunContext& context) -{ - switch (_mode) { - case Mode::SINGLE: - // fprintf(stderr, "%u run %s\n", context.id(), _block->path().c_str()); - _block->process(context); - break; - case Mode::SEQUENTIAL: - for (const auto& task : _children) { - task->run(context); - } - break; - case Mode::PARALLEL: - // Initialize (not) done state of sub-tasks - for (const auto& task : _children) { - task->set_done(false); - } - - // Grab the first sub-task - _next = 0; - _done_end = 0; - Task* t = steal(context); - - // Allow other threads to steal sub-tasks - context.claim_task(this); - - // Run available tasks until this task is finished - for (; t; t = get_task(context)) { - t->run(context); - } - context.claim_task(nullptr); - break; - } - - set_done(true); -} - -Task* -Task::steal(RunContext& context) -{ - if (_mode == Mode::PARALLEL) { - const unsigned i = _next++; - if (i < _children.size()) { - return _children[i].get(); - } - } - - return nullptr; -} - -Task* -Task::get_task(RunContext& context) +static Task* +get_task(ParTask& task, RunContext& context) { // Attempt to "steal" a task from ourselves - Task* t = steal(context); + Task* t = steal(task, context); if (t) { return t; } while (true) { // Push done end index as forward as possible - while (_done_end < _children.size() && _children[_done_end]->done()) { - ++_done_end; - } + // while (task.done_end < task.children.size() && task.children[task.done_end]->done()) { + // ++task.done_end; + // } - if (_done_end >= _children.size()) { + if (task.done_end >= task.children.size()) { return nullptr; // All child tasks are finished } @@ -103,10 +54,67 @@ Task::get_task(RunContext& context) } } +struct Runner +{ + using result_type = void; + + void operator()(SingleTask& task) { + task.block->process(context); + } + + void operator()(SeqTask& task) { + for (const auto& child : task.children) { + run(*child, 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); + + // 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); + } + context.claim_task(nullptr); + } + + RunContext context; +}; + +void +run(Task& task, RunContext& context) +{ + Runner runner{context}; + boost::apply_visitor(runner, task); +} + +Task* +steal(ParTask& task, RunContext& context) +{ + const unsigned i = task.next++; + if (i < task.children.size()) { + return task.children[i].get(); + } + + return nullptr; +} + std::unique_ptr<Task> -Task::simplify(std::unique_ptr<Task>&& task) +simplify(std::unique_ptr<Task>&& task) { - if (task->mode() == Mode::SINGLE) { +#if 0 + if (boost::get<SingleTask>(task.get())) { return std::move(task); } @@ -129,10 +137,12 @@ Task::simplify(std::unique_ptr<Task>&& task) if (ret->_children.size() == 1) { return std::move(ret->_children.front()); } - return ret; +#endif + return nullptr; } +#if 0 void Task::dump(std::function<void (const std::string&)> sink, unsigned indent, bool first) const { @@ -153,6 +163,7 @@ Task::dump(std::function<void (const std::string&)> sink, unsigned indent, bool sink(")"); } } +#endif } // namespace Server } // namespace Ingen |