blob: 6ba01ff0b50d8c468f57dfa6822deeb4f405bebf [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];
Mathieu Chartier4201cf02017-01-12 14:51:44 -080026 test_getStackTraces();
Mathieu Chartier905f5912014-12-12 13:05:33 -080027 for (int t = 0; t < threads.length; t++) {
28 threads[t] = new Thread(new Main());
29 threads[t].start();
30 }
31 for (Thread t : threads) {
32 t.join();
33 }
34 System.out.println("Finishing");
35 }
36
Nicolas Geoffray91011af2017-01-13 11:29:41 +000037 static Thread getHeapTaskDaemon() throws Exception {
38 Field f = ThreadGroup.class.getDeclaredField("systemThreadGroup");
39 f.setAccessible(true);
40 ThreadGroup systemThreadGroup = (ThreadGroup) f.get(null);
41
42 while (true) {
43 int activeCount = systemThreadGroup.activeCount();
44 Thread[] array = new Thread[activeCount];
45 systemThreadGroup.enumerate(array);
46 for (Thread thread : array) {
47 if (thread.getName().equals("HeapTaskDaemon") &&
48 thread.getState() != Thread.State.NEW) {
49 return thread;
50 }
51 }
52 // Yield to eventually get the daemon started.
53 Thread.sleep(10);
54 }
55 }
56
57 static void test_getStackTraces() throws Exception {
58 Thread heapDaemon = getHeapTaskDaemon();
59
60 // Force a GC to ensure the daemon truly started.
61 Runtime.getRuntime().gc();
Mathieu Chartier4201cf02017-01-12 14:51:44 -080062 // Check all the current threads for positive IDs.
63 Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
64 for (Map.Entry<Thread, StackTraceElement[]> pair : map.entrySet()) {
65 Thread thread = pair.getKey();
66 // Expect empty stack trace since we do not support suspending the GC thread for
67 // obtaining stack traces. See b/28261069.
Nicolas Geoffray91011af2017-01-13 11:29:41 +000068 if (thread == heapDaemon) {
Mathieu Chartier4201cf02017-01-12 14:51:44 -080069 System.out.println(thread.getName() + " depth " + pair.getValue().length);
70 }
71 }
72 }
73
Mathieu Chartier905f5912014-12-12 13:05:33 -080074 public void test_getId() {
75 if (Thread.currentThread().getId() <= 0) {
76 System.out.println("current thread's ID is not positive");
77 }
78 // Check all the current threads for positive IDs.
79 Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces();
80 for (Thread thread : stMap.keySet()) {
81 if (thread.getId() <= 0) {
82 System.out.println("thread's ID is not positive: " + thread.getName());
83 }
84 }
85 }
86
87 public void run() {
88 for (int i = 0; i < totalOperations; ++i) {
89 test_getId();
90 }
91 }
92}