aboutsummaryrefslogtreecommitdiff
path: root/build2/scheduler
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-02-10 07:56:33 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-02-13 12:42:42 +0200
commitbcb2a89e111a918a48a132a2a29e0c26d724591d (patch)
tree282bd5358f32fa8983c81c0d746d7d05bd5c3ddf /build2/scheduler
parent107357ca4d02341810f47dee20df034e9c4574e0 (diff)
Redo scheduler task flag as atomic counter
Makes for simpler code and also seems to perform better.
Diffstat (limited to 'build2/scheduler')
-rw-r--r--build2/scheduler14
1 files changed, 10 insertions, 4 deletions
diff --git a/build2/scheduler b/build2/scheduler
index 1ce98e8..d2eb0fc 100644
--- a/build2/scheduler
+++ b/build2/scheduler
@@ -282,7 +282,6 @@ namespace build2
std::mutex mutex_;
bool shutdown_ = true; // Shutdown flag.
- bool task_ = false; // Task queued flag (see below).
// The constraints that we must maintain:
//
@@ -348,10 +347,12 @@ namespace build2
// Task queue.
//
- // Each queue has its own mutex. If the task_ flag above is true then
- // there *might* be a task in one of the queues. If it is false, then
- // it means there are definitely no tasks.
+ // Each queue has its own mutex plus we have an atomic total count of the
+ // queued tasks. Note that it should only be modified while holding one
+ // of the queue lock.
//
+ atomic_count queued_task_count_;
+
// For now we only support trivially-destructible tasks.
//
struct task_data
@@ -427,6 +428,7 @@ namespace build2
// | | |
t = s != 0 ? (t != task_queue_depth_ - 1 ? t + 1 : 0) : t;
s++;
+ queued_task_count_.fetch_add (1, std::memory_order_release);
return &tq.data[t];
}
@@ -453,6 +455,8 @@ namespace build2
if (--s == 0 || a)
m = h; // Reset or adjust the mark.
+ queued_task_count_.fetch_sub (1, std::memory_order_release);
+
// The thunk moves the task data to its stack, releases the lock,
// and continues to execute the task.
//
@@ -488,6 +492,8 @@ namespace build2
t = s != 1 ? (t != 0 ? t - 1 : task_queue_depth_ - 1) : t;
--s;
+ queued_task_count_.fetch_sub (1, std::memory_order_release);
+
td.thunk (*this, ql, &td.data);
ql.lock ();