Add SuspendReason enum and change Suspension functions.

More self-documenting and more type safe.

Bug: 62821960
Test: ./test.py
Change-Id: Ic7a1ae6a25e687d65f5aa10c1aad54a7b80dd086
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 46307dd..0dfc60d 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -461,6 +461,7 @@
         "object_callbacks.h",
         "process_state.h",
         "stack.h",
+        "suspend_reason.h",
         "thread.h",
         "thread_state.h",
         "ti/agent.h",
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index cc12439..c94a8e0 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -2446,7 +2446,7 @@
   ThreadList* thread_list = Runtime::Current()->GetThreadList();
   Thread* thread = thread_list->SuspendThreadByPeer(peer.get(),
                                                     request_suspension,
-                                                    /* debug_suspension */ true,
+                                                    SuspendReason::kForDebugger,
                                                     &timed_out);
   if (thread != nullptr) {
     return JDWP::ERR_NONE;
@@ -2477,7 +2477,7 @@
     needs_resume = thread->GetDebugSuspendCount() > 0;
   }
   if (needs_resume) {
-    Runtime::Current()->GetThreadList()->Resume(thread, true);
+    Runtime::Current()->GetThreadList()->Resume(thread, SuspendReason::kForDebugger);
   }
 }
 
@@ -3694,7 +3694,7 @@
           ThreadList* const thread_list = Runtime::Current()->GetThreadList();
           suspended_thread = thread_list->SuspendThreadByPeer(thread_peer,
                                                               /* request_suspension */ true,
-                                                              /* debug_suspension */ true,
+                                                              SuspendReason::kForDebugger,
                                                               &timed_out);
         }
         if (suspended_thread == nullptr) {
@@ -3718,7 +3718,7 @@
 
   ~ScopedDebuggerThreadSuspension() {
     if (other_suspend_) {
-      Runtime::Current()->GetThreadList()->Resume(thread_, true);
+      Runtime::Current()->GetThreadList()->Resume(thread_, SuspendReason::kForDebugger);
     }
   }
 
@@ -4040,7 +4040,7 @@
     thread_list->UndoDebuggerSuspensions();
   } else {
     VLOG(jdwp) << "      Resuming event thread only";
-    thread_list->Resume(targetThread, true);
+    thread_list->Resume(targetThread, SuspendReason::kForDebugger);
   }
 
   return JDWP::ERR_NONE;
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index 940afc8..3e3eaae 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -898,7 +898,9 @@
     Thread* owner;
     {
       ScopedThreadSuspension sts(self, kBlocked);
-      owner = thread_list->SuspendThreadByThreadId(owner_thread_id, false, &timed_out);
+      owner = thread_list->SuspendThreadByThreadId(owner_thread_id,
+                                                   SuspendReason::kInternal,
+                                                   &timed_out);
     }
     if (owner != nullptr) {
       // We succeeded in suspending the thread, check the lock's status didn't change.
@@ -908,7 +910,7 @@
         // Go ahead and inflate the lock.
         Inflate(self, owner, obj.Get(), hash_code);
       }
-      thread_list->Resume(owner, false);
+      thread_list->Resume(owner, SuspendReason::kInternal);
     }
     self->SetMonitorEnterObject(nullptr);
   }
diff --git a/runtime/native/dalvik_system_VMStack.cc b/runtime/native/dalvik_system_VMStack.cc
index e86e64e..7d2d0e5 100644
--- a/runtime/native/dalvik_system_VMStack.cc
+++ b/runtime/native/dalvik_system_VMStack.cc
@@ -51,7 +51,10 @@
     ScopedThreadSuspension sts(soa.Self(), kNative);
     ThreadList* thread_list = Runtime::Current()->GetThreadList();
     bool timed_out;
