summaryrefslogtreecommitdiffstats
path: root/src/server/Task.hpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-03-29 10:56:18 +0200
committerDavid Robillard <d@drobilla.net>2018-03-29 10:56:18 +0200
commit7a5e694c3ffed12532ee2b97f99c4b56dbba4d02 (patch)
tree483f736f406a40093f1f65444d76f12b89caaf7e /src/server/Task.hpp
parentc9863ba79edbac7ae78ad0e374a2988c816ad31a (diff)
downloadingen-7a5e694c3ffed12532ee2b97f99c4b56dbba4d02.tar.gz
ingen-7a5e694c3ffed12532ee2b97f99c4b56dbba4d02.tar.bz2
ingen-7a5e694c3ffed12532ee2b97f99c4b56dbba4d02.zip
WIP: more variant task
Diffstat (limited to 'src/server/Task.hpp')
-rw-r--r--src/server/Task.hpp112
1 files changed, 25 insertions, 87 deletions
diff --git a/src/server/Task.hpp b/src/server/Task.hpp
index 25f76260..79ada9f0 100644
--- a/src/server/Task.hpp
+++ b/src/server/Task.hpp
@@ -39,25 +39,29 @@ struct ParTask;
using Task = boost::variant<SingleTask, SeqTask, ParTask>;
-using TaskChildren = std::deque<std::unique_ptr<Task>>;
+using TaskChildren = std::deque<Task>;
+/** 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<typename... Args>
void emplace_front(Args... args) {
- children.emplace_front(new Task(std::forward<Args>(args)...));
+ children.emplace_front(std::forward<Args>(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;
@@ -65,105 +69,39 @@ struct ParTask : MultiTask {
: done_end(task.done_end)
, next(task.next.load())
, done(task.done.load())
- {}
-
- unsigned done_end{0}; ///< Index of rightmost done sub-task
- std::atomic<unsigned> next{0}; ///< Index of next sub-task
- std::atomic<bool> done{false}; ///< Completion phase
-};
-
- #if 0
-class Task {
-public:
- enum class Mode {
- SINGLE, ///< Single block to run
- SEQUENTIAL, ///< Elements must be run sequentially in order
- PARALLEL ///< Elements may be run in any order in parallel
- };
-
- explicit Task(BlockImpl* block)
- : _block(block)
- , _mode(Mode::SINGLE)
- , _done_end(0)
- , _next(0)
- , _done(false)
- {
- assert(block);
- assert(!(_mode == Mode::SINGLE && !_block));
- }
-
-
- Task(Mode mode)
- : _block(nullptr)
- , _mode(mode)
- , _done_end(0)
- , _next(0)
- , _done(false)
{
- assert(!(_mode == Mode::SINGLE && !_block));
- }
-
- /** Run task in the given context. */
- void run(RunContext& context);
-
- /** Pretty print task to the given stream (recursively). */
- void dump(std::function<void (const std::string&)> sink, unsigned indent, bool first) const;
-
- /** Return true iff this is an empty task. */
- bool empty() const { return _mode != Mode::SINGLE && _children.empty(); }
-
- /** Simplify task expression. */
- static std::unique_ptr<Task> simplify(std::unique_ptr<Task>&& task);
-
- /** Steal a child task from this task (succeeds for PARALLEL only). */
- Task* steal(RunContext& context);
-
- /** Return the child task at the front of this task. */
- Task& front() const {
- return *_children.front();
- }
-
- /** Prepend a child to this task. */
- template<typename... Args>
- void emplace_front(Args... args) {
- _children.emplace_front(std::unique_ptr<Task>(new Task(std::forward<Args>(args)...)));
+ children = std::move(task.children);
}
- Mode mode() const { return _mode; }
- BlockImpl* block() const { return _block; }
- bool done() const { return _done; }
-
- void set_done(bool done) { _done = done; }
-
-private:
- typedef std::deque<std::unique_ptr<Task>> Children;
-
- Task(const Task&) = delete;
- Task& operator=(const Task&) = delete;
-
- Task* get_task(RunContext& context);
-
- void append(std::unique_ptr<Task>&& t) {
- _children.emplace_back(std::move(t));
+ ParTask& operator=(ParTask&& task) {
+ children = std::move(task.children);
+ done_end = task.done_end;
+ next = task.next.load();
+ done = task.done.load();
+ return *this;
}
- Children _children; ///< Vector of child tasks
- BlockImpl* _block; ///< Used for SINGLE only
- Mode _mode; ///< Execution mode
- unsigned _done_end; ///< Index of rightmost done sub-task
- std::atomic<unsigned> _next; ///< Index of next sub-task
- std::atomic<bool> _done; ///< Completion phase
+ unsigned done_end{0}; ///< Index of rightmost done sub-task
+ std::atomic<unsigned> next{0}; ///< Index of next sub-task
+ std::atomic<bool> done{false}; ///< Completion phase
};
-#endif
+struct Job {
+ Task task;
+};
+/** Run task in the given context. */
void run(Task& task, RunContext& context);
-std::unique_ptr<Task> simplify(std::unique_ptr<Task>&& task);
+/** Simplify and optimize task. */
+Task simplify(Task&& task);
/** Steal a child task from this task. */
Task* steal(ParTask& task, RunContext& context);
+/** Pretty print task to the given stream (recursively). */
+void dump(Task& task, std::function<void (const std::string&)> sink, unsigned indent, bool first);
+
} // namespace Server
} // namespace Ingen