1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage tests.api.org.apache.harmony.kernel.dalvik; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.lang.reflect.Field; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport junit.framework.Assert; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport junit.framework.TestCase; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport sun.misc.Unsafe; 248fc6b356871b0d750c355bb528afdb93011577e4Jorg Pleumannimport dalvik.annotation.AndroidOnly; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport dalvik.annotation.TestLevel; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport dalvik.annotation.TestTargetClass; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport dalvik.annotation.TestTargetNew; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tests for the <code>park()</code> functionality of {@link Unsafe}. 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project@TestTargetClass(Unsafe.class) 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class ThreadsTest extends TestCase { 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static Unsafe UNSAFE = null; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static RuntimeException INITIALIZEFAILED = null; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static { 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set up {@link #UNSAFE}. This subverts the access check to 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * get the unique Unsafe instance. We can do this because 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * there's no security manager installed when running the 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * test. 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Field field = Unsafe.class.getDeclaredField("THE_ONE"); 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project field.setAccessible(true); 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNSAFE = (Unsafe) field.get(null); 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (NoSuchFieldException ex) { 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project INITIALIZEFAILED = new RuntimeException(ex); 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IllegalAccessException ex) { 52373e615d325c2bde095360e29dd6341acbf75de9Urs Grob INITIALIZEFAILED = new RuntimeException(ex); 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** Test the case where the park times out. */ 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @TestTargetNew( 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project level = TestLevel.PARTIAL, 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project notes = "", 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = "unpark", 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project args = {Object.class} 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ) 638fc6b356871b0d750c355bb528afdb93011577e4Jorg Pleumann @AndroidOnly("Accesses Android-specific private field") 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void test_parkFor_1() { 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Parker parker = new Parker(false, 500); 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread parkerThread = new Thread(parker); 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread waiterThread = 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new Thread(new WaitAndUnpark(1000, parkerThread)); 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parkerThread.start(); 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project waiterThread.start(); 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parker.assertDurationIsInRange(500); 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** Test the case where the unpark happens before the timeout. */ 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @TestTargetNew( 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project level = TestLevel.PARTIAL, 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project notes = "", 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = "unpark", 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project args = {Object.class} 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ) 828fc6b356871b0d750c355bb528afdb93011577e4Jorg Pleumann @AndroidOnly("Accesses Android-specific private field") 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void test_parkFor_2() { 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Parker parker = new Parker(false, 1000); 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread parkerThread = new Thread(parker); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread waiterThread = 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new Thread(new WaitAndUnpark(300, parkerThread)); 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parkerThread.start(); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project waiterThread.start(); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parker.assertDurationIsInRange(300); 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** Test the case where the thread is preemptively unparked. */ 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @TestTargetNew( 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project level = TestLevel.PARTIAL, 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project notes = "", 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = "unpark", 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project args = {Object.class} 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ) 1018fc6b356871b0d750c355bb528afdb93011577e4Jorg Pleumann @AndroidOnly("Accesses Android-specific private field") 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void test_parkFor_3() { 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Parker parker = new Parker(false, 1000); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread parkerThread = new Thread(parker); 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNSAFE.unpark(parkerThread); 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parkerThread.start(); 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parker.assertDurationIsInRange(0); 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** Test the case where the park times out. */ 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @TestTargetNew( 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project level = TestLevel.PARTIAL, 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project notes = "", 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = "unpark", 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project args = {Object.class} 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ) 1188fc6b356871b0d750c355bb528afdb93011577e4Jorg Pleumann @AndroidOnly("Accesses Android-specific private field") 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void test_parkUntil_1() { 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Parker parker = new Parker(true, 500); 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread parkerThread = new Thread(parker); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread waiterThread = 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new Thread(new WaitAndUnpark(1000, parkerThread)); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parkerThread.start(); 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project waiterThread.start(); 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parker.assertDurationIsInRange(500); 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** Test the case where the unpark happens before the timeout. */ 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @TestTargetNew( 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project level = TestLevel.PARTIAL, 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project notes = "", 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = "unpark", 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project args = {Object.class} 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ) 1378fc6b356871b0d750c355bb528afdb93011577e4Jorg Pleumann @AndroidOnly("Accesses Android-specific private field") 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void test_parkUntil_2() { 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Parker parker = new Parker(true, 1000); 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread parkerThread = new Thread(parker); 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread waiterThread = 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new Thread(new WaitAndUnpark(300, parkerThread)); 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parkerThread.start(); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project waiterThread.start(); 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parker.assertDurationIsInRange(300); 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** Test the case where the thread is preemptively unparked. */ 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @TestTargetNew( 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project level = TestLevel.PARTIAL, 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project notes = "", 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = "unpark", 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project args = {Object.class} 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ) 1568fc6b356871b0d750c355bb528afdb93011577e4Jorg Pleumann @AndroidOnly("Accesses Android-specific private field") 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void test_parkUntil_3() { 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Parker parker = new Parker(true, 1000); 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread parkerThread = new Thread(parker); 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNSAFE.unpark(parkerThread); 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parkerThread.start(); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parker.assertDurationIsInRange(0); 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO: Add more tests. 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper <code>Runnable</code> for tests, which parks for or until 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the indicated value, noting the duration of time actually parked. 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static class Parker implements Runnable { 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** whether {@link #amount} is milliseconds to wait in an 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * absolute fashion (<code>true</code>) or nanoseconds to wait 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in a relative fashion (<code>false</code>) */ 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final boolean absolute; 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** amount to wait (see above) */ 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final long amount; 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** whether the run has completed */ 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean completed; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** recorded start time */ 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private long startMillis; 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** recorded end time */ 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private long endMillis; 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Construct an instance. 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param absolute whether to use an absolute time or not; in 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * either case, this constructor takes a duration to park for 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param parkMillis the number of milliseconds to be parked 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Parker(boolean absolute, long parkMillis) { 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.absolute = absolute; 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Multiply by 1000000 because parkFor() takes nanoseconds. 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.amount = absolute ? parkMillis : parkMillis * 1000000; 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void run() { 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean absolute = this.absolute; 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long amount = this.amount; 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long start = System.currentTimeMillis(); 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (absolute) { 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNSAFE.park(true, start + amount); 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNSAFE.park(false, amount); 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long end = System.currentTimeMillis(); 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (this) { 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startMillis = start; 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project endMillis = end; 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project completed = true; 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project notifyAll(); 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Wait for the test to complete and return the duration. 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param maxWaitMillis the maximum amount of time to 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * wait for the test to complete 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the duration in milliseconds 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public long getDurationMillis(long maxWaitMillis) { 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project synchronized (this) { 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! completed) { 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project wait(maxWaitMillis); 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (InterruptedException ex) { 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Ignore it. 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! completed) { 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Assert.fail("parker hanging"); 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return endMillis - startMillis; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Asserts that the actual duration is within 5% of the 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * given expected time. 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param expectedMillis the expected duration, in milliseconds 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void assertDurationIsInRange(long expectedMillis) { 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Allow a bit more slop for the maximum on "expected 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instantaneous" results. 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long minimum = (long) ((double) expectedMillis * 0.95); 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long maximum = 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Math.max((long) ((double) expectedMillis * 1.05), 10); 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long waitMillis = Math.max(expectedMillis * 10, 10); 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long duration = getDurationMillis(waitMillis); 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (duration < minimum) { 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Assert.fail("expected duration: " + expectedMillis + 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "; actual too short: " + duration); 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (duration > maximum) { 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Assert.fail("expected duration: " + expectedMillis + 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "; actual too long: " + duration); 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper <code>Runnable</code> for tests, which waits for the 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specified amount of time and then unparks an indicated thread. 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static class WaitAndUnpark implements Runnable { 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final long waitMillis; 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final Thread thread; 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public WaitAndUnpark(long waitMillis, Thread thread) { 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.waitMillis = waitMillis; 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.thread = thread; 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void run() { 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Thread.sleep(waitMillis); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (InterruptedException ex) { 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("shouldn't happen", ex); 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNSAFE.unpark(thread); 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected void setUp() throws Exception { 302373e615d325c2bde095360e29dd6341acbf75de9Urs Grob if (INITIALIZEFAILED != null) { 303373e615d325c2bde095360e29dd6341acbf75de9Urs Grob throw INITIALIZEFAILED; 304373e615d325c2bde095360e29dd6341acbf75de9Urs Grob } 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 307