blob: a16219e60bdb89a5ee088b6bcbb81dd255d14799 [file] [log] [blame]
jeffhao5d1ac922011-09-29 17:41:15 -07001import sun.misc.Unsafe;
2
3import java.lang.reflect.Field;
4
5public class Main {
6 private static Unsafe UNSAFE;
7
8 public static void main(String[] args) throws Exception {
9 setUp();
10
11 ParkTester test = new ParkTester();
12
13 System.out.println("Test starting");
14
15 test.start();
16 UNSAFE.unpark(test);
17 clearStack(10);
18
19 System.out.println("GC'ing");
20 System.gc();
21 System.gc();
22
23 System.out.println("Asking thread to park");
24 test.parkNow = true;
25
26 try {
27 Thread.sleep(1500);
28 } catch (InterruptedException ex) {
29 // Ignore it.
30 }
31
32 if (test.success) {
33 System.out.println("Test succeeded!");
34 } else {
35 System.out.println("Test failed.");
36 }
37 }
38
39 /**
40 * Set up {@link #UNSAFE}.
41 */
42 public static void setUp() {
43 /*
44 * Subvert the access check to get the unique Unsafe instance.
45 * We can do this because there's no security manager
46 * installed when running the test.
47 */
48 try {
49 Field field = Unsafe.class.getDeclaredField("THE_ONE");
50 field.setAccessible(true);
51
52 UNSAFE = (Unsafe) field.get(null);
53 } catch (NoSuchFieldException ex) {
54 throw new RuntimeException(ex);
55 } catch (IllegalAccessException ex) {
56 throw new RuntimeException(ex);
57 }
58 }
59
60 /**
61 * Scribbles on the stack to help ensure we don't have a fake
62 * pointer that would keep would-be garbage alive.
63 */
64 private static void clearStack(int depth) {
65 int a = 0;
66 int b = 0;
67 int c = 0;
68 int d = 0;
69 int e = 0;
70 int f = 0;
71 int g = 0;
72 int h = 0;
73 int i = 0;
74 int j = 0;
75
76 if (depth > 0) {
77 clearStack(depth - 1);
78 }
79 }
80
81 private static class ParkTester extends Thread {
82 public volatile boolean parkNow = false;
83 public volatile boolean success = false;
84
85 public void run() {
86 while (!parkNow) {
87 try {
88 Thread.sleep(500);
89 } catch (InterruptedException ex) {
90 // Ignore it.
91 }
92 }
93
94 long start = System.currentTimeMillis();
95 UNSAFE.park(false, 500 * 1000000); // 500 msec
96 long elapsed = System.currentTimeMillis() - start;
97
98 if (elapsed > 200) {
99 System.out.println("park()ed for " + elapsed + " msec");
100 success = false;
101 } else {
102 System.out.println("park() returned quickly");
103 success = true;
104 }
105 }
106 }
107}