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);
 }