Implement mutex requeueing for cv broadcasts.
Make the mutex guarding a condition variable part of its state. On a
broadcast requeue waiters on the mutex so they are awoken as the mutex
is unlocked (thereby avoiding thundering herds). Explicit futex use
still guarded behind ART_USE_FUTEXES which remains disabled as I'm
unhappy with some of the warts of mutex usage. Uploading so that the API
changes can stabilize.
Change-Id: Iedb601856ccd8bbc3a64da4ba0cee82246e7bcbf
diff --git a/src/heap.cc b/src/heap.cc
index 2f5362e..98845d8 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -279,7 +279,8 @@
// but we can create the heap lock now. We don't create it earlier to
// make it clear that you can't use locks during heap initialization.
gc_complete_lock_ = new Mutex("GC complete lock");
- gc_complete_cond_.reset(new ConditionVariable("GC complete condition variable"));
+ gc_complete_cond_.reset(new ConditionVariable("GC complete condition variable",
+ *gc_complete_lock_));
// Set up the cumulative timing loggers.
for (size_t i = static_cast<size_t>(kGcTypeSticky); i < static_cast<size_t>(kGcTypeMax);
@@ -963,7 +964,7 @@
is_gc_running_ = false;
last_gc_type_ = gc_type;
// Wake anyone who may have been waiting for the GC to complete.
- gc_complete_cond_->Broadcast();
+ gc_complete_cond_->Broadcast(self);
}
// Inform DDMS that a GC completed.
Dbg::GcDidFinish();
@@ -1803,7 +1804,7 @@
{
MutexLock mu(self, *gc_complete_lock_);
while (is_gc_running_) {
- gc_complete_cond_->Wait(self, *gc_complete_lock_);
+ gc_complete_cond_->Wait(self);
}
last_gc_type = last_gc_type_;
wait_time = NanoTime() - wait_start;;