Home | History | Annotate | Download | only in src
      1 /*
      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 
     17 import java.lang.reflect.Field;
     18 import java.util.Map;
     19 
     20 public 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         }
     33         // Do this test after the other part to leave some time for the heap task daemon to start
     34         // up.
     35         test_getStackTraces();
     36         System.out.println("Finishing");
     37     }
     38 
     39     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();
     64         // 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.
     70             if (thread == heapDaemon) {
     71                 System.out.println(thread.getName() + " depth " + pair.getValue().length);
     72             }
     73         }
     74     }
     75 
     76     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 }
     95