-    Thread* thread = thread_list->SuspendThreadByPeer(peer, true, false, &timed_out);
+    Thread* thread = thread_list->SuspendThreadByPeer(peer,
+                                                      /* request_suspension */ true,
+                                                      SuspendReason::kInternal,
+                                                      &timed_out);
     if (thread != nullptr) {
       // Must be runnable to create returned array.
       {
@@ -59,7 +62,7 @@
         trace = thread->CreateInternalStackTrace<false>(soa);
       }
       // Restart suspended thread.
-      thread_list->Resume(thread, false);
+      thread_list->Resume(thread, SuspendReason::kInternal);
     } else if (timed_out) {
       LOG(ERROR) << "Trying to get thread's stack failed as the thread failed to suspend within a "
           "generous timeout.";
diff --git a/runtime/native/java_lang_Thread.cc b/runtime/native/java_lang_Thread.cc
index e4d1705..8b76327 100644
--- a/runtime/native/java_lang_Thread.cc
+++ b/runtime/native/java_lang_Thread.cc
@@ -146,13 +146,16 @@
   ThreadList* thread_list = Runtime::Current()->GetThreadList();
   bool timed_out;
   // Take suspend thread lock to avoid races with threads trying to suspend this one.
-  Thread* thread = thread_list->SuspendThreadByPeer(peer, true, false, &timed_out);
+  Thread* thread = thread_list->SuspendThreadByPeer(peer,
+                                                    /* request_suspension */ true,
+                                                    SuspendReason::kInternal,
+                                                    &timed_out);
   if (thread != nullptr) {
     {
       ScopedObjectAccess soa(env);
       thread->SetThreadName(name.c_str());
     }
-    thread_list->Resume(thread, false);
+    thread_list->Resume(thread, SuspendReason::kInternal);
   } else if (timed_out) {
     LOG(ERROR) << "Trying to set thread name to '" << name.c_str() << "' failed as the thread "
         "failed to suspend within a generous timeout.";
diff --git a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc
index 0a254ac..c516b66 100644
--- a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc
+++ b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc
@@ -66,7 +66,9 @@
     }
 
     // Suspend thread to build stack trace.
-    Thread* thread = thread_list->SuspendThreadByThreadId(thin_lock_id, false, &timed_out);
+    Thread* thread = thread_list->SuspendThreadByThreadId(thin_lock_id,
+                                                          SuspendReason::kInternal,
+                                                          &timed_out);
     if (thread != nullptr) {
       {
         ScopedObjectAccess soa(env);
@@ -74,7 +76,7 @@
         trace = Thread::InternalStackTraceToStackTraceElementArray(soa, internal_trace);
       }
       // Restart suspended thread.
-      thread_list->Resume(thread, false);
+      thread_list->Resume(thread, SuspendReason::kInternal);
     } else {
       if (timed_out) {
         LOG(ERROR) << "Trying to get thread's stack by id failed as the thread failed to suspend "
diff --git a/runtime/openjdkjvm/OpenjdkJvm.cc b/runtime/openjdkjvm/OpenjdkJvm.cc
index 0b93b07..4560dda 100644
--- a/runtime/openjdkjvm/OpenjdkJvm.cc
+++ b/runtime/openjdkjvm/OpenjdkJvm.cc
@@ -422,14 +422,17 @@
   // Take suspend thread lock to avoid races with threads trying to suspend this one.
   art::Thread* thread;
   {
-    thread = thread_list->SuspendThreadByPeer(jthread, true, false, &timed_out);
+    thread = thread_list->SuspendThreadByPeer(jthread,
+                                              true,
+                                              art::SuspendReason::kInternal,
+                                              &timed_out);
   }
   if (thread != NULL) {
     {
       art::ScopedObjectAccess soa(env);
       thread->SetThreadName(name.c_str());
     }
-    thread_list->Resume(thread, false);
+    thread_list->Resume(thread, art::SuspendReason::kInternal);
   } else if (timed_out) {
     LOG(ERROR) << "Trying to set thread name to '" << name.c_str() << "' failed as the thread "
         "failed to suspend within a generous timeout.";
diff --git a/runtime/suspend_reason.h b/runtime/suspend_reason.h
new file mode 100644
index 0000000..27c4d32
--- /dev/null
+++ b/runtime/suspend_reason.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_SUSPEND_REASON_H_
+#define ART_RUNTIME_SUSPEND_REASON_H_
+
+#include <ostream>
+
+namespace art {
+
+// The various reasons that we might be suspending a thread.
+enum class SuspendReason {
+  // Suspending for internal reasons (e.g. GC, stack trace, etc.).
+  // TODO Split this into more descriptive sections.
+  kInternal,
+  // Suspending for debugger (code in Dbg::*, runtime/jdwp/, etc.).
+  kForDebugger,
+};
+
+std::ostream& operator<<(std::ostream& os, const SuspendReason& thread);
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_SUSPEND_REASON_H_
diff --git a/runtime/thread-inl.h b/runtime/thread-inl.h
index 7da15d9..95608b5 100644
--- a/runtime/thread-inl.h
+++ b/runtime/thread-inl.h
@@ -330,12 +330,12 @@
 inline bool Thread::ModifySuspendCount(Thread* self,
                                        int delta,
                                        AtomicInteger* suspend_barrier,
-                                       bool for_debugger) {
+                                       SuspendReason reason) {
   if (delta > 0 && ((kUseReadBarrier && this != self) || suspend_barrier != nullptr)) {
     // When delta > 0 (requesting a suspend), ModifySuspendCountInternal() may fail either if
     // active_suspend_barriers is full or we are in the middle of a thread flip. Retry in a loop.
     while (true) {
-      if (LIKELY(ModifySuspendCountInternal(self, delta, suspend_barrier, for_debugger))) {
+      if (LIKELY(ModifySuspendCountInternal(self, delta, suspend_barrier, reason))) {
         return true;
       } else {
         // Failure means the list of active_suspend_barriers is full or we are in the middle of a
@@ -354,7 +354,7 @@
       }
     }
   } else {
-    return ModifySuspendCountInternal(self, delta, suspend_barrier, for_debugger);
+    return ModifySuspendCountInternal(self, delta, suspend_barrier, reason);
   }
 }
 
diff --git a/runtime/thread.cc b/runtime/thread.cc
index be1614b..a811666 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1178,10 +1178,10 @@
 bool Thread::ModifySuspendCountInternal(Thread* self,
                                         int delta,
                                         AtomicInteger* suspend_barrier,
-                                        bool for_debugger) {
+                                        SuspendReason reason) {
   if (kIsDebugBuild) {
     DCHECK(delta == -1 || delta == +1 || delta == -tls32_.debug_suspend_count)
-          << delta << " " << tls32_.debug_suspend_count << " " << this;
+          << reason << " " << delta << " " << tls32_.debug_suspend_count << " " << this;
     DCHECK_GE(tls32_.suspend_count, tls32_.debug_suspend_count) << this;
     Locks::thread_suspend_count_lock_->AssertHeld(self);
     if (this != self && !IsSuspended()) {
@@ -1217,8 +1217,12 @@
   }
 
   tls32_.suspend_count += delta;
-  if (for_debugger) {
-    tls32_.debug_suspend_count += delta;
+  switch (reason) {
+    case SuspendReason::kForDebugger:
+      tls32_.debug_suspend_count += delta;
+      break;
+    case SuspendReason::kInternal:
+      break;
   }
 
   if (tls32_.suspend_count == 0) {
@@ -1458,7 +1462,7 @@
     {
       MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
 
-      if (!ModifySuspendCount(self, +1, nullptr, false)) {
+      if (!ModifySuspendCount(self, +1, nullptr, SuspendReason::kInternal)) {
         // Just retry the loop.
         sched_yield();
         continue;
@@ -1483,7 +1487,7 @@
       MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
 
       DCHECK_NE(GetState(), ThreadState::kRunnable);
-      bool updated = ModifySuspendCount(self, -1, nullptr, false);
+      bool updated = ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal);
       DCHECK(updated);
     }
 
diff --git a/runtime/thread.h b/runtime/thread.h
index 770173e..e785ddc 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -40,6 +40,7 @@
 #include "managed_stack.h"
 #include "offsets.h"
 #include "runtime_stats.h"
+#include "suspend_reason.h"
 #include "thread_state.h"
 
 class BacktraceMap;
@@ -244,7 +245,7 @@
   bool ModifySuspendCount(Thread* self,
                           int delta,
                           AtomicInteger* suspend_barrier,
-                          bool for_debugger)
+                          SuspendReason reason)
       WARN_UNUSED
       REQUIRES(Locks::thread_suspend_count_lock_);
 
@@ -1300,7 +1301,7 @@
   bool ModifySuspendCountInternal(Thread* self,
                                   int delta,
                                   AtomicInteger* suspend_barrier,
-                                  bool for_debugger)
+                                  SuspendReason reason)
       WARN_UNUSED
       REQUIRES(Locks::thread_suspend_count_lock_);
 
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 95aba79..fc767ed 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -332,7 +332,7 @@
               // Spurious fail, try again.
               continue;
             }
-            bool updated = thread->ModifySuspendCount(self, +1, nullptr, false);
+            bool updated = thread->ModifySuspendCount(self, +1, nullptr, SuspendReason::kInternal);
             DCHECK(updated);
             suspended_count_modified_threads.push_back(thread);
             break;
@@ -375,7 +375,7 @@
     checkpoint_function->Run(thread);
     {
       MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
-      bool updated = thread->ModifySuspendCount(self, -1, nullptr, false);
+      bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal);
       DCHECK(updated);
     }
   }
@@ -583,7 +583,7 @@
       if ((state == kWaitingForGcThreadFlip || thread->IsTransitioningToRunnable()) &&
           thread->GetSuspendCount() == 1) {
         // The thread will resume right after the broadcast.
-        bool updated = thread->ModifySuspendCount(self, -1, nullptr, false);
+        bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal);
         DCHECK(updated);
         ++runnable_thread_count;
       } else {
@@ -617,7 +617,7 @@
     TimingLogger::ScopedTiming split4("ResumeOtherThreads", collector->GetTimings());
     MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
     for (const auto& thread : other_threads) {
-      bool updated = thread->ModifySuspendCount(self, -1, nullptr, false);
+      bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal);
       DCHECK(updated);
     }
     Thread::resume_cond_->Broadcast(self);
@@ -688,7 +688,7 @@
 void ThreadList::SuspendAllInternal(Thread* self,
                                     Thread* ignore1,
                                     Thread* ignore2,
-                                    bool debug_suspend) {
+                                    SuspendReason reason) {
   Locks::mutator_lock_->AssertNotExclusiveHeld(self);
   Locks::thread_list_lock_->AssertNotHeld(self);
   Locks::thread_suspend_count_lock_->AssertNotHeld(self);
@@ -718,7 +718,7 @@
     MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
     // Update global suspend all state for attaching threads.
     ++suspend_all_count_;
-    if (debug_suspend) {
+    if (reason == SuspendReason::kForDebugger) {
       ++debug_suspend_all_count_;
     }
     pending_threads.StoreRelaxed(list_.size() - num_ignored);
@@ -728,7 +728,7 @@
         continue;
       }
       VLOG(threads) << "requesting thread suspend: " << *thread;
-      bool updated = thread->ModifySuspendCount(self, +1, &pending_threads, debug_suspend);
+      bool updated = thread->ModifySuspendCount(self, +1, &pending_threads, reason);
       DCHECK(updated);
 
       // Must install the pending_threads counter first, then check thread->IsSuspend() and clear
@@ -807,7 +807,7 @@
       if (thread == self) {
         continue;
       }
-      bool updated = thread->ModifySuspendCount(self, -1, nullptr, false);
+      bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal);
       DCHECK(updated);
     }
 
@@ -828,14 +828,13 @@
   }
 }
 
-void ThreadList::Resume(Thread* thread, bool for_debugger) {
+void ThreadList::Resume(Thread* thread, SuspendReason reason) {
   // This assumes there was an ATRACE_BEGIN when we suspended the thread.
   ATRACE_END();
 
   Thread* self = Thread::Current();
   DCHECK_NE(thread, self);
-  VLOG(threads) << "Resume(" << reinterpret_cast<void*>(thread) << ") starting..."
-      << (for_debugger ? " (debugger)" : "");
+  VLOG(threads) << "Resume(" << reinterpret_cast<void*>(thread) << ") starting..." << reason;
 
   {
     // To check Contains.
@@ -850,7 +849,7 @@
           << ") thread not within thread list";
       return;
     }
-    bool updated = thread->ModifySuspendCount(self, -1, nullptr, for_debugger);
+    bool updated = thread->ModifySuspendCount(self, -1, nullptr, reason);
     DCHECK(updated);
   }
 
@@ -882,7 +881,7 @@
 
 Thread* ThreadList::SuspendThreadByPeer(jobject peer,
                                         bool request_suspension,
-                                        bool debug_suspension,
+                                        SuspendReason reason,
                                         bool* timed_out) {
   const uint64_t start_time = NanoTime();
   useconds_t sleep_us = kThreadSuspendInitialSleepUs;
@@ -910,7 +909,7 @@
           bool updated = suspended_thread->ModifySuspendCount(soa.Self(),
                                                               -1,
                                                               nullptr,
-                                                              debug_suspension);
+                                                              reason);
           DCHECK(updated);
         }
         ThreadSuspendByPeerWarning(self,
@@ -937,7 +936,7 @@
           }
           CHECK(suspended_thread == nullptr);
           suspended_thread = thread;
-          bool updated = suspended_thread->ModifySuspendCount(self, +1, nullptr, debug_suspension);
+          bool updated = suspended_thread->ModifySuspendCount(self, +1, nullptr, reason);
           DCHECK(updated);
           request_suspension = false;
         } else {
@@ -973,7 +972,7 @@
             bool updated = suspended_thread->ModifySuspendCount(soa.Self(),
                                                                 -1,
                                                                 nullptr,
-                                                                debug_suspension);
+                                                                reason);
             DCHECK(updated);
           }
           *timed_out = true;
