aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-01-02 16:00:58 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-01-02 16:00:58 +0200
commit80c3fa5476bbdab479b57e892001b3259b5b3537 (patch)
tree866dc1d3fd746f0d4b6e6806b75ee983e939846e
parent8d743ac19a1b0c15deccfb14525eaeef56b4135b (diff)
Fix data race (tsan) bug
-rw-r--r--build2/scheduler.cxx10
-rw-r--r--build2/scheduler.hxx17
2 files changed, 15 insertions, 12 deletions
diff --git a/build2/scheduler.cxx b/build2/scheduler.cxx
index cd621bc..e6a0bc6 100644
--- a/build2/scheduler.cxx
+++ b/build2/scheduler.cxx
@@ -186,8 +186,8 @@ namespace build2
try { shutdown (); } catch (system_error&) {}
}
- void scheduler::
- wait_idle ()
+ auto scheduler::
+ wait_idle () -> lock
{
lock l (mutex_);
@@ -200,6 +200,8 @@ namespace build2
this_thread::yield ();
l.lock ();
}
+
+ return l;
}
size_t scheduler::
@@ -319,7 +321,7 @@ namespace build2
// The scheduler must not be active though some threads might still be
// comming off from finishing a task. So we busy-wait for them.
//
- wait_idle ();
+ lock l (wait_idle ());
max_active_ = max_active;
}
@@ -411,7 +413,7 @@ namespace build2
// comming off from finishing a task and trying to report progress. So we
// busy-wait for them (also in ~monitor_guard()).
//
- wait_idle ();
+ lock l (wait_idle ());
monitor_count_ = &c;
monitor_tshold_.store (t, memory_order_relaxed);
diff --git a/build2/scheduler.hxx b/build2/scheduler.hxx
index 20e5128..4880392 100644
--- a/build2/scheduler.hxx
+++ b/build2/scheduler.hxx
@@ -256,7 +256,7 @@ namespace build2
{
if (s_ != nullptr)
{
- s_->wait_idle (); // See monitor() for details.
+ lock l (s_->wait_idle ()); // See monitor() for details.
s_->monitor_count_ = nullptr;
s_->monitor_func_ = nullptr;
}
@@ -300,12 +300,6 @@ namespace build2
task_queue_ = nullptr;
}
- // Assuming all the task have been executed, busy-wait for all the threads
- // to become idle. Normally you don't need to call this function directly.
- //
- void
- wait_idle ();
-
// Return the number of hardware threads or 0 if unable to determine.
//
static size_t
@@ -324,9 +318,16 @@ namespace build2
size_t
shard_size (size_t mul = 1, size_t div = 1) const;
- private:
+ // Assuming all the task have been executed, busy-wait for all the threads
+ // to become idle. Return the lock over the scheduler mutex. Normally you
+ // don't need to call this function directly.
+ //
using lock = std::unique_lock<std::mutex>;
+ lock
+ wait_idle ();
+
+ private:
void
activate_helper (lock&);