• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 import sun.misc.Unsafe;
2 
3 import java.lang.reflect.Field;
4 
5 public class Main {
6     private static Unsafe UNSAFE;
7 
main(String[] args)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      */
setUp()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      */
clearStack(int depth)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 
run()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 }
108