1 /* 2 * Copyright (C) 2006 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.util.ArrayList; 18 import java.util.Arrays; 19 import java.util.Iterator; 20 import java.util.List; 21 22 /** 23 * Test some basic thread stuff. 24 */ 25 public class Main { main(String[] args)26 public static void main(String[] args) throws Exception { 27 System.loadLibrary(args[0]); 28 System.out.println("thread test starting"); 29 testThreadCapacity(); 30 testThreadDaemons(); 31 testSleepZero(); 32 testSetName(); 33 testThreadPriorities(); 34 testMainThreadGroup(); 35 testMainThreadAllStackTraces(); 36 System.out.println("thread test done"); 37 } 38 39 /* 40 * Simple thread capacity test. 41 */ testThreadCapacity()42 private static void testThreadCapacity() throws Exception { 43 TestCapacityThread[] threads = new TestCapacityThread[128]; 44 for (int i = 0; i < threads.length; i++) { 45 threads[i] = new TestCapacityThread(); 46 } 47 48 for (TestCapacityThread thread : threads) { 49 thread.start(); 50 } 51 for (TestCapacityThread thread : threads) { 52 thread.join(); 53 } 54 55 System.out.println("testThreadCapacity thread count: " + TestCapacityThread.mCount); 56 } 57 58 private static class TestCapacityThread extends Thread { 59 static int mCount = 0; run()60 public void run() { 61 synchronized (TestCapacityThread.class) { 62 ++mCount; 63 } 64 try { 65 sleep(1000); 66 } catch (Exception ex) { 67 } 68 } 69 } 70 testThreadDaemons()71 private static void testThreadDaemons() { 72 Thread t = new Thread(null, new TestDaemonThread(), "TestDaemonThread", 7168); 73 74 t.setDaemon(false); 75 76 System.out.print("testThreadDaemons starting thread '" + t.getName() + "'\n"); 77 t.start(); 78 79 try { 80 t.join(); 81 } catch (InterruptedException ex) { 82 ex.printStackTrace(System.out); 83 } 84 85 System.out.print("testThreadDaemons finished\n"); 86 } 87 88 private static class TestDaemonThread implements Runnable { run()89 public void run() { 90 System.out.print("testThreadDaemons @ Thread running\n"); 91 92 try { 93 Thread.currentThread().setDaemon(true); 94 System.out.print("testThreadDaemons @ FAILED: setDaemon() succeeded\n"); 95 } catch (IllegalThreadStateException itse) { 96 System.out.print("testThreadDaemons @ Got expected setDaemon exception\n"); 97 } 98 99 try { 100 Thread.sleep(2000); 101 } 102 catch (InterruptedException ie) { 103 System.out.print("testThreadDaemons @ Interrupted!\n"); 104 } 105 finally { 106 System.out.print("testThreadDaemons @ Thread bailing\n"); 107 } 108 } 109 } 110 testSleepZero()111 private static void testSleepZero() throws Exception { 112 Thread.currentThread().interrupt(); 113 try { 114 Thread.sleep(0); 115 throw new AssertionError("unreachable"); 116 } catch (InterruptedException e) { 117 if (Thread.currentThread().isInterrupted()) { 118 throw new AssertionError("thread is interrupted"); 119 } 120 } 121 System.out.print("testSleepZero finished\n"); 122 } 123 testSetName()124 private static void testSetName() throws Exception { 125 System.out.print("testSetName starting\n"); 126 Thread thread = new Thread() { 127 @Override 128 public void run() { 129 System.out.print("testSetName running\n"); 130 } 131 }; 132 thread.start(); 133 thread.setName("HelloWorld"); // b/17302037 hang if setName called after start 134 if (!thread.getName().equals("HelloWorld")) { 135 throw new AssertionError("Unexpected thread name: " + thread.getName()); 136 } 137 thread.join(); 138 if (!thread.getName().equals("HelloWorld")) { 139 throw new AssertionError("Unexpected thread name after join: " + thread.getName()); 140 } 141 System.out.print("testSetName finished\n"); 142 } 143 testThreadPriorities()144 private static void testThreadPriorities() throws Exception { 145 System.out.print("testThreadPriorities starting\n"); 146 147 PriorityStoringThread t1 = new PriorityStoringThread(false); 148 t1.setPriority(Thread.MAX_PRIORITY); 149 t1.start(); 150 t1.join(); 151 if (supportsThreadPriorities() && (t1.getNativePriority() != Thread.MAX_PRIORITY)) { 152 System.out.print("thread priority for t1 was " + t1.getNativePriority() + 153 " [expected Thread.MAX_PRIORITY]\n"); 154 } 155 156 PriorityStoringThread t2 = new PriorityStoringThread(true); 157 t2.start(); 158 t2.join(); 159 if (supportsThreadPriorities() && (t2.getNativePriority() != Thread.MAX_PRIORITY)) { 160 System.out.print("thread priority for t2 was " + t2.getNativePriority() + 161 " [expected Thread.MAX_PRIORITY]\n"); 162 } 163 164 System.out.print("testThreadPriorities finished\n"); 165 } 166 testMainThreadGroup()167 private static void testMainThreadGroup() { 168 Thread threads[] = new Thread[10]; 169 Thread current = Thread.currentThread(); 170 current.getThreadGroup().enumerate(threads); 171 172 for (Thread t : threads) { 173 if (t == current) { 174 System.out.println("Found current Thread in ThreadGroup"); 175 return; 176 } 177 } 178 throw new RuntimeException("Did not find main thread: " + Arrays.toString(threads)); 179 } 180 testMainThreadAllStackTraces()181 private static void testMainThreadAllStackTraces() { 182 StackTraceElement[] trace = Thread.getAllStackTraces().get(Thread.currentThread()); 183 if (trace == null) { 184 throw new RuntimeException("Did not find main thread: " + Thread.getAllStackTraces()); 185 } 186 List<StackTraceElement> list = Arrays.asList(trace); 187 Iterator<StackTraceElement> it = list.iterator(); 188 while (it.hasNext()) { 189 StackTraceElement ste = it.next(); 190 if (ste.getClassName().equals("Main")) { 191 if (!ste.getMethodName().equals("testMainThreadAllStackTraces")) { 192 throw new RuntimeException(list.toString()); 193 } 194 195 StackTraceElement ste2 = it.next(); 196 if (!ste2.getClassName().equals("Main")) { 197 throw new RuntimeException(list.toString()); 198 } 199 if (!ste2.getMethodName().equals("main")) { 200 throw new RuntimeException(list.toString()); 201 } 202 203 System.out.println("Found expected stack in getAllStackTraces()"); 204 return; 205 } 206 } 207 throw new RuntimeException(list.toString()); 208 } 209 getNativePriority()210 private static native int getNativePriority(); supportsThreadPriorities()211 private static native boolean supportsThreadPriorities(); 212 213 static class PriorityStoringThread extends Thread { 214 private final boolean setPriority; 215 private volatile int nativePriority; 216 PriorityStoringThread(boolean setPriority)217 public PriorityStoringThread(boolean setPriority) { 218 this.setPriority = setPriority; 219 this.nativePriority = -1; 220 } 221 222 @Override run()223 public void run() { 224 if (setPriority) { 225 setPriority(Thread.MAX_PRIORITY); 226 } 227 228 nativePriority = Main.getNativePriority(); 229 } 230 getNativePriority()231 public int getNativePriority() { 232 return nativePriority; 233 } 234 } 235 } 236