Fix race in thread attaching during GC.
Forgot to mask in suspend request if thread is attaching during GC.
Lots of extra assertions and debugging.
Change-Id: Id4d2ab659284acace51b37b86831a968c1945ae8
diff --git a/src/thread_list.cc b/src/thread_list.cc
index 082d7af..56912ac 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -117,12 +117,16 @@
}
}
-void ThreadList::AssertThreadsAreSuspended() {
+void ThreadList::AssertThreadsAreSuspended(Thread* ignore1, Thread* ignore2) {
MutexLock mu(*Locks::thread_list_lock_);
MutexLock mu2(*Locks::thread_suspend_count_lock_);
for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
Thread* thread = *it;
- CHECK_NE(thread->GetState(), kRunnable);
+ if (thread != ignore1 || thread == ignore2) {
+ CHECK(thread->IsSuspended())
+ << "\nUnsuspended thread: <<" << *thread << "\n"
+ << "self: <<" << *Thread::Current();
+ }
}
}
@@ -171,7 +175,7 @@
continue;
}
VLOG(threads) << "requesting thread suspend: " << *thread;
- thread->ModifySuspendCount(+1, false);
+ thread->ModifySuspendCount(self, +1, false);
}
}
}
@@ -190,7 +194,7 @@
#endif
// Debug check that all threads are suspended.
- AssertThreadsAreSuspended();
+ AssertThreadsAreSuspended(self);
VLOG(threads) << *self << " SuspendAll complete";
}
@@ -199,6 +203,10 @@
Thread* self = Thread::Current();
VLOG(threads) << *self << " ResumeAll starting";
+
+ // Debug check that all threads are suspended.
+ AssertThreadsAreSuspended(self);
+
Locks::mutator_lock_->ExclusiveUnlock(self);
{
MutexLock mu(self, *Locks::thread_list_lock_);
@@ -211,7 +219,7 @@
if (thread == self) {
continue;
}
- thread->ModifySuspendCount(-1, false);
+ thread->ModifySuspendCount(self, -1, false);
}
// Broadcast a notification to all suspended threads, some or all of
@@ -236,7 +244,7 @@
if (!Contains(thread)) {
return;
}
- thread->ModifySuspendCount(-1, for_debugger);
+ thread->ModifySuspendCount(self, -1, for_debugger);
}
{
@@ -268,7 +276,7 @@
continue;
}
VLOG(threads) << "requesting thread suspend: " << *thread;
- thread->ModifySuspendCount(+1, true);
+ thread->ModifySuspendCount(self, +1, true);
}
}
}
@@ -289,7 +297,7 @@
Locks::mutator_lock_->ExclusiveLock(self);
Locks::mutator_lock_->ExclusiveUnlock(self);
#endif
- AssertThreadsAreSuspended();
+ AssertThreadsAreSuspended(self, debug_thread);
VLOG(threads) << *self << " SuspendAll complete";
}
@@ -306,7 +314,7 @@
// to ensure that we're the only one fiddling with the suspend count
// though.
MutexLock mu(self, *Locks::thread_suspend_count_lock_);
- self->ModifySuspendCount(+1, true);
+ self->ModifySuspendCount(self, +1, true);
// Suspend ourselves.
CHECK_GT(self->suspend_count_, 0);
@@ -351,7 +359,7 @@
if (thread == self || thread->debug_suspend_count_ == 0) {
continue;
}
- thread->ModifySuspendCount(-thread->debug_suspend_count_, true);
+ thread->ModifySuspendCount(self, -thread->debug_suspend_count_, true);
}
}
@@ -397,7 +405,7 @@
// daemons.
CHECK(thread->IsDaemon());
if (thread != self) {
- thread->ModifySuspendCount(+1, false);
+ thread->ModifySuspendCount(self, +1, false);
}
}
}
@@ -438,6 +446,9 @@
MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
self->suspend_count_ = suspend_all_count_;
self->debug_suspend_count_ = debug_suspend_all_count_;
+ if (self->suspend_count_ > 0) {
+ self->AtomicSetFlag(kSuspendRequest);
+ }
CHECK(!Contains(self));
list_.push_back(self);
}