blob: 4e48e0e1a672d1053ee7531af6303200dadef489 [file] [log] [blame]
Mathieu Chartier905f5912014-12-12 13:05:33 -08001/*
2 * Copyright (C) 2014 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
Nicolas Geoffray91011af2017-01-13 11:29:41 +000017import java.lang.reflect.Field;
Mathieu Chartier905f5912014-12-12 13:05:33 -080018import java.util.Map;
19
20public class Main implements Runnable {
21 static final int numberOfThreads = 5;
22 static final int totalOperations = 1000;
23
24 public static void main(String[] args) throws Exception {
25 final Thread[] threads = new Thread[numberOfThreads];
26 for (int t = 0; t < threads.length; t++) {
27 threads[t] = new Thread(new Main());
28 threads[t].start();
29 }
30 for (Thread t : threads) {
31 t.join();
32 }
Mathieu Chartier160ab8e2017-01-17 11:05:20 -080033 // Do this test after the other part to leave some time for the heap task daemon to start
34 // up.
35 test_getStackTraces();
Mathieu Chartier905f5912014-12-12 13:05:33 -080036 System.out.println("Finishing");
37 }
38
Nicolas Geoffray91011af2017-01-13 11:29:41 +000039 static Thread getHeapTaskDaemon() throws Exception {
40 Field f = ThreadGroup.class.getDeclaredField("systemThreadGroup");
41 f.setAccessible(true);
42 ThreadGroup systemThreadGroup = (ThreadGroup) f.get(null);
43
44 while (true) {
45 int activeCount = systemThreadGroup.activeCount();
46 Thread[] array = new Thread[activeCount];
47 systemThreadGroup.enumerate(array);
48 for (Thread thread : array) {
49 if (thread.getName().equals("HeapTaskDaemon") &&
50 thread.getState() != Thread.State.NEW) {
51 return thread;
52 }
53 }
54 // Yield to eventually get the daemon started.
55 Thread.sleep(10);
56 }
57 }
58
59 static void test_getStackTraces() throws Exception {
60 Thread heapDaemon = getHeapTaskDaemon();
61
62 // Force a GC to ensure the daemon truly started.
63 Runtime.getRuntime().gc();
Mathieu Chartier4201cf02017-01-12 14:51:44 -080064 // Check all the current threads for positive IDs.
65 Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
66 for (Map.Entry<Thread, StackTraceElement[]> pair : map.entrySet()) {
67 Thread thread = pair.getKey();
68 // Expect empty stack trace since we do not support suspending the GC thread for
69 // obtaining stack traces. See b/28261069.
Nicolas Geoffray91011af2017-01-13 11:29:41 +000070 if (thread == heapDaemon) {
Mathieu Chartier4201cf02017-01-12 14:51:44 -080071 System.out.println(thread.getName() + " depth " + pair.getValue().length);
72 }
73 }
74 }
75
Mathieu Chartier905f5912014-12-12 13:05:33 -080076 public void test_getId() {
77 if (Thread.currentThread().getId() <= 0) {
78 System.out.println("current thread's ID is not positive");
79 }
80 // Check all the current threads for positive IDs.
81 Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces();
82 for (Thread thread : stMap.keySet()) {
83 if (thread.getId() <= 0) {
84 System.out.println("thread's ID is not positive: " + thread.getName());
85 }
86 }
87 }
88
89 public void run() {
90 for (int i = 0; i < totalOperations; ++i) {
91 test_getId();
92 }
93 }
94}