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
17import java.util.ArrayList;
18
19/**
20 * Test some basic thread stuff.
21 */
22public class Main {
23    static {
24        System.loadLibrary("arttest");
25    }
26
27    public static void main(String[] args) throws Exception {
28        System.out.println("thread test starting");
29        testThreadCapacity();
30        testThreadDaemons();
31        testSleepZero();
32        testSetName();
33        testThreadPriorities();
34        System.out.println("thread test done");
35    }
36
37    /*
38     * Simple thread capacity test.
39     */
40    private static void testThreadCapacity() throws Exception {
41        TestCapacityThread[] threads = new TestCapacityThread[512];
42        for (int i = 0; i < 512; i++) {
43            threads[i] = new TestCapacityThread();
44        }
45
46        for (TestCapacityThread thread : threads) {
47            thread.start();
48        }
49        for (TestCapacityThread thread : threads) {
50            thread.join();
51        }
52
53        System.out.println("testThreadCapacity thread count: " + TestCapacityThread.mCount);
54    }
55
56    private static class TestCapacityThread extends Thread {
57        static int mCount = 0;
58        public void run() {
59            synchronized (TestCapacityThread.class) {
60                ++mCount;
61            }
62            try {
63                sleep(1000);
64            } catch (Exception ex) {
65            }
66        }
67    }
68
69    private static void testThreadDaemons() {
70        Thread t = new Thread(null, new TestDaemonThread(), "TestDaemonThread", 7168);
71
72        t.setDaemon(false);
73
74        System.out.print("testThreadDaemons starting thread '" + t.getName() + "'\n");
75        t.start();
76
77        try {
78            t.join();
79        } catch (InterruptedException ex) {
80            ex.printStackTrace();
81        }
82
83        System.out.print("testThreadDaemons finished\n");
84    }
85
86    private static class TestDaemonThread implements Runnable {
87        public void run() {
88            System.out.print("testThreadDaemons @ Thread running\n");
89
90            try {
91                Thread.currentThread().setDaemon(true);
92                System.out.print("testThreadDaemons @ FAILED: setDaemon() succeeded\n");
93            } catch (IllegalThreadStateException itse) {
94                System.out.print("testThreadDaemons @ Got expected setDaemon exception\n");
95            }
96
97            try {
98                Thread.sleep(2000);
99            }
100            catch (InterruptedException ie) {
101                System.out.print("testThreadDaemons @ Interrupted!\n");
102            }
103            finally {
104                System.out.print("testThreadDaemons @ Thread bailing\n");
105            }
106        }
107    }
108
109    private static void testSleepZero() throws Exception {
110        Thread.currentThread().interrupt();
111        try {
112            Thread.sleep(0);
113            throw new AssertionError("unreachable");
114        } catch (InterruptedException e) {
115            if (Thread.currentThread().isInterrupted()) {
116                throw new AssertionError("thread is interrupted");
117            }
118        }
119        System.out.print("testSleepZero finished\n");
120    }
121
122    private static void testSetName() throws Exception {
123        System.out.print("testSetName starting\n");
124        Thread thread = new Thread() {
125            @Override
126            public void run() {
127                System.out.print("testSetName running\n");
128            }
129        };
130        thread.start();
131        thread.setName("HelloWorld");  // b/17302037 hang if setName called after start
132        if (!thread.getName().equals("HelloWorld")) {
133            throw new AssertionError("Unexpected thread name: " + thread.getName());
134        }
135        thread.join();
136        if (!thread.getName().equals("HelloWorld")) {
137            throw new AssertionError("Unexpected thread name after join: " + thread.getName());
138        }
139        System.out.print("testSetName finished\n");
140    }
141
142    private static void testThreadPriorities() throws Exception {
143        System.out.print("testThreadPriorities starting\n");
144
145        PriorityStoringThread t1 = new PriorityStoringThread(false);
146        t1.setPriority(Thread.MAX_PRIORITY);
147        t1.start();
148        t1.join();
149        if (supportsThreadPriorities() && (t1.getNativePriority() != Thread.MAX_PRIORITY)) {
150            System.out.print("thread priority for t1 was " + t1.getNativePriority() +
151                " [expected Thread.MAX_PRIORITY]\n");
152        }
153
154        PriorityStoringThread t2 = new PriorityStoringThread(true);
155        t2.start();
156        t2.join();
157        if (supportsThreadPriorities() && (t2.getNativePriority() != Thread.MAX_PRIORITY)) {
158            System.out.print("thread priority for t2 was " + t2.getNativePriority() +
159                " [expected Thread.MAX_PRIORITY]\n");
160        }
161
162        System.out.print("testThreadPriorities finished\n");
163    }
164
165    private static native int getNativePriority();
166    private static native boolean supportsThreadPriorities();
167
168    static class PriorityStoringThread extends Thread {
169        private final boolean setPriority;
170        private volatile int nativePriority;
171
172        public PriorityStoringThread(boolean setPriority) {
173            this.setPriority = setPriority;
174            this.nativePriority = -1;
175        }
176
177        @Override
178        public void run() {
179            if (setPriority) {
180                setPriority(Thread.MAX_PRIORITY);
181            }
182
183            nativePriority = Main.getNativePriority();
184        }
185
186        public int getNativePriority() {
187            return nativePriority;
188        }
189    }
190}
191