aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/scheduler.ixx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/scheduler.ixx')
-rw-r--r--libbuild2/scheduler.ixx88
1 files changed, 88 insertions, 0 deletions
diff --git a/libbuild2/scheduler.ixx b/libbuild2/scheduler.ixx
new file mode 100644
index 0000000..f46d035
--- /dev/null
+++ b/libbuild2/scheduler.ixx
@@ -0,0 +1,88 @@
+// file : libbuild2/scheduler.ixx -*- C++ -*-
+// license : MIT; see accompanying LICENSE file
+
+namespace build2
+{
+ inline size_t scheduler::
+ wait (size_t start_count, const atomic_count& task_count, work_queue wq)
+ {
+ // Note that task_count is a synchronization point.
+ //
+ size_t tc;
+ if ((tc = task_count.load (memory_order_acquire)) <= start_count)
+ return tc;
+
+ if (optional<size_t> r = wait_impl (start_count, task_count, wq))
+ return *r;
+
+ return suspend (start_count, task_count);
+ }
+
+ inline size_t scheduler::
+ wait (const atomic_count& task_count, work_queue wq)
+ {
+ return wait (0, task_count, wq);
+ }
+
+ template <typename L>
+ inline size_t scheduler::
+ wait (size_t start_count,
+ const atomic_count& task_count,
+ L& lock,
+ work_queue wq)
+ {
+ // Note that task_count is a synchronization point.
+ //
+ size_t tc;
+ if ((tc = task_count.load (memory_order_acquire)) <= start_count)
+ return tc;
+
+ if (optional<size_t> r = wait_impl (start_count, task_count, wq))
+ return *r;
+
+ lock.unlock ();
+ return suspend (start_count, task_count);
+ }
+
+ inline void scheduler::
+ deactivate (bool external)
+ {
+ if (max_active_ != 1) // Serial execution.
+ deactivate_impl (external, lock (mutex_));
+ }
+
+ inline void scheduler::
+ activate (bool external)
+ {
+ if (max_active_ != 1) // Serial execution.
+ activate_impl (external, false /* collision */);
+ }
+
+ inline scheduler::queue_mark::
+ queue_mark (scheduler& s)
+ : tq_ (s.queue ())
+ {
+ if (tq_ != nullptr)
+ {
+ lock ql (tq_->mutex);
+
+ if (tq_->mark != s.task_queue_depth_)
+ {
+ om_ = tq_->mark;
+ tq_->mark = s.task_queue_depth_;
+ }
+ else
+ tq_ = nullptr;
+ }
+ }
+
+ inline scheduler::queue_mark::
+ ~queue_mark ()
+ {
+ if (tq_ != nullptr)
+ {
+ lock ql (tq_->mutex);
+ tq_->mark = tq_->size == 0 ? tq_->tail : om_;
+ }
+ }
+}