blob: c59efe2f7bc1b8de20a4e912f22e9fe3ecc2388f [file] [log] [blame]
Andreas Gamped18d9e22017-01-16 16:08:45 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import java.util.Arrays;
18import java.util.Comparator;
19
20public class Main {
21 public static void main(String[] args) throws Exception {
22 System.loadLibrary(args[1]);
23
24 doTest();
25 }
26
27 private static void doTest() throws Exception {
28 Thread t1 = Thread.currentThread();
29 ThreadGroup curGroup = t1.getThreadGroup();
30
31 ThreadGroup rootGroup = curGroup;
32 while (rootGroup.getParent() != null) {
33 rootGroup = rootGroup.getParent();
34 }
35
36 ThreadGroup topGroups[] = getTopThreadGroups();
37 if (topGroups == null || topGroups.length != 1 || topGroups[0] != rootGroup) {
38 System.out.println(Arrays.toString(topGroups));
39 throw new RuntimeException("Unexpected topGroups");
40 }
41
42 printThreadGroupInfo(curGroup);
43 printThreadGroupInfo(rootGroup);
44
45 waitGroupChildren(rootGroup, 5 /* # daemons */, 30 /* timeout in seconds */);
46
47 checkChildren(curGroup);
48 }
49
50 private static void printThreadGroupInfo(ThreadGroup tg) {
51 Object[] threadGroupInfo = getThreadGroupInfo(tg);
52 if (threadGroupInfo == null || threadGroupInfo.length != 4) {
53 System.out.println(Arrays.toString(threadGroupInfo));
54 throw new RuntimeException("threadGroupInfo length wrong");
55 }
56
57 System.out.println(tg);
58 System.out.println(" " + threadGroupInfo[0]); // Parent
59 System.out.println(" " + threadGroupInfo[1]); // Name
60 System.out.println(" " + threadGroupInfo[2]); // Priority
61 System.out.println(" " + threadGroupInfo[3]); // Daemon
62 }
63
64 private static void checkChildren(ThreadGroup tg) {
65 Object[] data = getThreadGroupChildren(tg);
66 Thread[] threads = (Thread[])data[0];
67 ThreadGroup[] groups = (ThreadGroup[])data[1];
68
69 Arrays.sort(threads, THREAD_COMP);
70 Arrays.sort(groups, THREADGROUP_COMP);
71 System.out.println(tg.getName() + ":");
72 System.out.println(" " + Arrays.toString(threads));
73 System.out.println(" " + Arrays.toString(groups));
74
75 if (tg.getParent() != null) {
76 checkChildren(tg.getParent());
77 }
78 }
79
80 private static void waitGroupChildren(ThreadGroup tg, int expectedChildCount, int timeoutS)
81 throws Exception {
82 for (int i = 0; i < timeoutS; i++) {
83 Object[] data = getThreadGroupChildren(tg);
84 Thread[] threads = (Thread[])data[0];
85 if (threads.length == expectedChildCount) {
86 return;
87 }
88 Thread.sleep(1000);
89 }
90
91 Object[] data = getThreadGroupChildren(tg);
92 Thread[] threads = (Thread[])data[0];
93 System.out.println(Arrays.toString(threads));
94 throw new RuntimeException("Waited unsuccessfully for " + expectedChildCount + " children.");
95 }
96
97 private final static Comparator<Thread> THREAD_COMP = new Comparator<Thread>() {
98 public int compare(Thread o1, Thread o2) {
99 return o1.getName().compareTo(o2.getName());
100 }
101 };
102
103 private final static Comparator<ThreadGroup> THREADGROUP_COMP = new Comparator<ThreadGroup>() {
104 public int compare(ThreadGroup o1, ThreadGroup o2) {
105 return o1.getName().compareTo(o2.getName());
106 }
107 };
108
109 private static native ThreadGroup[] getTopThreadGroups();
110 private static native Object[] getThreadGroupInfo(ThreadGroup tg);
111 // Returns an array where element 0 is an array of threads and element 1 is an array of groups.
112 private static native Object[] getThreadGroupChildren(ThreadGroup tg);
113}