1af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe/* 2af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Copyright (C) 2017 The Android Open Source Project 3af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 4af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License"); 5af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * you may not use this file except in compliance with the License. 6af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * You may obtain a copy of the License at 7af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 8af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * http://www.apache.org/licenses/LICENSE-2.0 9af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 10af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Unless required by applicable law or agreed to in writing, software 11af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS, 12af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * See the License for the specific language governing permissions and 14af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * limitations under the License. 15af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe */ 16af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 174665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampepackage art; 184665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe 19af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampeimport java.util.Arrays; 2072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampeimport java.util.ArrayList; 2172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampeimport java.util.Collections; 228580744607a963d408956c3eb712b0e070c139b0Andreas Gampeimport java.util.Comparator; 2372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampeimport java.util.concurrent.CountDownLatch; 24ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Lightimport java.util.function.Function; 2572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampeimport java.util.HashMap; 264471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampeimport java.util.Iterator; 2772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampeimport java.util.List; 2872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampeimport java.util.Map; 29447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampeimport java.util.Set; 30af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 314665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampepublic class Test924 { 324665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe public static void run() throws Exception { 33447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe // Run the test on its own thread, so we have a known state for the "current" thread. 34447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe Thread t = new Thread("TestThread") { 35447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe @Override 36447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe public void run() { 37447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe try { 38447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe doTest(); 39447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe } catch (Exception e) { 40447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe throw new RuntimeException(e); 41447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe } 42447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe } 43447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe }; 44447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe t.start(); 45447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe t.join(); 46af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 47af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 48af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe private static void doTest() throws Exception { 49af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe Thread t1 = Thread.currentThread(); 50af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe Thread t2 = getCurrentThread(); 51af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 52447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe // Need to adjust priority, as on-device this may be unexpected (and we prefer not 53447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe // to special-case this.) 54447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe t1.setPriority(5); 55447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe 56af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (t1 != t2) { 57af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe throw new RuntimeException("Expected " + t1 + " but got " + t2); 58af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 59af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe System.out.println("currentThread OK"); 60af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 61af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe printThreadInfo(t1); 62af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe printThreadInfo(null); 63af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 64af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe Thread t3 = new Thread("Daemon Thread"); 65af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe t3.setDaemon(true); 66af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Do not start this thread, yet. 67af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe printThreadInfo(t3); 68af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Start, and wait for it to die. 69af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe t3.start(); 70af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe t3.join(); 7172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.sleep(500); // Wait a little bit. 72af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Thread has died, check that we can still get info. 73af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe printThreadInfo(t3); 7472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 75db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe // Try a subclass of thread. 76db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe Thread t4 = new Thread("Subclass") { 77db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe }; 78db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe printThreadInfo(t4); 79db6c2ab29ef6ebe89c9ea43dae3b899a935fa74eAndreas Gampe 80ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light doCurrentThreadStateTests(); 81ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light doStateTests(Thread::new); 82ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light doStateTests(ExtThread::new); 838580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 848580744607a963d408956c3eb712b0e070c139b0Andreas Gampe doAllThreadsTests(); 857b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe 867b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe doTLSTests(); 87eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 88eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe doTestEvents(); 8972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 9072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 91ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light private static final class ExtThread extends Thread { 92ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light public ExtThread(Runnable r) { super(r); } 93ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light } 94ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light 9572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe private static class Holder { 9672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe volatile boolean flag = false; 9772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 9872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 99ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light private static void doCurrentThreadStateTests() throws Exception { 10072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe System.out.println(Integer.toHexString(getThreadState(null))); 10172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe System.out.println(Integer.toHexString(getThreadState(Thread.currentThread()))); 102ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light } 10372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 104ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light private static void doStateTests(Function<Runnable, Thread> mkThread) throws Exception { 10572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe final CountDownLatch cdl1 = new CountDownLatch(1); 10672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe final CountDownLatch cdl2 = new CountDownLatch(1); 10772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe final CountDownLatch cdl3_1 = new CountDownLatch(1); 10872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe final CountDownLatch cdl3_2 = new CountDownLatch(1); 10972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe final CountDownLatch cdl4 = new CountDownLatch(1); 11072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe final CountDownLatch cdl5 = new CountDownLatch(1); 11172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe final Holder h = new Holder(); 112597adad749499bc2da85851273e7623f6b249d1eAlex Light final NativeWaiter w = new NativeWaiter(); 11372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Runnable r = new Runnable() { 11472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe @Override 11572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe public void run() { 11672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe try { 11772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl1.countDown(); 11872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe synchronized(cdl1) { 11972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl1.wait(); 12072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 12172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 12272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl2.countDown(); 12372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe synchronized(cdl2) { 12472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl2.wait(1000); // Wait a second. 12572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 12672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 12772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl3_1.await(); 12872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl3_2.countDown(); 12972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe synchronized(cdl3_2) { 13072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Nothing, just wanted to block on cdl3. 13172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 13272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 13372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl4.countDown(); 13472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.sleep(1000); 13572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 13672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl5.countDown(); 13772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe while (!h.flag) { 13872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Busy-loop. 13972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 140597adad749499bc2da85851273e7623f6b249d1eAlex Light 141597adad749499bc2da85851273e7623f6b249d1eAlex Light nativeLoop(w.struct); 14272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } catch (Exception e) { 14372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe throw new RuntimeException(e); 14472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 14572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 14672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe }; 14772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 148ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light Thread t = mkThread.apply(r); 149ba461c3c5b588b0b65d3cc99aa12fe46a673962cAlex Light System.out.println("Thread type is " + t.getClass()); 15072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe printThreadState(t); 15172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe t.start(); 15272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 15372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Waiting. 15472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl1.await(); 15572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.yield(); 15672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.sleep(100); 15772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe printThreadState(t); 15872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe synchronized(cdl1) { 15972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl1.notifyAll(); 16072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 16172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 16272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Timed waiting. 16372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl2.await(); 16472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.yield(); 16572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.sleep(100); 16672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe printThreadState(t); 16772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe synchronized(cdl2) { 16872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl2.notifyAll(); 16972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 17072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 17172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Blocked on monitor. 17272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe synchronized(cdl3_2) { 17372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl3_1.countDown(); 17472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl3_2.await(); 175d59695c324f949115a609948a893ef8a9bdbca9fAndreas Gampe // While the latch improves the chances to make good progress, scheduling might still be 176d59695c324f949115a609948a893ef8a9bdbca9fAndreas Gampe // messy. Wait till we get the right Java-side Thread state. 177d59695c324f949115a609948a893ef8a9bdbca9fAndreas Gampe do { 178d59695c324f949115a609948a893ef8a9bdbca9fAndreas Gampe Thread.yield(); 179d59695c324f949115a609948a893ef8a9bdbca9fAndreas Gampe } while (t.getState() != Thread.State.BLOCKED); 180ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light // Since internal thread suspension (For GC or other cases) can happen at any time and changes 181ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light // the thread state we just have it print the majority thread state across 11 calls over 55 182ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light // milliseconds. 183ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light printMajorityThreadState(t, 11, 5); 18472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 18572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 18672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Sleeping. 18772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl4.await(); 18872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.yield(); 18972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.sleep(100); 19072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe printThreadState(t); 19172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 19272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Running. 19372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe cdl5.await(); 19472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.yield(); 19572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.sleep(100); 19672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe printThreadState(t); 19772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe h.flag = true; 19872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 199597adad749499bc2da85851273e7623f6b249d1eAlex Light // Native 200597adad749499bc2da85851273e7623f6b249d1eAlex Light w.waitForNative(); 201597adad749499bc2da85851273e7623f6b249d1eAlex Light printThreadState(t); 202597adad749499bc2da85851273e7623f6b249d1eAlex Light w.finish(); 203597adad749499bc2da85851273e7623f6b249d1eAlex Light 20472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Dying. 20572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe t.join(); 20672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.yield(); 20772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Thread.sleep(100); 20872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 20972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe printThreadState(t); 21072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 21172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 2128580744607a963d408956c3eb712b0e070c139b0Andreas Gampe private static void doAllThreadsTests() { 2138580744607a963d408956c3eb712b0e070c139b0Andreas Gampe Thread[] threads = getAllThreads(); 2144471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe List<Thread> threadList = new ArrayList<>(Arrays.asList(threads)); 2154471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe 2164471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe // Filter out JIT thread. It may or may not be there depending on configuration. 2174471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe Iterator<Thread> it = threadList.iterator(); 2184471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe while (it.hasNext()) { 2194471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe Thread t = it.next(); 2204471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe if (t.getName().startsWith("Jit thread pool worker")) { 2214471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe it.remove(); 2224471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe break; 2234471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe } 2244471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe } 2254471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe 2264471e4f7c5874bdaf93762b6047d4a4bebc465dfAndreas Gampe Collections.sort(threadList, THREAD_COMP); 227447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe 228447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe List<Thread> expectedList = new ArrayList<>(); 229447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe Set<Thread> threadsFromTraces = Thread.getAllStackTraces().keySet(); 230447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe 231447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe expectedList.add(findThreadByName(threadsFromTraces, "FinalizerDaemon")); 232447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe expectedList.add(findThreadByName(threadsFromTraces, "FinalizerWatchdogDaemon")); 233447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe expectedList.add(findThreadByName(threadsFromTraces, "HeapTaskDaemon")); 234447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe expectedList.add(findThreadByName(threadsFromTraces, "ReferenceQueueDaemon")); 235447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe // We can't get the signal catcher through getAllStackTraces. So ignore it. 236447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe // expectedList.add(findThreadByName(threadsFromTraces, "Signal Catcher")); 237447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe expectedList.add(findThreadByName(threadsFromTraces, "TestThread")); 238447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe expectedList.add(findThreadByName(threadsFromTraces, "main")); 239447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe 240447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe if (!threadList.containsAll(expectedList)) { 241447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe throw new RuntimeException("Expected " + expectedList + " as subset, got " + threadList); 242447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe } 243447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe System.out.println(expectedList); 244447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe } 245447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe 246447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe private static Thread findThreadByName(Set<Thread> threads, String name) { 247447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe for (Thread t : threads) { 248447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe if (t.getName().equals(name)) { 249447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe return t; 250447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe } 251447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe } 252447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe throw new RuntimeException("Did not find thread " + name + ": " + threads); 2538580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 2548580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 2557b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe private static void doTLSTests() throws Exception { 2567b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe doTLSNonLiveTests(); 2577b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe doTLSLiveTests(); 2587b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } 2597b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe 2607b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe private static void doTLSNonLiveTests() throws Exception { 2617b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe Thread t = new Thread(); 2627b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe try { 2637b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe setTLS(t, 1); 2647b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe System.out.println("Expected failure setting TLS for non-live thread"); 2657b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } catch (Exception e) { 2667b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe System.out.println(e.getMessage()); 2677b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } 2687b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe t.start(); 2697b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe t.join(); 2707b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe try { 2717b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe setTLS(t, 1); 2727b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe System.out.println("Expected failure setting TLS for non-live thread"); 2737b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } catch (Exception e) { 2747b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe System.out.println(e.getMessage()); 2757b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } 2767b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } 2777b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe 2787b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe private static void doTLSLiveTests() throws Exception { 2797b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe setTLS(Thread.currentThread(), 1); 2807b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe 2817b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe long l = getTLS(Thread.currentThread()); 2827b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe if (l != 1) { 2837b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe throw new RuntimeException("Unexpected TLS value: " + l); 2847b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe }; 2857b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe 2867b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe final CountDownLatch cdl1 = new CountDownLatch(1); 2877b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe final CountDownLatch cdl2 = new CountDownLatch(1); 2887b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe 2897b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe Runnable r = new Runnable() { 2907b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe @Override 2917b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe public void run() { 2927b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe try { 2937b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe cdl1.countDown(); 2947b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe cdl2.await(); 2957b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe setTLS(Thread.currentThread(), 2); 2967b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe if (getTLS(Thread.currentThread()) != 2) { 2977b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe throw new RuntimeException("Different thread issue"); 2987b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } 2997b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } catch (Exception e) { 3007b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe throw new RuntimeException(e); 3017b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } 3027b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } 3037b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe }; 3047b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe 3057b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe Thread t = new Thread(r); 3067b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe t.start(); 3077b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe cdl1.await(); 3087b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe setTLS(Thread.currentThread(), 1); 3097b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe cdl2.countDown(); 3107b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe 3117b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe t.join(); 3127b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe if (getTLS(Thread.currentThread()) != 1) { 3137b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe throw new RuntimeException("Got clobbered"); 3147b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } 3157b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe } 3167b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe 317eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe private static void doTestEvents() throws Exception { 318eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe enableThreadEvents(true); 319eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 320447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe final CountDownLatch cdl1 = new CountDownLatch(1); 321447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe final CountDownLatch cdl2 = new CountDownLatch(1); 322447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe 323447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe Runnable r = new Runnable() { 324447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe @Override 325447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe public void run() { 326447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe try { 327447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe cdl1.countDown(); 328447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe cdl2.await(); 329447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe } catch (Exception e) { 330447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe throw new RuntimeException(e); 331447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe } 332447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe } 333447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe }; 334447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe Thread t = new Thread(r, "EventTestThread"); 335eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 336eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe System.out.println("Constructed thread"); 337eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe Thread.yield(); 338447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe Thread.sleep(100); 339447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe System.out.println(Arrays.toString(getThreadEventMessages())); 340eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 341eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe t.start(); 342447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe cdl1.await(); 343447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe 344447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe System.out.println(Arrays.toString(getThreadEventMessages())); 345447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe 346447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe cdl2.countDown(); 347eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe t.join(); 348447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe System.out.println(Arrays.toString(getThreadEventMessages())); 349eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 350eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe System.out.println("Thread joined"); 351eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 352eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe enableThreadEvents(false); 353eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 354eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 3558580744607a963d408956c3eb712b0e070c139b0Andreas Gampe private final static Comparator<Thread> THREAD_COMP = new Comparator<Thread>() { 3568580744607a963d408956c3eb712b0e070c139b0Andreas Gampe public int compare(Thread o1, Thread o2) { 3578580744607a963d408956c3eb712b0e070c139b0Andreas Gampe return o1.getName().compareTo(o2.getName()); 3588580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 3598580744607a963d408956c3eb712b0e070c139b0Andreas Gampe }; 3608580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 36172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe private final static Map<Integer, String> STATE_NAMES = new HashMap<Integer, String>(); 36272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe private final static List<Integer> STATE_KEYS = new ArrayList<Integer>(); 36372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe static { 36472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x1, "ALIVE"); 36572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x2, "TERMINATED"); 36672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x4, "RUNNABLE"); 36772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x400, "BLOCKED_ON_MONITOR_ENTER"); 36872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x80, "WAITING"); 36972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x10, "WAITING_INDEFINITELY"); 37072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x20, "WAITING_WITH_TIMEOUT"); 37172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x40, "SLEEPING"); 37272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x100, "IN_OBJECT_WAIT"); 37372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x200, "PARKED"); 37472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x100000, "SUSPENDED"); 37572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x200000, "INTERRUPTED"); 37672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_NAMES.put(0x400000, "IN_NATIVE"); 37772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe STATE_KEYS.addAll(STATE_NAMES.keySet()); 37872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe Collections.sort(STATE_KEYS); 37972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 380ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light 381ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light // Call getThreadState 'votes' times waiting 'wait' millis between calls and print the most common 382ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light // result. 383ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light private static void printMajorityThreadState(Thread t, int votes, int wait) throws Exception { 384ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light Map<Integer, Integer> states = new HashMap<>(); 385ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light for (int i = 0; i < votes; i++) { 386ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light int cur_state = getThreadState(t); 387ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light states.put(cur_state, states.getOrDefault(cur_state, 0) + 1); 388ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light Thread.sleep(wait); // Wait a little bit. 389ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light } 390ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light int best_state = -1; 391ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light int highest_count = 0; 392ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light for (Map.Entry<Integer, Integer> e : states.entrySet()) { 393ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light if (e.getValue() > highest_count) { 394ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light highest_count = e.getValue(); 395ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light best_state = e.getKey(); 396ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light } 397ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light } 398ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light printThreadState(best_state); 399ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light } 400ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light 40172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe private static void printThreadState(Thread t) { 402ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light printThreadState(getThreadState(t)); 403ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light } 40472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 405ed3a357e6b28dbc00a60b72af8bb846775348172Alex Light private static void printThreadState(int state) { 40672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe StringBuilder sb = new StringBuilder(); 40772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 40872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe for (Integer i : STATE_KEYS) { 40972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if ((state & i) != 0) { 41072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (sb.length()>0) { 41172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe sb.append('|'); 41272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 41372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe sb.append(STATE_NAMES.get(i)); 41472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 41572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 41672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 41772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (sb.length() == 0) { 41872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe sb.append("NEW"); 41972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 42072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 42172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe System.out.println(Integer.toHexString(state) + " = " + sb.toString()); 422af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 423af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 424af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe private static void printThreadInfo(Thread t) { 425af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe Object[] threadInfo = getThreadInfo(t); 426af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (threadInfo == null || threadInfo.length != 5) { 427af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe System.out.println(Arrays.toString(threadInfo)); 428af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe throw new RuntimeException("threadInfo length wrong"); 429af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 430af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 431af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe System.out.println(threadInfo[0]); // Name 432af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe System.out.println(threadInfo[1]); // Priority 433af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe System.out.println(threadInfo[2]); // Daemon 434af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe System.out.println(threadInfo[3]); // Threadgroup 435af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe System.out.println(threadInfo[4] == null ? "null" : threadInfo[4].getClass()); // Context CL. 436af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 437af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 438597adad749499bc2da85851273e7623f6b249d1eAlex Light public static final class NativeWaiter { 439597adad749499bc2da85851273e7623f6b249d1eAlex Light public long struct; 440597adad749499bc2da85851273e7623f6b249d1eAlex Light public NativeWaiter() { 441597adad749499bc2da85851273e7623f6b249d1eAlex Light struct = nativeWaiterStructAlloc(); 442597adad749499bc2da85851273e7623f6b249d1eAlex Light } 443597adad749499bc2da85851273e7623f6b249d1eAlex Light public void waitForNative() { 444597adad749499bc2da85851273e7623f6b249d1eAlex Light if (struct == 0l) { 445597adad749499bc2da85851273e7623f6b249d1eAlex Light throw new Error("Already resumed from native!"); 446597adad749499bc2da85851273e7623f6b249d1eAlex Light } 447597adad749499bc2da85851273e7623f6b249d1eAlex Light nativeWaiterStructWaitForNative(struct); 448597adad749499bc2da85851273e7623f6b249d1eAlex Light } 449597adad749499bc2da85851273e7623f6b249d1eAlex Light public void finish() { 450597adad749499bc2da85851273e7623f6b249d1eAlex Light if (struct == 0l) { 451597adad749499bc2da85851273e7623f6b249d1eAlex Light throw new Error("Already resumed from native!"); 452597adad749499bc2da85851273e7623f6b249d1eAlex Light } 453597adad749499bc2da85851273e7623f6b249d1eAlex Light nativeWaiterStructFinish(struct); 454597adad749499bc2da85851273e7623f6b249d1eAlex Light struct = 0; 455597adad749499bc2da85851273e7623f6b249d1eAlex Light } 456597adad749499bc2da85851273e7623f6b249d1eAlex Light } 457597adad749499bc2da85851273e7623f6b249d1eAlex Light 458597adad749499bc2da85851273e7623f6b249d1eAlex Light private static native long nativeWaiterStructAlloc(); 459597adad749499bc2da85851273e7623f6b249d1eAlex Light private static native void nativeWaiterStructWaitForNative(long struct); 460597adad749499bc2da85851273e7623f6b249d1eAlex Light private static native void nativeWaiterStructFinish(long struct); 461597adad749499bc2da85851273e7623f6b249d1eAlex Light private static native void nativeLoop(long w); 462597adad749499bc2da85851273e7623f6b249d1eAlex Light 463af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe private static native Thread getCurrentThread(); 464af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe private static native Object[] getThreadInfo(Thread t); 46572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe private static native int getThreadState(Thread t); 4668580744607a963d408956c3eb712b0e070c139b0Andreas Gampe private static native Thread[] getAllThreads(); 4677b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe private static native void setTLS(Thread t, long l); 4687b3b326158676a89bc27639b829a3e1746f8c988Andreas Gampe private static native long getTLS(Thread t); 469eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe private static native void enableThreadEvents(boolean b); 470447c1af5187ea23b8bd045a84fd332dd6a284fe0Andreas Gampe private static native String[] getThreadEventMessages(); 471af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe} 472