diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-02-10 07:56:33 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-02-13 12:42:42 +0200 |
commit | bcb2a89e111a918a48a132a2a29e0c26d724591d (patch) | |
tree | 282bd5358f32fa8983c81c0d746d7d05bd5c3ddf /build2/scheduler | |
parent | 107357ca4d02341810f47dee20df034e9c4574e0 (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/scheduler | 14 |
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 (); |