@@ -1002,7 +1001,7 @@
 }
 
 Thread* ThreadList::SuspendThreadByThreadId(uint32_t thread_id,
-                                            bool debug_suspension,
+                                            SuspendReason reason,
                                             bool* timed_out) {
   const uint64_t start_time = NanoTime();
   useconds_t sleep_us = kThreadSuspendInitialSleepUs;
@@ -1047,7 +1046,7 @@
             // which will allow this thread to be suspended.
             continue;
           }
-          bool updated = thread->ModifySuspendCount(self, +1, nullptr, debug_suspension);
+          bool updated = thread->ModifySuspendCount(self, +1, nullptr, reason);
           DCHECK(updated);
           suspended_thread = thread;
         } else {
@@ -1079,7 +1078,7 @@
                                          "Thread suspension timed out",
                                          thread_id);
           if (suspended_thread != nullptr) {
-            bool updated = thread->ModifySuspendCount(soa.Self(), -1, nullptr, debug_suspension);
+            bool updated = thread->ModifySuspendCount(soa.Self(), -1, nullptr, reason);
             DCHECK(updated);
           }
           *timed_out = true;
@@ -1114,7 +1113,7 @@
 
   VLOG(threads) << *self << " SuspendAllForDebugger starting...";
 
-  SuspendAllInternal(self, self, debug_thread, true);
+  SuspendAllInternal(self, self, debug_thread, SuspendReason::kForDebugger);
   // Block on the mutator lock until all Runnable threads release their share of access then
   // immediately unlock again.
 #if HAVE_TIMED_RWLOCK
