/* 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 "Work.hpp" namespace Ingen { namespace Server { class Runner; class BlockImpl; class Task { public: using Unit = BlockImpl; using IR = Work; using Mode = typename IR::Mode; using Children = std::vector; Task(Task&& task) : _children(std::move(task._children)) , _unit(task._unit) , _mode(task._mode) , _done_end(task._done_end) , _next(task._next.load()) , _done(task._done.load()) {} Task(const Task&) = delete; Task& operator=(const Task&) = delete; /** Run task in the given context. */ void run(Runner& context); /** Return true iff this is an empty task. */ bool empty() const { return _mode != Mode::UNIT && _children.empty(); } /** Simplify task expression. */ static Task compile(const IR& source); /** Steal a child task from this task (succeeds for PARALLEL only). */ Task* steal(Runner& context); Mode mode() const { return _mode; } Unit* unit() const { return _unit; } const Children& children() const { return _children; } bool done() const { return _done; } void set_done(bool done) { _done = done; } private: Task(Mode mode, Unit* unit = nullptr) : _unit(unit) , _mode(mode) , _done_end(0) , _next(0) , _done(false) { assert(!(mode == Mode::UNIT && !unit)); } Task* get_task(Runner& context); void append(Task t) { _children.emplace_back(std::move(t)); } Children _children; ///< Vector of child tasks Unit* _unit; ///< Used for UNIT only Mode _mode; ///< Execution mode unsigned _done_end; ///< Index of rightmost done sub-task std::atomic _next; ///< Index of next sub-task std::atomic _done; ///< Completion phase }; } // namespace Server } // namespace Ingen #endif // INGEN_ENGINE_TASK_HPP