aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/scheduler.ixx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-05-12 10:46:21 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-05-12 16:30:12 +0200
commit88379eedeae654391711d8cdda17dfc2be6367ef (patch)
tree966ee03369b51013021600a2beea8334962ab2ec /libbuild2/scheduler.ixx
parent8b858c642ccab43050dcff2d8f98db469ac6dc1b (diff)
Keep phase locked while working own queue
Diffstat (limited to 'libbuild2/scheduler.ixx')
-rw-r--r--libbuild2/scheduler.ixx35
1 files changed, 35 insertions, 0 deletions
diff --git a/libbuild2/scheduler.ixx b/libbuild2/scheduler.ixx
index f9f0f2e..4cf347c 100644
--- a/libbuild2/scheduler.ixx
+++ b/libbuild2/scheduler.ixx
@@ -3,6 +3,41 @@
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);
+ }
+
+ 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 scheduler::queue_mark::
queue_mark (scheduler& s)
: tq_ (s.queue ())