Add thread suspend stress

Seems to be passing, aim to catch bugs related to thread suspension.

Bug: 28988206

Change-Id: I48190900ccd7a2545c6f09cf730e995043b0d9b7
diff --git a/test/149-suspend-all-stress/expected.txt b/test/149-suspend-all-stress/expected.txt
new file mode 100644
index 0000000..f993efc
--- /dev/null
+++ b/test/149-suspend-all-stress/expected.txt
@@ -0,0 +1,2 @@
+JNI_OnLoad called
+Finishing
diff --git a/test/149-suspend-all-stress/info.txt b/test/149-suspend-all-stress/info.txt
new file mode 100644
index 0000000..29b414c
--- /dev/null
+++ b/test/149-suspend-all-stress/info.txt
@@ -0,0 +1 @@
+Stress test for multiple threads calling SuspendAll
diff --git a/test/149-suspend-all-stress/src/Main.java b/test/149-suspend-all-stress/src/Main.java
new file mode 100644
index 0000000..6a27c4b
--- /dev/null
+++ b/test/149-suspend-all-stress/src/Main.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+import java.util.Map;
+
+public class Main implements Runnable {
+    static final int numberOfThreads = 8;
+
+    public static void main(String[] args) throws Exception {
+        System.loadLibrary(args[0]);
+        final Thread[] threads = new Thread[numberOfThreads];
+        for (int t = 0; t < threads.length; t++) {
+            threads[t] = new Thread(new Main());
+            threads[t].start();
+        }
+        for (Thread t : threads) {
+            t.join();
+        }
+        System.out.println("Finishing");
+    }
+
+    public void run() {
+        suspendAndResume();
+    }
+
+    private static native void suspendAndResume();
+}
diff --git a/test/149-suspend-all-stress/suspend_all.cc b/test/149-suspend-all-stress/suspend_all.cc
new file mode 100644
index 0000000..c22ddad
--- /dev/null
+++ b/test/149-suspend-all-stress/suspend_all.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "jni.h"
+#include "runtime.h"
+#include "thread_list.h"
+
+namespace art {
+
+extern "C" JNIEXPORT void JNICALL Java_Main_suspendAndResume(JNIEnv*, jclass) {
+  usleep(100 * 1000);  // Leave some time for threads to get in here before we start suspending.
+  for (size_t i = 0; i < 500; ++i) {
+    Runtime::Current()->GetThreadList()->SuspendAll(__FUNCTION__);
+    usleep(500);
+    Runtime::Current()->GetThreadList()->ResumeAll();
+  }
+}
+
+}  // namespace art
diff --git a/test/Android.libarttest.mk b/test/Android.libarttest.mk
index 2e6359b..feee7c2 100644
--- a/test/Android.libarttest.mk
+++ b/test/Android.libarttest.mk
@@ -35,6 +35,7 @@
   139-register-natives/regnative.cc \
   141-class-unload/jni_unload.cc \
   148-multithread-gc-annotations/gc_coverage.cc \
+  149-suspend-all-stress/suspend_all.cc \
   454-get-vreg/get_vreg_jni.cc \
   457-regs/regs_jni.cc \
   461-get-reference-vreg/get_reference_vreg_jni.cc \