/* This file is part of Ingen. Copyright 2007-2017 David Robillard Ingen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. Ingen is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. You should have received a copy of the GNU Affero General Public License along with Ingen. If not, see . */ #ifndef INGEN_ENGINE_TASK_HPP #define INGEN_ENGINE_TASK_HPP #include #include #include #include #include #include #include #include "Job.hpp" namespace Ingen { namespace Server { class BlockImpl; class RunContext; struct SingleTask; struct MultiTask; struct SeqTask; struct ParTask; using Task = boost::variant; using TaskChildren = std::deque; /** A basic task that contains a single node. */ struct SingleTask { BlockImpl* block; ///< Block to run }; /** Base for tasks that contain multiple children. */ struct MultiTask { /** Prepend a child to this task. */ template void emplace_front(Args... args) { children.emplace_front(std::forward(args)...); } TaskChildren children; ///< Child tasks }; /** A task with children that must be run sequentially in order. */ struct SeqTask : MultiTask { }; /** A task with children that can be run in any order in parallel. */ struct ParTask : MultiTask { ParTask() = default; ParTask(ParTask&& task) : next(task.next.load()) , done(task.done.load()) { children = std::move(task.children); } ParTask& operator=(ParTask&& task) { children = std::move(task.children); next = task.next.load(); done = task.done.load(); return *this; } std::atomic next{0}; ///< Index of next sub-task std::atomic done{0}; ///< Count of finished sub-tasks }; /** Run task in the given context. */ void run(Job& job, RunContext& context); /** Simplify and optimize task. */ Task simplify(Task&& task); /** Steal a child task from this task. */ Job steal(ParTask& task, RunContext& context); /** Pretty print task to the given stream (recursively). */ void dump(Task& task, std::function sink, unsigned indent, bool first); } // namespace Server } // namespace Ingen #endif // INGEN_ENGINE_TASK_HPP