From f8cd75372d9c45a0a8616d89a18a5b9906ac9d54 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 12 Nov 2017 19:57:56 +0100 Subject: WIP: Clean up task implementation --- src/server/CompiledGraph.cpp | 163 ++++++++++++++++++++++++------------------- 1 file changed, 93 insertions(+), 70 deletions(-) (limited to 'src/server/CompiledGraph.cpp') diff --git a/src/server/CompiledGraph.cpp b/src/server/CompiledGraph.cpp index 0d51f284..e4af74ba 100644 --- a/src/server/CompiledGraph.cpp +++ b/src/server/CompiledGraph.cpp @@ -15,6 +15,7 @@ */ #include +#include #include "ingen/ColorContext.hpp" #include "ingen/Configuration.hpp" @@ -23,11 +24,14 @@ #include "CompiledGraph.hpp" #include "Engine.hpp" #include "GraphImpl.hpp" -#include "ThreadManager.hpp" namespace Ingen { namespace Server { +typedef std::set BlockSet; +typedef Task BlockTask; +typedef Work IR; + /** Graph contains ambiguous feedback with no delay nodes. */ class FeedbackException : public std::exception { public: @@ -52,30 +56,6 @@ has_provider_with_many_dependants(BlockImpl* n) return false; } -CompiledGraph::CompiledGraph(GraphImpl* graph) - : _master(Task::Mode::SEQUENTIAL) -{ - compile_graph(graph); -} - -MPtr -CompiledGraph::compile(Raul::Maid& maid, GraphImpl& graph) -{ - try { - return maid.make_managed(&graph); - } catch (FeedbackException e) { - Log& log = graph.engine().log(); - if (e.node && e.root) { - log.error(fmt("Feedback compiling %1% from %2%\n") - % e.node->path() % e.root->path()); - } else { - log.error(fmt("Feedback compiling %1%\n") - % e.node->path()); - } - return MPtr(); - } -} - static size_t num_unvisited_dependants(BlockImpl* block) { @@ -103,11 +83,15 @@ parallel_depth(BlockImpl* block) return 2 + min_provider_depth; } -void -CompiledGraph::compile_graph(GraphImpl* graph) -{ - ThreadManager::assert_thread(THREAD_PRE_PROCESS); +static void +compile_block(BlockImpl* n, + IR& task, + size_t max_depth, + std::set& k); +static BlockTask +compile_graph(GraphImpl* graph) +{ // Start with sink nodes (no outputs, or connected only to graph outputs) std::set blocks; for (auto& b : graph->blocks()) { @@ -120,6 +104,8 @@ CompiledGraph::compile_graph(GraphImpl* graph) } } + IR main = IR::sequential(); + // Keep compiling working set until all nodes are visited while (!blocks.empty()) { std::set predecessors; @@ -130,26 +116,21 @@ CompiledGraph::compile_graph(GraphImpl* graph) depth = std::min(depth, parallel_depth(i)); } - Task par(Task::Mode::PARALLEL); + IR par = IR::parallel(); for (auto b : blocks) { assert(num_unvisited_dependants(b) == 0); - Task seq(Task::Mode::SEQUENTIAL); + IR seq = IR::sequential(); compile_block(b, seq, depth, predecessors); - par.push_front(std::move(seq)); + par.prepend(std::move(seq)); } - _master.push_front(std::move(par)); + main.prepend(std::move(par)); blocks = predecessors; } - _master = Task::simplify(std::move(_master)); - - if (graph->engine().world()->conf().option("trace").get()) { - ColorContext ctx(stderr, ColorContext::Color::YELLOW); - dump(graph->path()); - } + return BlockTask::compile(main); } -/** Throw a FeedbackException iff `dependant` has `root` as a dependency. */ +/** Throw a FeedbackException iff `provider` has `root` as a dependency. */ static void check_feedback(const BlockImpl* root, BlockImpl* provider) { @@ -173,12 +154,12 @@ check_feedback(const BlockImpl* root, BlockImpl* provider) } } -void -CompiledGraph::compile_provider(const BlockImpl* root, - BlockImpl* block, - Task& task, - size_t max_depth, - std::set& k) +static void +compile_provider(const BlockImpl* root, + BlockImpl* block, + IR& task, + size_t max_depth, + std::set& k) { if (block->dependants().size() > 1) { /* Provider has other dependants, so this is the tail of a sequential task. @@ -189,11 +170,11 @@ CompiledGraph::compile_provider(const BlockImpl* root, } } else if (max_depth > 0) { // Calling dependant has only this provider, add here - if (task.mode() == Task::Mode::PARALLEL) { + if (task.mode() == IR::Mode::PARALLEL) { // Inside a parallel task, compile into a new sequential child - Task seq(Task::Mode::SEQUENTIAL); + IR seq = IR::sequential(); compile_block(block, seq, max_depth, k); - task.push_front(std::move(seq)); + task.prepend(std::move(seq)); } else { // Prepend to given sequential task compile_block(block, task, max_depth, k); @@ -205,18 +186,18 @@ CompiledGraph::compile_provider(const BlockImpl* root, } } -void -CompiledGraph::compile_block(BlockImpl* n, - Task& task, - size_t max_depth, - std::set& k) +static void +compile_block(BlockImpl* n, + IR& task, + size_t max_depth, + std::set& k) { switch (n->get_mark()) { case BlockImpl::Mark::UNVISITED: n->set_mark(BlockImpl::Mark::VISITING); // Execute this task after the providers to follow - task.push_front(Task(Task::Mode::SINGLE, n)); + task.prepend(IR::unit(*n)); if (n->providers().size() < 2) { // Single provider, prepend it to this sequential task @@ -233,11 +214,11 @@ CompiledGraph::compile_block(BlockImpl* n, } else { // Multiple providers with only this node as dependant, // make a new parallel task to execute them - Task par(Task::Mode::PARALLEL); + IR par = IR::parallel(); for (auto p : n->providers()) { compile_provider(n, p, par, max_depth - 1, k); } - task.push_front(std::move(par)); + task.prepend(std::move(par)); } n->set_mark(BlockImpl::Mark::VISITED); break; @@ -250,23 +231,65 @@ CompiledGraph::compile_block(BlockImpl* n, } } -void -CompiledGraph::run(RunContext& context) +static void +dump_string(const std::string& str) { - _master.run(context); + fwrite(str.c_str(), 1, str.size(), stderr); } -void -CompiledGraph::dump(const std::string& name) const +static void +dump_task(const BlockTask& task, unsigned indent, bool first) +{ + if (!first) { + dump_string("\n"); + for (unsigned i = 0; i < indent; ++i) { + dump_string(" "); + } + } + + if (task.mode() == BlockTask::Mode::UNIT) { + dump_string(task.unit()->path()); + } else { + dump_string((task.mode() == BlockTask::Mode::SEQUENTIAL) + ? "(seq " + : "(par "); + for (size_t i = 0; i < task.children().size(); ++i) { + dump_task(task.children()[i], indent + 5, i == 0); + } + dump_string(")"); + } +} + +static void +dump(const BlockTask& task, const std::string& name) +{ + dump_string("(compiled-graph "); + dump_string(name); + dump_task(task, 2, false); + dump_string(")\n"); +} + +MPtr +compile(Raul::Maid& maid, GraphImpl& graph) { - auto sink = [](const std::string& s) { - fwrite(s.c_str(), 1, s.size(), stderr); - }; - - sink("(compiled-graph "); - sink(name); - _master.dump(sink, 2, false); - sink(")\n"); + try { + BlockTask master(compile_graph(&graph)); + if (graph.engine().world()->conf().option("trace").get()) { + ColorContext ctx(stderr, ColorContext::Color::YELLOW); + dump(master, graph.path()); + } + return maid.make_managed(std::move(master)); + } catch (FeedbackException e) { + Log& log = graph.engine().log(); + if (e.node && e.root) { + log.error(fmt("Feedback compiling %1% from %2%\n") + % e.node->path() % e.root->path()); + } else { + log.error(fmt("Feedback compiling %1%\n") + % e.node->path()); + } + return MPtr(); + } } } // namespace Server -- cgit v1.2.1