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