Home | History | Annotate | Download | only in src
      1 import sun.misc.Unsafe;
      2 
      3 import java.lang.reflect.Field;
      4 
      5 public 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 }
    108