OSDN Git Service

ART: Call ThreadGroup.add in Thread::FinishStartup
authorAndreas Gampe <agampe@google.com>
Tue, 18 Apr 2017 03:19:14 +0000 (20:19 -0700)
committerAndreas Gampe <agampe@google.com>
Tue, 18 Apr 2017 04:16:29 +0000 (21:16 -0700)
ART should add the main thread to the main ThreadGroup. Behavior
of the Thread constructor changed.

Bug: 37444210
Test: art/test/testrunner/testrunner.py -b --host -t 051
Test: m test-art-host
Test: m build-art-host && art/tools/run-libcore-tests.sh --mode=host
Change-Id: I92cf2f9a6c5c3fdf385eb7925addc38b64fa4d98

runtime/thread.cc
test/051-thread/expected.txt
test/051-thread/src/Main.java

index 008c388..abe65c1 100644 (file)
@@ -1928,6 +1928,23 @@ void Thread::FinishStartup() {
   Thread::Current()->AssertNoPendingException();
 
   Runtime::Current()->GetClassLinker()->RunRootClinits();
+
+  // The thread counts as started from now on. We need to add it to the ThreadGroup. For regular
+  // threads, this is done in Thread.start() on the Java side.
+  {
+    // This is only ever done once. There's no benefit in caching the method.
+    jmethodID thread_group_add = soa.Env()->GetMethodID(WellKnownClasses::java_lang_ThreadGroup,
+                                                        "add",
+                                                        "(Ljava/lang/Thread;)V");
+    CHECK(thread_group_add != nullptr);
+    ScopedLocalRef<jobject> thread_jobject(
+        soa.Env(), soa.Env()->AddLocalReference<jobject>(Thread::Current()->GetPeer()));
+    soa.Env()->CallNonvirtualVoidMethod(runtime->GetMainThreadGroup(),
+                                        WellKnownClasses::java_lang_ThreadGroup,
+                                        thread_group_add,
+                                        thread_jobject.get());
+    Thread::Current()->AssertNoPendingException();
+  }
 }
 
 void Thread::Shutdown() {
index 3fc3492..c8af963 100644 (file)
@@ -12,4 +12,6 @@ testSetName running
 testSetName finished
 testThreadPriorities starting
 testThreadPriorities finished
+Found current Thread in ThreadGroup
+Found expected stack in getAllStackTraces()
 thread test done
index 82fc0d4..08cb5de 100644 (file)
@@ -15,6 +15,9 @@
  */
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
 
 /**
  * Test some basic thread stuff.
@@ -28,6 +31,8 @@ public class Main {
         testSleepZero();
         testSetName();
         testThreadPriorities();
+        testMainThreadGroup();
+        testMainThreadAllStackTraces();
         System.out.println("thread test done");
     }
 
@@ -159,6 +164,49 @@ public class Main {
         System.out.print("testThreadPriorities finished\n");
     }
 
+    private static void testMainThreadGroup() {
+      Thread threads[] = new Thread[10];
+      Thread current = Thread.currentThread();
+      current.getThreadGroup().enumerate(threads);
+
+      for (Thread t : threads) {
+        if (t == current) {
+          System.out.println("Found current Thread in ThreadGroup");
+          return;
+        }
+      }
+      throw new RuntimeException("Did not find main thread: " + Arrays.toString(threads));
+    }
+
+    private static void testMainThreadAllStackTraces() {
+      StackTraceElement[] trace = Thread.getAllStackTraces().get(Thread.currentThread());
+      if (trace == null) {
+        throw new RuntimeException("Did not find main thread: " + Thread.getAllStackTraces());
+      }
+      List<StackTraceElement> list = Arrays.asList(trace);
+      Iterator<StackTraceElement> it = list.iterator();
+      while (it.hasNext()) {
+        StackTraceElement ste = it.next();
+        if (ste.getClassName().equals("Main")) {
+          if (!ste.getMethodName().equals("testMainThreadAllStackTraces")) {
+            throw new RuntimeException(list.toString());
+          }
+
+          StackTraceElement ste2 = it.next();
+          if (!ste2.getClassName().equals("Main")) {
+            throw new RuntimeException(list.toString());
+          }
+          if (!ste2.getMethodName().equals("main")) {
+            throw new RuntimeException(list.toString());
+          }
+
+          System.out.println("Found expected stack in getAllStackTraces()");
+          return;
+        }
+      }
+      throw new RuntimeException(list.toString());
+    }
+
     private static native int getNativePriority();
     private static native boolean supportsThreadPriorities();