ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/LockSupportTest.java
Revision: 1.29
Committed: Fri May 12 18:48:11 2017 UTC (7 years ago) by jsr166
Branch: MAIN
Changes since 1.28: +12 -7 lines
Log Message:
use MAX_SPURIOUS_WAKEUPS

File Contents

# User Rev Content
1 dl 1.1 /*
2 jsr166 1.15 * Written by Doug Lea and Martin Buchholz with assistance from
3     * members of JCP JSR-166 Expert Group and released to the public
4     * domain, as explained at
5 jsr166 1.18 * http://creativecommons.org/publicdomain/zero/1.0/
6 jsr166 1.8 * Other contributors include Andrew Wright, Jeffrey Hayes,
7     * Pat Fisher, Mike Judd.
8 dl 1.1 */
9    
10 jsr166 1.24 import static java.util.concurrent.TimeUnit.MILLISECONDS;
11    
12 jsr166 1.23 import java.util.concurrent.CountDownLatch;
13 jsr166 1.15 import java.util.concurrent.atomic.AtomicBoolean;
14 jsr166 1.23 import java.util.concurrent.locks.LockSupport;
15 jsr166 1.24
16     import junit.framework.Test;
17     import junit.framework.TestSuite;
18 dl 1.1
19 jsr166 1.10 public class LockSupportTest extends JSR166TestCase {
20 dl 1.1 public static void main(String[] args) {
21 jsr166 1.25 main(suite(), args);
22 dl 1.1 }
23 jsr166 1.15
24 dl 1.1 public static Test suite() {
25 jsr166 1.12 return new TestSuite(LockSupportTest.class);
26 dl 1.1 }
27    
28 jsr166 1.26 static {
29     // Reduce the risk of rare disastrous classloading in first call to
30     // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
31     Class<?> ensureLoaded = LockSupport.class;
32     }
33    
34 dl 1.3 /**
35 jsr166 1.23 * Returns the blocker object used by tests in this file.
36     * Any old object will do; we'll return a convenient one.
37 dl 1.3 */
38 jsr166 1.23 static Object theBlocker() {
39     return LockSupportTest.class;
40     }
41    
42     enum ParkMethod {
43     park() {
44     void park() {
45 jsr166 1.11 LockSupport.park();
46 jsr166 1.23 }
47     void park(long millis) {
48     throw new UnsupportedOperationException();
49     }
50     },
51     parkUntil() {
52     void park(long millis) {
53     LockSupport.parkUntil(deadline(millis));
54     }
55     },
56     parkNanos() {
57     void park(long millis) {
58     LockSupport.parkNanos(MILLISECONDS.toNanos(millis));
59     }
60     },
61     parkBlocker() {
62     void park() {
63     LockSupport.park(theBlocker());
64     }
65     void park(long millis) {
66     throw new UnsupportedOperationException();
67     }
68     },
69     parkUntilBlocker() {
70     void park(long millis) {
71     LockSupport.parkUntil(theBlocker(), deadline(millis));
72     }
73     },
74     parkNanosBlocker() {
75     void park(long millis) {
76     LockSupport.parkNanos(theBlocker(),
77     MILLISECONDS.toNanos(millis));
78     }
79     };
80    
81     void park() { park(2 * LONG_DELAY_MS); }
82     abstract void park(long millis);
83    
84     /** Returns a deadline to use with parkUntil. */
85     long deadline(long millis) {
86     // beware of rounding
87     return System.currentTimeMillis() + millis + 1;
88     }
89 jsr166 1.15 }
90    
91     /**
92 jsr166 1.23 * park is released by subsequent unpark
93 jsr166 1.15 */
94 jsr166 1.23 public void testParkBeforeUnpark_park() {
95     testParkBeforeUnpark(ParkMethod.park);
96     }
97     public void testParkBeforeUnpark_parkNanos() {
98     testParkBeforeUnpark(ParkMethod.parkNanos);
99     }
100     public void testParkBeforeUnpark_parkUntil() {
101     testParkBeforeUnpark(ParkMethod.parkUntil);
102     }
103     public void testParkBeforeUnpark_parkBlocker() {
104     testParkBeforeUnpark(ParkMethod.parkBlocker);
105     }
106     public void testParkBeforeUnpark_parkNanosBlocker() {
107     testParkBeforeUnpark(ParkMethod.parkNanosBlocker);
108     }
109     public void testParkBeforeUnpark_parkUntilBlocker() {
110     testParkBeforeUnpark(ParkMethod.parkUntilBlocker);
111 jsr166 1.15 }
112 jsr166 1.23 public void testParkBeforeUnpark(final ParkMethod parkMethod) {
113     final CountDownLatch pleaseUnpark = new CountDownLatch(1);
114 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
115 jsr166 1.15 public void realRun() {
116 jsr166 1.23 pleaseUnpark.countDown();
117     parkMethod.park();
118 jsr166 1.15 }});
119    
120 jsr166 1.23 await(pleaseUnpark);
121 jsr166 1.11 LockSupport.unpark(t);
122 jsr166 1.23 awaitTermination(t);
123 dl 1.1 }
124    
125 dl 1.3 /**
126 jsr166 1.15 * park is released by preceding unpark
127 dl 1.4 */
128 jsr166 1.23 public void testParkAfterUnpark_park() {
129     testParkAfterUnpark(ParkMethod.park);
130     }
131     public void testParkAfterUnpark_parkNanos() {
132     testParkAfterUnpark(ParkMethod.parkNanos);
133     }
134     public void testParkAfterUnpark_parkUntil() {
135     testParkAfterUnpark(ParkMethod.parkUntil);
136     }
137     public void testParkAfterUnpark_parkBlocker() {
138     testParkAfterUnpark(ParkMethod.parkBlocker);
139     }
140     public void testParkAfterUnpark_parkNanosBlocker() {
141     testParkAfterUnpark(ParkMethod.parkNanosBlocker);
142 dl 1.4 }
143 jsr166 1.23 public void testParkAfterUnpark_parkUntilBlocker() {
144     testParkAfterUnpark(ParkMethod.parkUntilBlocker);
145 jsr166 1.15 }
146 jsr166 1.23 public void testParkAfterUnpark(final ParkMethod parkMethod) {
147     final CountDownLatch pleaseUnpark = new CountDownLatch(1);
148     final AtomicBoolean pleasePark = new AtomicBoolean(false);
149 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
150 jsr166 1.23 public void realRun() {
151     pleaseUnpark.countDown();
152     while (!pleasePark.get())
153 jsr166 1.15 Thread.yield();
154 jsr166 1.23 parkMethod.park();
155 jsr166 1.15 }});
156    
157 jsr166 1.23 await(pleaseUnpark);
158 jsr166 1.15 LockSupport.unpark(t);
159 jsr166 1.23 pleasePark.set(true);
160     awaitTermination(t);
161 jsr166 1.15 }
162    
163     /**
164     * park is released by subsequent interrupt
165     */
166 jsr166 1.23 public void testParkBeforeInterrupt_park() {
167     testParkBeforeInterrupt(ParkMethod.park);
168     }
169     public void testParkBeforeInterrupt_parkNanos() {
170     testParkBeforeInterrupt(ParkMethod.parkNanos);
171     }
172     public void testParkBeforeInterrupt_parkUntil() {
173     testParkBeforeInterrupt(ParkMethod.parkUntil);
174     }
175     public void testParkBeforeInterrupt_parkBlocker() {
176     testParkBeforeInterrupt(ParkMethod.parkBlocker);
177     }
178     public void testParkBeforeInterrupt_parkNanosBlocker() {
179     testParkBeforeInterrupt(ParkMethod.parkNanosBlocker);
180     }
181     public void testParkBeforeInterrupt_parkUntilBlocker() {
182     testParkBeforeInterrupt(ParkMethod.parkUntilBlocker);
183     }
184     public void testParkBeforeInterrupt(final ParkMethod parkMethod) {
185     final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
186 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
187 jsr166 1.12 public void realRun() {
188 jsr166 1.23 pleaseInterrupt.countDown();
189 jsr166 1.29 for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
190 jsr166 1.23 parkMethod.park();
191 jsr166 1.29 if (Thread.interrupted())
192     return;
193     }
194     fail("too many consecutive spurious wakeups?");
195 jsr166 1.15 }});
196    
197 jsr166 1.23 await(pleaseInterrupt);
198     assertThreadStaysAlive(t);
199 jsr166 1.15 t.interrupt();
200 jsr166 1.23 awaitTermination(t);
201 jsr166 1.15 }
202    
203     /**
204 jsr166 1.23 * park is released by preceding interrupt
205 jsr166 1.15 */
206 jsr166 1.23 public void testParkAfterInterrupt_park() {
207     testParkAfterInterrupt(ParkMethod.park);
208     }
209     public void testParkAfterInterrupt_parkNanos() {
210     testParkAfterInterrupt(ParkMethod.parkNanos);
211     }
212     public void testParkAfterInterrupt_parkUntil() {
213     testParkAfterInterrupt(ParkMethod.parkUntil);
214     }
215     public void testParkAfterInterrupt_parkBlocker() {
216     testParkAfterInterrupt(ParkMethod.parkBlocker);
217     }
218     public void testParkAfterInterrupt_parkNanosBlocker() {
219     testParkAfterInterrupt(ParkMethod.parkNanosBlocker);
220 dl 1.4 }
221 jsr166 1.23 public void testParkAfterInterrupt_parkUntilBlocker() {
222     testParkAfterInterrupt(ParkMethod.parkUntilBlocker);
223 jsr166 1.15 }
224 jsr166 1.23 public void testParkAfterInterrupt(final ParkMethod parkMethod) {
225     final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
226     final AtomicBoolean pleasePark = new AtomicBoolean(false);
227 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
228 jsr166 1.15 public void realRun() throws Exception {
229 jsr166 1.23 pleaseInterrupt.countDown();
230     while (!pleasePark.get())
231 jsr166 1.15 Thread.yield();
232     assertTrue(Thread.currentThread().isInterrupted());
233 jsr166 1.23 parkMethod.park();
234 jsr166 1.15 assertTrue(Thread.currentThread().isInterrupted());
235     }});
236    
237 jsr166 1.23 await(pleaseInterrupt);
238 jsr166 1.15 t.interrupt();
239 jsr166 1.23 pleasePark.set(true);
240     awaitTermination(t);
241 jsr166 1.15 }
242    
243     /**
244 jsr166 1.23 * timed park times out if not unparked
245 jsr166 1.15 */
246 jsr166 1.23 public void testParkTimesOut_parkNanos() {
247     testParkTimesOut(ParkMethod.parkNanos);
248     }
249     public void testParkTimesOut_parkUntil() {
250     testParkTimesOut(ParkMethod.parkUntil);
251     }
252     public void testParkTimesOut_parkNanosBlocker() {
253     testParkTimesOut(ParkMethod.parkNanosBlocker);
254     }
255     public void testParkTimesOut_parkUntilBlocker() {
256     testParkTimesOut(ParkMethod.parkUntilBlocker);
257     }
258     public void testParkTimesOut(final ParkMethod parkMethod) {
259 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
260 jsr166 1.23 public void realRun() {
261 jsr166 1.27 for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
262 jsr166 1.23 long startTime = System.nanoTime();
263     parkMethod.park(timeoutMillis());
264     if (millisElapsedSince(startTime) >= timeoutMillis())
265     return;
266     }
267 jsr166 1.27 fail("too many consecutive spurious wakeups?");
268 jsr166 1.15 }});
269    
270 jsr166 1.23 awaitTermination(t);
271 jsr166 1.15 }
272    
273     /**
274 jsr166 1.23 * getBlocker(null) throws NullPointerException
275 jsr166 1.15 */
276 jsr166 1.23 public void testGetBlockerNull() {
277     try {
278     LockSupport.getBlocker(null);
279     shouldThrow();
280     } catch (NullPointerException success) {}
281 dl 1.4 }
282    
283     /**
284 jsr166 1.23 * getBlocker returns the blocker object passed to park
285 dl 1.3 */
286 jsr166 1.23 public void testGetBlocker_parkBlocker() {
287     testGetBlocker(ParkMethod.parkBlocker);
288     }
289     public void testGetBlocker_parkNanosBlocker() {
290     testGetBlocker(ParkMethod.parkNanosBlocker);
291     }
292     public void testGetBlocker_parkUntilBlocker() {
293     testGetBlocker(ParkMethod.parkUntilBlocker);
294     }
295     public void testGetBlocker(final ParkMethod parkMethod) {
296     final CountDownLatch started = new CountDownLatch(1);
297 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
298 jsr166 1.12 public void realRun() {
299 jsr166 1.23 Thread t = Thread.currentThread();
300     started.countDown();
301 jsr166 1.29 for (int tries = MAX_SPURIOUS_WAKEUPS; tries-->0; ) {
302 jsr166 1.23 assertNull(LockSupport.getBlocker(t));
303     parkMethod.park();
304     assertNull(LockSupport.getBlocker(t));
305 jsr166 1.29 if (Thread.interrupted())
306     return;
307     }
308     fail("too many consecutive spurious wakeups?");
309 jsr166 1.11 }});
310    
311 jsr166 1.23 long startTime = System.nanoTime();
312     await(started);
313     for (;;) {
314     Object x = LockSupport.getBlocker(t);
315     if (x == theBlocker()) { // success
316     t.interrupt();
317     awaitTermination(t);
318     assertNull(LockSupport.getBlocker(t));
319     return;
320     } else {
321     assertNull(x); // ok
322     if (millisElapsedSince(startTime) > LONG_DELAY_MS)
323     fail("timed out");
324 jsr166 1.29 if (t.getState() == Thread.State.TERMINATED)
325     break;
326 jsr166 1.23 Thread.yield();
327     }
328     }
329 dl 1.1 }
330    
331 dl 1.3 /**
332 jsr166 1.23 * timed park(0) returns immediately.
333     *
334     * Requires hotspot fix for:
335     * 6763959 java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
336     * which is in jdk7-b118 and 6u25.
337 dl 1.3 */
338 jsr166 1.23 public void testPark0_parkNanos() {
339     testPark0(ParkMethod.parkNanos);
340     }
341     public void testPark0_parkUntil() {
342     testPark0(ParkMethod.parkUntil);
343     }
344     public void testPark0_parkNanosBlocker() {
345     testPark0(ParkMethod.parkNanosBlocker);
346     }
347     public void testPark0_parkUntilBlocker() {
348     testPark0(ParkMethod.parkUntilBlocker);
349     }
350     public void testPark0(final ParkMethod parkMethod) {
351 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
352 jsr166 1.12 public void realRun() {
353 jsr166 1.23 parkMethod.park(0L);
354 jsr166 1.15 }});
355    
356 jsr166 1.23 awaitTermination(t);
357 jsr166 1.15 }
358    
359     /**
360 jsr166 1.23 * timed park(Long.MIN_VALUE) returns immediately.
361 jsr166 1.20 */
362 jsr166 1.23 public void testParkNeg_parkNanos() {
363     testParkNeg(ParkMethod.parkNanos);
364     }
365     public void testParkNeg_parkUntil() {
366     testParkNeg(ParkMethod.parkUntil);
367     }
368     public void testParkNeg_parkNanosBlocker() {
369     testParkNeg(ParkMethod.parkNanosBlocker);
370     }
371     public void testParkNeg_parkUntilBlocker() {
372     testParkNeg(ParkMethod.parkUntilBlocker);
373 jsr166 1.20 }
374 jsr166 1.23 public void testParkNeg(final ParkMethod parkMethod) {
375 jsr166 1.16 Thread t = newStartedThread(new CheckedRunnable() {
376 jsr166 1.15 public void realRun() {
377 jsr166 1.23 parkMethod.park(Long.MIN_VALUE);
378 jsr166 1.11 }});
379    
380 jsr166 1.21 awaitTermination(t);
381 dl 1.1 }
382     }