/*
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