content: /*
   * Copyright (C) 2006 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  import java.util.ArrayList;
  
  /**
   * Test some basic thread stuff.
   */
  public class Main {
      public static void main(String[] args) throws Exception {
          System.loadLibrary(args[0]);
          System.out.println("thread test starting");
          testThreadCapacity();
          testThreadDaemons();
          testSleepZero();
          testSetName();
          testThreadPriorities();
          System.out.println("thread test done");
      }
  
      /*
       * Simple thread capacity test.
       */
      private static void testThreadCapacity() throws Exception {
          TestCapacityThread[] threads = new TestCapacityThread[512];
          for (int i = 0; i < 512; i++) {
              threads[i] = new TestCapacityThread();
          }
  
          for (TestCapacityThread thread : threads) {
              thread.start();
          }
          for (TestCapacityThread thread : threads) {
              thread.join();
          }
  
          System.out.println("testThreadCapacity thread count: " + TestCapacityThread.mCount);
      }
  
      private static class TestCapacityThread extends Thread {
          static int mCount = 0;
          public void run() {
              synchronized (TestCapacityThread.class) {
                  ++mCount;
              }
              try {
                  sleep(1000);
              } catch (Exception ex) {
              }
          }
      }
  
      private static void testThreadDaemons() {
          Thread t = new Thread(null, new TestDaemonThread(), "TestDaemonThread", 7168);
  
          t.setDaemon(false);
  
          System.out.print("testThreadDaemons starting thread '" + t.getName() + "'\n");
          t.start();
  
          try {
              t.join();
          } catch (InterruptedException ex) {
              ex.printStackTrace();
          }
  
          System.out.print("testThreadDaemons finished\n");
      }
  
      private static class TestDaemonThread implements Runnable {
          public void run() {
              System.out.print("testThreadDaemons @ Thread running\n");
  
              try {
                  Thread.currentThread().setDaemon(true);
                  System.out.print("testThreadDaemons @ FAILED: setDaemon() succeeded\n");
              } catch (IllegalThreadStateException itse) {
                  System.out.print("testThreadDaemons @ Got expected setDaemon exception\n");
              }
  
              try {
                  Thread.sleep(2000);
              }
              catch (InterruptedException ie) {
                  System.out.print("testThreadDaemons @ Interrupted!\n");
              }
              finally {
                  System.out.print("testThreadDaemons @ Thread bailing\n");
              }
          }
      }
  
      private static void testSleepZero() throws Exception {
          Thread.currentThread().interrupt();
          try {
              Thread.sleep(0);
              throw new AssertionError("unreachable");
          } catch (InterruptedException e) {
              if (Thread.currentThread().isInterrupted()) {
                  throw new AssertionError("thread is interrupted");
              }
          }
          System.out.print("testSleepZero finished\n");
      }
  
      private static void testSetName() throws Exception {
          System.out.print("testSetName starting\n");
          Thread thread = new Thread() {
              @Override
              public void run() {
                  System.out.print("testSetName running\n");
              }
          };
          thread.start();
          thread.setName("HelloWorld");  // b/17302037 hang if setName called after start
          if (!thread.getName().equals("HelloWorld")) {
              throw new AssertionError("Unexpected thread name: " + thread.getName());
          }
          thread.join();
          if (!thread.getName().equals("HelloWorld")) {
              throw new AssertionError("Unexpected thread name after join: " + thread.getName());
          }
          System.out.print("testSetName finished\n");
      }
  
      private static void testThreadPriorities() throws Exception {
          System.out.print("testThreadPriorities starting\n");
  
          PriorityStoringThread t1 = new PriorityStoringThread(false);
          t1.setPriority(Thread.MAX_PRIORITY);
          t1.start();
          t1.join();
          if (supportsThreadPriorities() && (t1.getNativePriority() != Thread.MAX_PRIORITY)) {
              System.out.print("thread priority for t1 was " + t1.getNativePriority() +
                  " [expected Thread.MAX_PRIORITY]\n");
          }
  
          PriorityStoringThread t2 = new PriorityStoringThread(true);
          t2.start();
          t2.join();
          if (supportsThreadPriorities() && (t2.getNativePriority() != Thread.MAX_PRIORITY)) {
              System.out.print("thread priority for t2 was " + t2.getNativePriority() +
                  " [expected Thread.MAX_PRIORITY]\n");
          }
  
          System.out.print("testThreadPriorities finished\n");
      }
  
      private static native int getNativePriority();
      private static native boolean supportsThreadPriorities();
  
      static class PriorityStoringThread extends Thread {
          private final boolean setPriority;
          private volatile int nativePriority;
  
          public PriorityStoringThread(boolean setPriority) {
              this.setPriority = setPriority;
              this.nativePriority = -1;
          }
  
          @Override
          public void run() {
              if (setPriority) {
                  setPriority(Thread.MAX_PRIORITY);
              }
  
              nativePriority = Main.getNativePriority();
          }
  
          public int getNativePriority() {
              return nativePriority;
          }
      }
  }
  