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