| Roland Levillain | 379e573 | 2017-08-21 19:26:22 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2011 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 17 | import sun.misc.Unsafe; |
| 18 | |
| 19 | import java.lang.reflect.Field; |
| 20 | |
| 21 | public class Main { |
| 22 | private static Unsafe UNSAFE; |
| 23 | |
| 24 | public static void main(String[] args) throws Exception { |
| 25 | setUp(); |
| 26 | |
| 27 | ParkTester test = new ParkTester(); |
| 28 | |
| 29 | System.out.println("Test starting"); |
| 30 | |
| 31 | test.start(); |
| 32 | UNSAFE.unpark(test); |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 33 | |
| 34 | System.out.println("GC'ing"); |
| 35 | System.gc(); |
| Mathieu Chartier | 7befd0e | 2014-02-03 17:48:41 -0800 | [diff] [blame] | 36 | System.runFinalization(); |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 37 | System.gc(); |
| 38 | |
| 39 | System.out.println("Asking thread to park"); |
| 40 | test.parkNow = true; |
| 41 | |
| 42 | try { |
| Roland Levillain | 379e573 | 2017-08-21 19:26:22 +0100 | [diff] [blame] | 43 | // Give some time to the ParkTester thread to honor the park command. |
| 44 | Thread.sleep(3000); |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 45 | } catch (InterruptedException ex) { |
| Roland Levillain | 379e573 | 2017-08-21 19:26:22 +0100 | [diff] [blame] | 46 | System.out.println("Main thread interrupted!"); |
| 47 | System.exit(1); |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 48 | } |
| 49 | |
| 50 | if (test.success) { |
| 51 | System.out.println("Test succeeded!"); |
| 52 | } else { |
| 53 | System.out.println("Test failed."); |
| Hans Boehm | 75c3ff3 | 2020-04-20 16:44:27 -0700 | [diff] [blame] | 54 | test.printTimes(); |
| 55 | System.out.println("Value of success = " + test.success); |
| 56 | Thread.sleep(3000); |
| 57 | System.out.println("Value of success after sleeping = " + test.success); |
| 58 | test.printTimes(); // In case they weren't ready the first time. |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 59 | } |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Set up {@link #UNSAFE}. |
| 64 | */ |
| Brian Carlstrom | 5f57d2d | 2015-06-02 21:53:14 -0700 | [diff] [blame] | 65 | public static void setUp() throws Exception{ |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 66 | /* |
| 67 | * Subvert the access check to get the unique Unsafe instance. |
| 68 | * We can do this because there's no security manager |
| 69 | * installed when running the test. |
| 70 | */ |
| Brian Carlstrom | 5f57d2d | 2015-06-02 21:53:14 -0700 | [diff] [blame] | 71 | Field field = null; |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 72 | try { |
| Brian Carlstrom | 5f57d2d | 2015-06-02 21:53:14 -0700 | [diff] [blame] | 73 | field = Unsafe.class.getDeclaredField("THE_ONE"); |
| 74 | } catch (NoSuchFieldException e1) { |
| 75 | try { |
| 76 | field = Unsafe.class.getDeclaredField("theUnsafe"); |
| 77 | } catch (NoSuchFieldException e2) { |
| 78 | throw new RuntimeException("Failed to find THE_ONE or theUnsafe"); |
| 79 | } |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 80 | } |
| Brian Carlstrom | 5f57d2d | 2015-06-02 21:53:14 -0700 | [diff] [blame] | 81 | field.setAccessible(true); |
| 82 | UNSAFE = (Unsafe) field.get(null); |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 83 | } |
| 84 | |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 85 | private static class ParkTester extends Thread { |
| 86 | public volatile boolean parkNow = false; |
| 87 | public volatile boolean success = false; |
| Hans Boehm | 75c3ff3 | 2020-04-20 16:44:27 -0700 | [diff] [blame] | 88 | public volatile long startTime = 0; |
| 89 | public volatile long elapsedTime = 0; |
| 90 | public volatile long finishTime = 0; |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 91 | |
| 92 | public void run() { |
| 93 | while (!parkNow) { |
| 94 | try { |
| 95 | Thread.sleep(500); |
| 96 | } catch (InterruptedException ex) { |
| 97 | // Ignore it. |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | long start = System.currentTimeMillis(); |
| 102 | UNSAFE.park(false, 500 * 1000000); // 500 msec |
| 103 | long elapsed = System.currentTimeMillis() - start; |
| 104 | |
| 105 | if (elapsed > 200) { |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 106 | success = false; |
| Hans Boehm | 6128097 | 2020-05-13 18:47:20 -0700 | [diff] [blame] | 107 | System.out.println("park()ed for " + elapsed + " msec"); |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 108 | } else { |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 109 | success = true; |
| Hans Boehm | 6128097 | 2020-05-13 18:47:20 -0700 | [diff] [blame] | 110 | // println is occasionally very slow. |
| 111 | // But output still appears before main thread output. |
| 112 | System.out.println("park() returned quickly"); |
| Hans Boehm | 75c3ff3 | 2020-04-20 16:44:27 -0700 | [diff] [blame] | 113 | finishTime = System.currentTimeMillis(); |
| 114 | startTime = start; |
| 115 | elapsedTime = elapsed; |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 116 | } |
| 117 | } |
| Hans Boehm | 75c3ff3 | 2020-04-20 16:44:27 -0700 | [diff] [blame] | 118 | |
| 119 | public void printTimes() { |
| 120 | System.out.println("Started at " + startTime + "ms, took " + elapsedTime |
| 121 | + "ms, signalled at " + finishTime + "ms"); |
| 122 | } |
| jeffhao | 5d1ac92 | 2011-09-29 17:41:15 -0700 | [diff] [blame] | 123 | } |
| 124 | } |