@@ -1157,7 +1156,7 @@
     // to ensure that we're the only one fiddling with the suspend count
     // though.
     MutexLock mu(self, *Locks::thread_suspend_count_lock_);
-    bool updated = self->ModifySuspendCount(self, +1, nullptr, true);
+    bool updated = self->ModifySuspendCount(self, +1, nullptr, SuspendReason::kForDebugger);
     DCHECK(updated);
     CHECK_GT(self->GetSuspendCount(), 0);
 
@@ -1242,7 +1241,7 @@
           continue;
         }
         VLOG(threads) << "requesting thread resume: " << *thread;
-        bool updated = thread->ModifySuspendCount(self, -1, nullptr, true);
+        bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kForDebugger);
         DCHECK(updated);
       }
     }
@@ -1275,7 +1274,7 @@
       bool suspended = thread->ModifySuspendCount(self,
                                                   -thread->GetDebugSuspendCount(),
                                                   nullptr,
-                                                  true);
+                                                  SuspendReason::kForDebugger);
       DCHECK(suspended);
     }
   }
@@ -1333,7 +1332,7 @@
       // daemons.
       CHECK(thread->IsDaemon()) << *thread;
       if (thread != self) {
-        bool updated = thread->ModifySuspendCount(self, +1, nullptr, false);
+        bool updated = thread->ModifySuspendCount(self, +1, nullptr, SuspendReason::kInternal);
         DCHECK(updated);
         ++daemons_left;
       }
