Add Jvmti Suspend/ResumeThread functions

Enable the can_suspend jvmti capability and implement all required
functionality associated with it.

Test: ./test.py --host -j40
Bug: 34415266
Bug: 62821960
Bug: 63579748

Change-Id: I83b92de7f81622e1658114b034918e8295805b6e
diff --git a/runtime/openjdkjvmti/ti_thread.h b/runtime/openjdkjvmti/ti_thread.h
index 939aea7..57967eb 100644
--- a/runtime/openjdkjvmti/ti_thread.h
+++ b/runtime/openjdkjvmti/ti_thread.h
@@ -35,8 +35,11 @@
 #include "jni.h"
 #include "jvmti.h"
 
+#include "base/mutex.h"
+
 namespace art {
 class ArtField;
+class Thread;
 }  // namespace art
 
 namespace openjdkjvmti {
@@ -68,7 +71,33 @@
                                    const void* arg,
                                    jint priority);
 
+  static jvmtiError SuspendThread(jvmtiEnv* env, jthread thread);
+  static jvmtiError ResumeThread(jvmtiEnv* env, jthread thread);
+
+  static jvmtiError SuspendThreadList(jvmtiEnv* env,
+                                      jint request_count,
+                                      const jthread* threads,
+                                      jvmtiError* results);
+  static jvmtiError ResumeThreadList(jvmtiEnv* env,
+                                     jint request_count,
+                                     const jthread* threads,
+                                     jvmtiError* results);
+
  private:
+  // We need to make sure only one thread tries to suspend threads at a time so we can get the
+  // 'suspend-only-once' behavior the spec requires. Internally, ART considers suspension to be a
+  // counted state, allowing a single thread to be suspended multiple times by different users. This
+  // makes mapping into the JVMTI idea of thread suspension difficult. We have decided to split the
+  // difference and ensure that JVMTI tries to treat suspension as the boolean flag as much as
+  // possible with the suspend/resume methods but only do best effort. On the other hand
+  // GetThreadState will be totally accurate as much as possible. This means that calling
+  // ResumeThread on a thread that has state JVMTI_THREAD_STATE_SUSPENDED will not necessarily
+  // cause the thread to wake up if the thread is suspended for the debugger or gc or something.
+  static jvmtiError SuspendSelf(art::Thread* self)
+      REQUIRES(!art::Locks::mutator_lock_, !art::Locks::user_code_suspension_lock_);
+  static jvmtiError SuspendOther(art::Thread* self, jthread target_jthread, art::Thread* target)
+      REQUIRES(!art::Locks::mutator_lock_, !art::Locks::user_code_suspension_lock_);
+
   static art::ArtField* context_class_loader_;
 };