xref: /aosp_15_r20/art/test/053-wait-some/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2007 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker /**
18*795d594fSAndroid Build Coastguard Worker  * Exercise Object.wait(), comparing results against wall clock time.
19*795d594fSAndroid Build Coastguard Worker  */
20*795d594fSAndroid Build Coastguard Worker public class Main {
21*795d594fSAndroid Build Coastguard Worker     /* delays, in milliseconds */
22*795d594fSAndroid Build Coastguard Worker     private final static long[] DELAYS = {
23*795d594fSAndroid Build Coastguard Worker         200, 500, 1000, 2000, 3500, 8000
24*795d594fSAndroid Build Coastguard Worker     };
25*795d594fSAndroid Build Coastguard Worker     // This test is inherently prone to failures through scheduling delays and spurious wakeups.
26*795d594fSAndroid Build Coastguard Worker     // We try it repeatedly, and check that failures are "rare enough".
27*795d594fSAndroid Build Coastguard Worker     // Currently we go for success on the first try or 2 out of 3.
28*795d594fSAndroid Build Coastguard Worker     private final static int NUM_TRIES = 3;
29*795d594fSAndroid Build Coastguard Worker     private final static int MAX_FAILURES = 1;
30*795d594fSAndroid Build Coastguard Worker     private final static int NANOS_PER_MILLI = 1_000_000;
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker     // Allow a random scheduling delay of up to 400 msecs.  That value is empirically determined
33*795d594fSAndroid Build Coastguard Worker     // from failure logs, though we do get occasional violations.
34*795d594fSAndroid Build Coastguard Worker     // We seem to get very occasional very long delays on host, perhaps due to getting paged out.
35*795d594fSAndroid Build Coastguard Worker     private final static int MAX_SCHED_MILLIS = 400;
36*795d594fSAndroid Build Coastguard Worker 
main(String[] args)37*795d594fSAndroid Build Coastguard Worker     public static void main(String[] args) {
38*795d594fSAndroid Build Coastguard Worker         boolean timing = (args.length >= 1) && args[0].equals("--timing");
39*795d594fSAndroid Build Coastguard Worker         doit(timing);
40*795d594fSAndroid Build Coastguard Worker     }
41*795d594fSAndroid Build Coastguard Worker 
doit(boolean timing)42*795d594fSAndroid Build Coastguard Worker     public static void doit(boolean timing) {
43*795d594fSAndroid Build Coastguard Worker         Object sleepy = new Object();
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker         synchronized (sleepy) {
46*795d594fSAndroid Build Coastguard Worker             try {
47*795d594fSAndroid Build Coastguard Worker                 sleepy.wait(-500);
48*795d594fSAndroid Build Coastguard Worker                 System.out.println("HEY: didn't throw on negative arg");
49*795d594fSAndroid Build Coastguard Worker             } catch (IllegalArgumentException iae) {
50*795d594fSAndroid Build Coastguard Worker                 System.out.println("Caught expected exception on neg arg");
51*795d594fSAndroid Build Coastguard Worker             } catch (InterruptedException ie) {
52*795d594fSAndroid Build Coastguard Worker                 ie.printStackTrace(System.out);
53*795d594fSAndroid Build Coastguard Worker             }
54*795d594fSAndroid Build Coastguard Worker 
55*795d594fSAndroid Build Coastguard Worker             for (long delay : DELAYS) {
56*795d594fSAndroid Build Coastguard Worker                 System.out.println("Waiting for " + delay + "ms...");
57*795d594fSAndroid Build Coastguard Worker                 long min = delay - 1;
58*795d594fSAndroid Build Coastguard Worker                 long max = delay + MAX_SCHED_MILLIS;
59*795d594fSAndroid Build Coastguard Worker 
60*795d594fSAndroid Build Coastguard Worker                 int num_failures = 0;
61*795d594fSAndroid Build Coastguard Worker                 long elapsed_to_report = 0;
62*795d594fSAndroid Build Coastguard Worker                 boolean showTime = timing;
63*795d594fSAndroid Build Coastguard Worker                 for (int i = 0; i < (timing ? 1 : NUM_TRIES); ++i) {
64*795d594fSAndroid Build Coastguard Worker                     final long start = System.nanoTime();
65*795d594fSAndroid Build Coastguard Worker                     try {
66*795d594fSAndroid Build Coastguard Worker                         sleepy.wait(delay);
67*795d594fSAndroid Build Coastguard Worker                     } catch (InterruptedException ie) {
68*795d594fSAndroid Build Coastguard Worker                         ie.printStackTrace(System.out);
69*795d594fSAndroid Build Coastguard Worker                     }
70*795d594fSAndroid Build Coastguard Worker                     final long end = System.nanoTime();
71*795d594fSAndroid Build Coastguard Worker 
72*795d594fSAndroid Build Coastguard Worker                     long elapsed = (end - start + NANOS_PER_MILLI / 2) / NANOS_PER_MILLI;
73*795d594fSAndroid Build Coastguard Worker 
74*795d594fSAndroid Build Coastguard Worker                     if (timing) {
75*795d594fSAndroid Build Coastguard Worker                         elapsed_to_report = elapsed;
76*795d594fSAndroid Build Coastguard Worker                     } else {
77*795d594fSAndroid Build Coastguard Worker                         if (elapsed < min || elapsed > max) {
78*795d594fSAndroid Build Coastguard Worker                             ++ num_failures;
79*795d594fSAndroid Build Coastguard Worker                             elapsed_to_report = elapsed;
80*795d594fSAndroid Build Coastguard Worker                         } else if (i == 0) {
81*795d594fSAndroid Build Coastguard Worker                             // Save time if we immediately succeeded.
82*795d594fSAndroid Build Coastguard Worker                             break;
83*795d594fSAndroid Build Coastguard Worker                         }
84*795d594fSAndroid Build Coastguard Worker                     }
85*795d594fSAndroid Build Coastguard Worker                 }
86*795d594fSAndroid Build Coastguard Worker                 if (num_failures > MAX_FAILURES) {
87*795d594fSAndroid Build Coastguard Worker                     System.out.println("Failed " + num_failures + " times out of "
88*795d594fSAndroid Build Coastguard Worker                             + NUM_TRIES + " tries.");
89*795d594fSAndroid Build Coastguard Worker                     showTime = true;
90*795d594fSAndroid Build Coastguard Worker                     if (elapsed_to_report < min) {
91*795d594fSAndroid Build Coastguard Worker                         // This can legitimately happen due to premature wake-ups.
92*795d594fSAndroid Build Coastguard Worker                         // This seems rare and unexpected enough in practice that we should
93*795d594fSAndroid Build Coastguard Worker                         // still report if it occurs repeatedly.
94*795d594fSAndroid Build Coastguard Worker                         System.out.println("  Elapsed time was too short");
95*795d594fSAndroid Build Coastguard Worker                     } else if (elapsed_to_report > max) {
96*795d594fSAndroid Build Coastguard Worker                         System.out.println("  Elapsed time was too long: "
97*795d594fSAndroid Build Coastguard Worker                              + "elapsed = " + elapsed_to_report + " max = " + max);
98*795d594fSAndroid Build Coastguard Worker                     }
99*795d594fSAndroid Build Coastguard Worker                 }
100*795d594fSAndroid Build Coastguard Worker                 if (showTime) {
101*795d594fSAndroid Build Coastguard Worker                     System.out.println("  Wall clock elapsed "
102*795d594fSAndroid Build Coastguard Worker                             + elapsed_to_report + "ms");
103*795d594fSAndroid Build Coastguard Worker                 }
104*795d594fSAndroid Build Coastguard Worker             }
105*795d594fSAndroid Build Coastguard Worker         }
106*795d594fSAndroid Build Coastguard Worker     }
107*795d594fSAndroid Build Coastguard Worker }
108