@@ -1394,11 +1393,11 @@
   // Modify suspend count in increments of 1 to maintain invariants in ModifySuspendCount. While
   // this isn't particularly efficient the suspend counts are most commonly 0 or 1.
   for (int delta = debug_suspend_all_count_; delta > 0; delta--) {
-    bool updated = self->ModifySuspendCount(self, +1, nullptr, true);
+    bool updated = self->ModifySuspendCount(self, +1, nullptr, SuspendReason::kForDebugger);
     DCHECK(updated);
   }
   for (int delta = suspend_all_count_ - debug_suspend_all_count_; delta > 0; delta--) {
-    bool updated = self->ModifySuspendCount(self, +1, nullptr, false);
+    bool updated = self->ModifySuspendCount(self, +1, nullptr, SuspendReason::kInternal);
     DCHECK(updated);
   }
   CHECK(!Contains(self));
@@ -1495,12 +1494,12 @@
     MutexLock mu(self, *Locks::thread_list_lock_);
     MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
     for (Thread* thread : list_) {
-      bool suspended = thread->ModifySuspendCount(self, +1, nullptr, false);
+      bool suspended = thread->ModifySuspendCount(self, +1, nullptr, SuspendReason::kInternal);
       DCHECK(suspended);
       if (thread == self || thread->IsSuspended()) {
         threads_to_visit.push_back(thread);
       } else {
-        bool resumed = thread->ModifySuspendCount(self, -1, nullptr, false);
+        bool resumed = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal);
         DCHECK(resumed);
       }
     }
