Home | History | Annotate | Download | only in src
      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 {
     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      */
     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;
     60         public void run() {
     61             synchronized (TestCapacityThread.class) {
     62                 ++mCount;
     63             }
     64             try {
     65                 sleep(1000);
     66             } catch (Exception ex) {
     67             }
     68         }
     69     }
     70 
     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 {
     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 
    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 
    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 
    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 
    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 
    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 
    210     private static native int getNativePriority();
    211     private static native boolean supportsThreadPriorities();
    212 
    213     static class PriorityStoringThread extends Thread {
    214         private final boolean setPriority;
    215         private volatile int nativePriority;
    216 
    217         public PriorityStoringThread(boolean setPriority) {
    218             this.setPriority = setPriority;
    219             this.nativePriority = -1;
    220         }
    221 
    222         @Override
    223         public void run() {
    224             if (setPriority) {
    225                 setPriority(Thread.MAX_PRIORITY);
    226             }
    227 
    228             nativePriority = Main.getNativePriority();
    229         }
    230 
    231         public int getNativePriority() {
    232             return nativePriority;
    233         }
    234     }
    235 }
    236