@@ -1516,7 +1515,7 @@
   {
     MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
     for (Thread* thread : threads_to_visit) {
-      bool updated = thread->ModifySuspendCount(self, -1, nullptr, false);
+      bool updated = thread->ModifySuspendCount(self, -1, nullptr, SuspendReason::kInternal);
       DCHECK(updated);
     }
   }
diff --git a/runtime/thread_list.h b/runtime/thread_list.h
index 92702c6..41c5e32 100644
--- a/runtime/thread_list.h
+++ b/runtime/thread_list.h
@@ -23,6 +23,7 @@
 #include "base/time_utils.h"
 #include "base/value_object.h"
 #include "jni.h"
+#include "suspend_reason.h"
 
 #include <bitset>
 #include <list>
@@ -64,7 +65,7 @@
   void ResumeAll()
       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
       UNLOCK_FUNCTION(Locks::mutator_lock_);
-  void Resume(Thread* thread, bool for_debugger = false)
+  void Resume(Thread* thread, SuspendReason reason = SuspendReason::kInternal)
       REQUIRES(!Locks::thread_suspend_count_lock_);
 
   // Suspends all threads and gets exclusive access to the mutator_lock_.
@@ -81,7 +82,9 @@
   // If the thread should be suspended then value of request_suspension should be true otherwise
   // the routine will wait for a previous suspend request. If the suspension times out then *timeout
   // is set to true.
-  Thread* SuspendThreadByPeer(jobject peer, bool request_suspension, bool debug_suspension,
+  Thread* SuspendThreadByPeer(jobject peer,
+                              bool request_suspension,
+                              SuspendReason reason,
                               bool* timed_out)
       REQUIRES(!Locks::mutator_lock_,
                !Locks::thread_list_lock_,
@@ -91,7 +94,7 @@
   // thread on success else null. The thread id is used to identify the thread to avoid races with
   // the thread terminating. Note that as thread ids are recycled this may not suspend the expected
   // thread, that may be terminating. If the suspension times out then *timeout is set to true.
-  Thread* SuspendThreadByThreadId(uint32_t thread_id, bool debug_suspension, bool* timed_out)
+  Thread* SuspendThreadByThreadId(uint32_t thread_id, SuspendReason reason, bool* timed_out)
       REQUIRES(!Locks::mutator_lock_,
                !Locks::thread_list_lock_,
                !Locks::thread_suspend_count_lock_);
@@ -198,7 +201,7 @@
   void SuspendAllInternal(Thread* self,
                           Thread* ignore1,
                           Thread* ignore2 = nullptr,
-                          bool debug_suspend = false)
+                          SuspendReason reason = SuspendReason::kInternal)
       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
 
   void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = nullptr)