blob: 121901776bddb5b9ef42bbf2c4eaab10a93e616e [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include John Vint
6 */
7
8package jsr166;
9
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010010import static java.util.concurrent.TimeUnit.MILLISECONDS;
11
Calin Juravle8f0d92b2013-08-01 17:26:00 +010012import java.util.ArrayList;
13import java.util.List;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010014import java.util.concurrent.CountDownLatch;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010015import java.util.concurrent.Phaser;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010016import java.util.concurrent.TimeoutException;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010017import java.util.concurrent.atomic.AtomicInteger;
18
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010019import junit.framework.Test;
20import junit.framework.TestSuite;
21
Calin Juravle8f0d92b2013-08-01 17:26:00 +010022public class PhaserTest extends JSR166TestCase {
23
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010024 // android-note: Removed because the CTS runner does a bad job of
25 // retrying tests that have suite() declarations.
26 //
27 // public static void main(String[] args) {
28 // main(suite(), args);
29 // }
30 // public static Test suite() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000031 // return new TestSuite(PhaserTest.class);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010032 // }
33
Calin Juravle8f0d92b2013-08-01 17:26:00 +010034 private static final int maxParties = 65535;
35
36 /** Checks state of unterminated phaser. */
37 protected void assertState(Phaser phaser,
38 int phase, int parties, int unarrived) {
39 assertEquals(phase, phaser.getPhase());
40 assertEquals(parties, phaser.getRegisteredParties());
41 assertEquals(unarrived, phaser.getUnarrivedParties());
42 assertEquals(parties - unarrived, phaser.getArrivedParties());
43 assertFalse(phaser.isTerminated());
44 }
45
46 /** Checks state of terminated phaser. */
47 protected void assertTerminated(Phaser phaser, int maxPhase, int parties) {
48 assertTrue(phaser.isTerminated());
49 int expectedPhase = maxPhase + Integer.MIN_VALUE;
50 assertEquals(expectedPhase, phaser.getPhase());
51 assertEquals(parties, phaser.getRegisteredParties());
52 assertEquals(expectedPhase, phaser.register());
53 assertEquals(expectedPhase, phaser.arrive());
54 assertEquals(expectedPhase, phaser.arriveAndDeregister());
55 }
56
57 protected void assertTerminated(Phaser phaser, int maxPhase) {
58 assertTerminated(phaser, maxPhase, 0);
59 }
60
61 /**
62 * Empty constructor builds a new Phaser with no parent, no registered
63 * parties and initial phase number of 0
64 */
65 public void testConstructorDefaultValues() {
66 Phaser phaser = new Phaser();
67 assertNull(phaser.getParent());
68 assertEquals(0, phaser.getRegisteredParties());
69 assertEquals(0, phaser.getArrivedParties());
70 assertEquals(0, phaser.getUnarrivedParties());
71 assertEquals(0, phaser.getPhase());
72 }
73
74 /**
75 * Constructing with a negative number of parties throws
76 * IllegalArgumentException
77 */
78 public void testConstructorNegativeParties() {
79 try {
80 new Phaser(-1);
81 shouldThrow();
82 } catch (IllegalArgumentException success) {}
83 }
84
85 /**
86 * Constructing with a negative number of parties throws
87 * IllegalArgumentException
88 */
89 public void testConstructorNegativeParties2() {
90 try {
91 new Phaser(new Phaser(), -1);
92 shouldThrow();
93 } catch (IllegalArgumentException success) {}
94 }
95
96 /**
97 * Constructing with a number of parties > 65535 throws
98 * IllegalArgumentException
99 */
100 public void testConstructorPartiesExceedsLimit() {
101 new Phaser(maxParties);
102 try {
103 new Phaser(maxParties + 1);
104 shouldThrow();
105 } catch (IllegalArgumentException success) {}
106
107 new Phaser(new Phaser(), maxParties);
108 try {
109 new Phaser(new Phaser(), maxParties + 1);
110 shouldThrow();
111 } catch (IllegalArgumentException success) {}
112 }
113
114 /**
115 * The parent provided to the constructor should be returned from
116 * a later call to getParent
117 */
118 public void testConstructor3() {
119 Phaser parent = new Phaser();
120 assertSame(parent, new Phaser(parent).getParent());
121 assertNull(new Phaser(null).getParent());
122 }
123
124 /**
125 * The parent being input into the parameter should equal the original
126 * parent when being returned
127 */
128 public void testConstructor5() {
129 Phaser parent = new Phaser();
130 assertSame(parent, new Phaser(parent, 0).getParent());
131 assertNull(new Phaser(null, 0).getParent());
132 }
133
134 /**
135 * register() will increment the number of unarrived parties by
136 * one and not affect its arrived parties
137 */
138 public void testRegister1() {
139 Phaser phaser = new Phaser();
140 assertState(phaser, 0, 0, 0);
141 assertEquals(0, phaser.register());
142 assertState(phaser, 0, 1, 1);
143 }
144
145 /**
146 * Registering more than 65536 parties causes IllegalStateException
147 */
148 public void testRegister2() {
149 Phaser phaser = new Phaser(0);
150 assertState(phaser, 0, 0, 0);
151 assertEquals(0, phaser.bulkRegister(maxParties - 10));
152 assertState(phaser, 0, maxParties - 10, maxParties - 10);
153 for (int i = 0; i < 10; i++) {
154 assertState(phaser, 0, maxParties - 10 + i, maxParties - 10 + i);
155 assertEquals(0, phaser.register());
156 }
157 assertState(phaser, 0, maxParties, maxParties);
158 try {
159 phaser.register();
160 shouldThrow();
161 } catch (IllegalStateException success) {}
162
163 try {
164 phaser.bulkRegister(Integer.MAX_VALUE);
165 shouldThrow();
166 } catch (IllegalStateException success) {}
167
168 assertEquals(0, phaser.bulkRegister(0));
169 assertState(phaser, 0, maxParties, maxParties);
170 }
171
172 /**
173 * register() correctly returns the current barrier phase number
174 * when invoked
175 */
176 public void testRegister3() {
177 Phaser phaser = new Phaser();
178 assertEquals(0, phaser.register());
179 assertEquals(0, phaser.arrive());
180 assertEquals(1, phaser.register());
181 assertState(phaser, 1, 2, 2);
182 }
183
184 /**
185 * register causes the next arrive to not increment the phase
186 * rather retain the phase number
187 */
188 public void testRegister4() {
189 Phaser phaser = new Phaser(1);
190 assertEquals(0, phaser.arrive());
191 assertEquals(1, phaser.register());
192 assertEquals(1, phaser.arrive());
193 assertState(phaser, 1, 2, 1);
194 }
195
196 /**
197 * register on a subphaser that is currently empty succeeds, even
198 * in the presence of another non-empty subphaser
199 */
200 public void testRegisterEmptySubPhaser() {
201 Phaser root = new Phaser();
202 Phaser child1 = new Phaser(root, 1);
203 Phaser child2 = new Phaser(root, 0);
204 assertEquals(0, child2.register());
205 assertState(root, 0, 2, 2);
206 assertState(child1, 0, 1, 1);
207 assertState(child2, 0, 1, 1);
208 assertEquals(0, child2.arriveAndDeregister());
209 assertState(root, 0, 1, 1);
210 assertState(child1, 0, 1, 1);
211 assertState(child2, 0, 0, 0);
212 assertEquals(0, child2.register());
213 assertEquals(0, child2.arriveAndDeregister());
214 assertState(root, 0, 1, 1);
215 assertState(child1, 0, 1, 1);
216 assertState(child2, 0, 0, 0);
217 assertEquals(0, child1.arriveAndDeregister());
218 assertTerminated(root, 1);
219 assertTerminated(child1, 1);
220 assertTerminated(child2, 1);
221 }
222
223 /**
224 * Invoking bulkRegister with a negative parameter throws an
225 * IllegalArgumentException
226 */
227 public void testBulkRegister1() {
228 try {
229 new Phaser().bulkRegister(-1);
230 shouldThrow();
231 } catch (IllegalArgumentException success) {}
232 }
233
234 /**
235 * bulkRegister should correctly record the number of unarrived
236 * parties with the number of parties being registered
237 */
238 public void testBulkRegister2() {
239 Phaser phaser = new Phaser();
240 assertEquals(0, phaser.bulkRegister(0));
241 assertState(phaser, 0, 0, 0);
242 assertEquals(0, phaser.bulkRegister(20));
243 assertState(phaser, 0, 20, 20);
244 }
245
246 /**
247 * Registering with a number of parties greater than or equal to 1<<16
248 * throws IllegalStateException.
249 */
250 public void testBulkRegister3() {
251 assertEquals(0, new Phaser().bulkRegister((1 << 16) - 1));
252
253 try {
254 new Phaser().bulkRegister(1 << 16);
255 shouldThrow();
256 } catch (IllegalStateException success) {}
257
258 try {
259 new Phaser(2).bulkRegister((1 << 16) - 2);
260 shouldThrow();
261 } catch (IllegalStateException success) {}
262 }
263
264 /**
265 * the phase number increments correctly when tripping the barrier
266 */
267 public void testPhaseIncrement1() {
268 for (int size = 1; size < nine; size++) {
269 final Phaser phaser = new Phaser(size);
270 for (int index = 0; index <= (1 << size); index++) {
271 int phase = phaser.arrive();
272 assertTrue(index % size == 0 ? (index / size) == phase : index - (phase * size) > 0);
273 }
274 }
275 }
276
277 /**
278 * arrive() on a registered phaser increments phase.
279 */
280 public void testArrive1() {
281 Phaser phaser = new Phaser(1);
282 assertState(phaser, 0, 1, 1);
283 assertEquals(0, phaser.arrive());
284 assertState(phaser, 1, 1, 1);
285 }
286
287 /**
288 * arriveAndDeregister does not wait for others to arrive at barrier
289 */
290 public void testArriveAndDeregister() {
291 final Phaser phaser = new Phaser(1);
292 for (int i = 0; i < 10; i++) {
293 assertState(phaser, 0, 1, 1);
294 assertEquals(0, phaser.register());
295 assertState(phaser, 0, 2, 2);
296 assertEquals(0, phaser.arriveAndDeregister());
297 assertState(phaser, 0, 1, 1);
298 }
299 assertEquals(0, phaser.arriveAndDeregister());
300 assertTerminated(phaser, 1);
301 }
302
303 /**
304 * arriveAndDeregister does not wait for others to arrive at barrier
305 */
306 public void testArrive2() {
307 final Phaser phaser = new Phaser();
308 assertEquals(0, phaser.register());
309 List<Thread> threads = new ArrayList<Thread>();
310 for (int i = 0; i < 10; i++) {
311 assertEquals(0, phaser.register());
312 threads.add(newStartedThread(new CheckedRunnable() {
313 public void realRun() {
314 assertEquals(0, phaser.arriveAndDeregister());
315 }}));
316 }
317
318 for (Thread thread : threads)
319 awaitTermination(thread);
320 assertState(phaser, 0, 1, 1);
321 assertEquals(0, phaser.arrive());
322 assertState(phaser, 1, 1, 1);
323 }
324
325 /**
326 * arrive() returns a negative number if the Phaser is terminated
327 */
328 public void testArrive3() {
329 Phaser phaser = new Phaser(1);
330 phaser.forceTermination();
331 assertTerminated(phaser, 0, 1);
332 assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
333 assertTrue(phaser.arrive() < 0);
334 assertTrue(phaser.register() < 0);
335 assertTrue(phaser.arriveAndDeregister() < 0);
336 assertTrue(phaser.awaitAdvance(1) < 0);
337 assertTrue(phaser.getPhase() < 0);
338 }
339
340 /**
341 * arriveAndDeregister() throws IllegalStateException if number of
342 * registered or unarrived parties would become negative
343 */
344 public void testArriveAndDeregister1() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000345 Phaser phaser = new Phaser();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100346 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100347 phaser.arriveAndDeregister();
348 shouldThrow();
349 } catch (IllegalStateException success) {}
350 }
351
352 /**
353 * arriveAndDeregister reduces the number of arrived parties
354 */
355 public void testArriveAndDeregister2() {
356 final Phaser phaser = new Phaser(1);
357 assertEquals(0, phaser.register());
358 assertEquals(0, phaser.arrive());
359 assertState(phaser, 0, 2, 1);
360 assertEquals(0, phaser.arriveAndDeregister());
361 assertState(phaser, 1, 1, 1);
362 }
363
364 /**
365 * arriveAndDeregister arrives at the barrier on a phaser with a parent and
366 * when a deregistration occurs and causes the phaser to have zero parties
367 * its parent will be deregistered as well
368 */
369 public void testArriveAndDeregister3() {
370 Phaser parent = new Phaser();
371 Phaser child = new Phaser(parent);
372 assertState(child, 0, 0, 0);
373 assertState(parent, 0, 0, 0);
374 assertEquals(0, child.register());
375 assertState(child, 0, 1, 1);
376 assertState(parent, 0, 1, 1);
377 assertEquals(0, child.arriveAndDeregister());
378 assertTerminated(child, 1);
379 assertTerminated(parent, 1);
380 }
381
382 /**
383 * arriveAndDeregister deregisters one party from its parent when
384 * the number of parties of child is zero after deregistration
385 */
386 public void testArriveAndDeregister4() {
387 Phaser parent = new Phaser();
388 Phaser child = new Phaser(parent);
389 assertEquals(0, parent.register());
390 assertEquals(0, child.register());
391 assertState(child, 0, 1, 1);
392 assertState(parent, 0, 2, 2);
393 assertEquals(0, child.arriveAndDeregister());
394 assertState(child, 0, 0, 0);
395 assertState(parent, 0, 1, 1);
396 }
397
398 /**
399 * arriveAndDeregister deregisters one party from its parent when
400 * the number of parties of root is nonzero after deregistration.
401 */
402 public void testArriveAndDeregister5() {
403 Phaser root = new Phaser();
404 Phaser parent = new Phaser(root);
405 Phaser child = new Phaser(parent);
406 assertState(root, 0, 0, 0);
407 assertState(parent, 0, 0, 0);
408 assertState(child, 0, 0, 0);
409 assertEquals(0, child.register());
410 assertState(root, 0, 1, 1);
411 assertState(parent, 0, 1, 1);
412 assertState(child, 0, 1, 1);
413 assertEquals(0, child.arriveAndDeregister());
414 assertTerminated(child, 1);
415 assertTerminated(parent, 1);
416 assertTerminated(root, 1);
417 }
418
419 /**
420 * arriveAndDeregister returns the phase in which it leaves the
421 * phaser in after deregistration
422 */
423 public void testArriveAndDeregister6() {
424 final Phaser phaser = new Phaser(2);
425 Thread t = newStartedThread(new CheckedRunnable() {
426 public void realRun() {
427 assertEquals(0, phaser.arrive());
428 }});
429 assertEquals(1, phaser.arriveAndAwaitAdvance());
430 assertState(phaser, 1, 2, 2);
431 assertEquals(1, phaser.arriveAndDeregister());
432 assertState(phaser, 1, 1, 1);
433 assertEquals(1, phaser.arriveAndDeregister());
434 assertTerminated(phaser, 2);
435 awaitTermination(t);
436 }
437
438 /**
439 * awaitAdvance succeeds upon advance
440 */
441 public void testAwaitAdvance1() {
442 final Phaser phaser = new Phaser(1);
443 assertEquals(0, phaser.arrive());
444 assertEquals(1, phaser.awaitAdvance(0));
445 }
446
447 /**
448 * awaitAdvance with a negative parameter will return without affecting the
449 * phaser
450 */
451 public void testAwaitAdvance2() {
452 Phaser phaser = new Phaser();
453 assertTrue(phaser.awaitAdvance(-1) < 0);
454 assertState(phaser, 0, 0, 0);
455 }
456
457 /**
458 * awaitAdvanceInterruptibly blocks interruptibly
459 */
460 public void testAwaitAdvanceInterruptibly_interruptible() throws InterruptedException {
461 final Phaser phaser = new Phaser(1);
462 final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
463
464 Thread t1 = newStartedThread(new CheckedRunnable() {
465 public void realRun() {
466 Thread.currentThread().interrupt();
467 try {
468 phaser.awaitAdvanceInterruptibly(0);
469 shouldThrow();
470 } catch (InterruptedException success) {}
471 assertFalse(Thread.interrupted());
472
473 pleaseInterrupt.countDown();
474 try {
475 phaser.awaitAdvanceInterruptibly(0);
476 shouldThrow();
477 } catch (InterruptedException success) {}
478 assertFalse(Thread.interrupted());
479 }});
480
481 Thread t2 = newStartedThread(new CheckedRunnable() {
482 public void realRun() throws TimeoutException {
483 Thread.currentThread().interrupt();
484 try {
485 phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
486 shouldThrow();
487 } catch (InterruptedException success) {}
488 assertFalse(Thread.interrupted());
489
490 pleaseInterrupt.countDown();
491 try {
492 phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
493 shouldThrow();
494 } catch (InterruptedException success) {}
495 assertFalse(Thread.interrupted());
496 }});
497
498 await(pleaseInterrupt);
499 assertState(phaser, 0, 1, 1);
500 assertThreadsStayAlive(t1, t2);
501 t1.interrupt();
502 t2.interrupt();
503 awaitTermination(t1);
504 awaitTermination(t2);
505 assertState(phaser, 0, 1, 1);
506 assertEquals(0, phaser.arrive());
507 assertState(phaser, 1, 1, 1);
508 }
509
510 /**
511 * awaitAdvance continues waiting if interrupted before waiting
512 */
513 public void testAwaitAdvanceAfterInterrupt() {
514 final Phaser phaser = new Phaser();
515 assertEquals(0, phaser.register());
516 final CountDownLatch pleaseArrive = new CountDownLatch(1);
517
518 Thread t = newStartedThread(new CheckedRunnable() {
519 public void realRun() {
520 Thread.currentThread().interrupt();
521 assertEquals(0, phaser.register());
522 assertEquals(0, phaser.arrive());
523 pleaseArrive.countDown();
524 assertTrue(Thread.currentThread().isInterrupted());
525 assertEquals(1, phaser.awaitAdvance(0));
526 assertTrue(Thread.interrupted());
527 }});
528
529 await(pleaseArrive);
Tobias Thierercff661d2017-02-19 15:01:51 +0000530 waitForThreadToEnterWaitState(t);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100531 assertEquals(0, phaser.arrive());
532 awaitTermination(t);
533
534 Thread.currentThread().interrupt();
535 assertEquals(1, phaser.awaitAdvance(0));
536 assertTrue(Thread.interrupted());
537 }
538
539 /**
540 * awaitAdvance continues waiting if interrupted while waiting
541 */
542 public void testAwaitAdvanceBeforeInterrupt() {
543 final Phaser phaser = new Phaser();
544 assertEquals(0, phaser.register());
545 final CountDownLatch pleaseArrive = new CountDownLatch(1);
546
547 Thread t = newStartedThread(new CheckedRunnable() {
548 public void realRun() {
549 assertEquals(0, phaser.register());
550 assertEquals(0, phaser.arrive());
551 assertFalse(Thread.currentThread().isInterrupted());
552 pleaseArrive.countDown();
553 assertEquals(1, phaser.awaitAdvance(0));
554 assertTrue(Thread.interrupted());
555 }});
556
557 await(pleaseArrive);
Tobias Thierercff661d2017-02-19 15:01:51 +0000558 waitForThreadToEnterWaitState(t);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100559 t.interrupt();
560 assertEquals(0, phaser.arrive());
561 awaitTermination(t);
562
563 Thread.currentThread().interrupt();
564 assertEquals(1, phaser.awaitAdvance(0));
565 assertTrue(Thread.interrupted());
566 }
567
568 /**
569 * arriveAndAwaitAdvance continues waiting if interrupted before waiting
570 */
571 public void testArriveAndAwaitAdvanceAfterInterrupt() {
572 final Phaser phaser = new Phaser();
573 assertEquals(0, phaser.register());
Tobias Thierercff661d2017-02-19 15:01:51 +0000574 final CountDownLatch pleaseArrive = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100575
576 Thread t = newStartedThread(new CheckedRunnable() {
577 public void realRun() {
578 Thread.currentThread().interrupt();
579 assertEquals(0, phaser.register());
Tobias Thierercff661d2017-02-19 15:01:51 +0000580 pleaseArrive.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100581 assertTrue(Thread.currentThread().isInterrupted());
582 assertEquals(1, phaser.arriveAndAwaitAdvance());
Tobias Thierercff661d2017-02-19 15:01:51 +0000583 assertTrue(Thread.interrupted());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100584 }});
585
Tobias Thierercff661d2017-02-19 15:01:51 +0000586 await(pleaseArrive);
587 waitForThreadToEnterWaitState(t);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100588 Thread.currentThread().interrupt();
589 assertEquals(1, phaser.arriveAndAwaitAdvance());
590 assertTrue(Thread.interrupted());
591 awaitTermination(t);
592 }
593
594 /**
595 * arriveAndAwaitAdvance continues waiting if interrupted while waiting
596 */
597 public void testArriveAndAwaitAdvanceBeforeInterrupt() {
598 final Phaser phaser = new Phaser();
599 assertEquals(0, phaser.register());
600 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
601
602 Thread t = newStartedThread(new CheckedRunnable() {
603 public void realRun() {
604 assertEquals(0, phaser.register());
605 assertFalse(Thread.currentThread().isInterrupted());
606 pleaseInterrupt.countDown();
607 assertEquals(1, phaser.arriveAndAwaitAdvance());
Tobias Thierercff661d2017-02-19 15:01:51 +0000608 assertTrue(Thread.interrupted());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100609 }});
610
611 await(pleaseInterrupt);
Tobias Thierercff661d2017-02-19 15:01:51 +0000612 waitForThreadToEnterWaitState(t);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100613 t.interrupt();
614 Thread.currentThread().interrupt();
615 assertEquals(1, phaser.arriveAndAwaitAdvance());
616 assertTrue(Thread.interrupted());
617 awaitTermination(t);
618 }
619
620 /**
621 * awaitAdvance atomically waits for all parties within the same phase to
622 * complete before continuing
623 */
624 public void testAwaitAdvance4() {
625 final Phaser phaser = new Phaser(4);
626 final AtomicInteger count = new AtomicInteger(0);
627 List<Thread> threads = new ArrayList<Thread>();
628 for (int i = 0; i < 4; i++)
629 threads.add(newStartedThread(new CheckedRunnable() {
630 public void realRun() {
631 for (int k = 0; k < 3; k++) {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000632 assertEquals(2 * k + 1, phaser.arriveAndAwaitAdvance());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100633 count.incrementAndGet();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000634 assertEquals(2 * k + 1, phaser.arrive());
635 assertEquals(2 * k + 2, phaser.awaitAdvance(2 * k + 1));
636 assertEquals(4 * (k + 1), count.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100637 }}}));
638
639 for (Thread thread : threads)
640 awaitTermination(thread);
641 }
642
643 /**
644 * awaitAdvance returns the current phase
645 */
646 public void testAwaitAdvance5() {
647 final Phaser phaser = new Phaser(1);
648 assertEquals(1, phaser.awaitAdvance(phaser.arrive()));
649 assertEquals(1, phaser.getPhase());
650 assertEquals(1, phaser.register());
651 List<Thread> threads = new ArrayList<Thread>();
652 for (int i = 0; i < 8; i++) {
653 final CountDownLatch latch = new CountDownLatch(1);
654 final boolean goesFirst = ((i & 1) == 0);
655 threads.add(newStartedThread(new CheckedRunnable() {
656 public void realRun() {
657 if (goesFirst)
658 latch.countDown();
659 else
660 await(latch);
661 phaser.arrive();
662 }}));
663 if (goesFirst)
664 await(latch);
665 else
666 latch.countDown();
667 assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive()));
668 assertEquals(i + 2, phaser.getPhase());
669 }
670 for (Thread thread : threads)
671 awaitTermination(thread);
672 }
673
674 /**
675 * awaitAdvance returns the current phase in child phasers
676 */
677 public void testAwaitAdvanceTieredPhaser() throws Exception {
678 final Phaser parent = new Phaser();
679 final List<Phaser> zeroPartyChildren = new ArrayList<Phaser>(3);
680 final List<Phaser> onePartyChildren = new ArrayList<Phaser>(3);
681 for (int i = 0; i < 3; i++) {
682 zeroPartyChildren.add(new Phaser(parent, 0));
683 onePartyChildren.add(new Phaser(parent, 1));
684 }
685 final List<Phaser> phasers = new ArrayList<Phaser>();
686 phasers.addAll(zeroPartyChildren);
687 phasers.addAll(onePartyChildren);
688 phasers.add(parent);
689 for (Phaser phaser : phasers) {
690 assertEquals(-42, phaser.awaitAdvance(-42));
691 assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000692 assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100693 }
694
695 for (Phaser child : onePartyChildren)
696 assertEquals(0, child.arrive());
697 for (Phaser phaser : phasers) {
698 assertEquals(-42, phaser.awaitAdvance(-42));
699 assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000700 assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100701 assertEquals(1, phaser.awaitAdvance(0));
702 assertEquals(1, phaser.awaitAdvanceInterruptibly(0));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000703 assertEquals(1, phaser.awaitAdvanceInterruptibly(0, MEDIUM_DELAY_MS, MILLISECONDS));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100704 }
705
706 for (Phaser child : onePartyChildren)
707 assertEquals(1, child.arrive());
708 for (Phaser phaser : phasers) {
709 assertEquals(-42, phaser.awaitAdvance(-42));
710 assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000711 assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100712 assertEquals(2, phaser.awaitAdvance(0));
713 assertEquals(2, phaser.awaitAdvanceInterruptibly(0));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000714 assertEquals(2, phaser.awaitAdvanceInterruptibly(0, MEDIUM_DELAY_MS, MILLISECONDS));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100715 assertEquals(2, phaser.awaitAdvance(1));
716 assertEquals(2, phaser.awaitAdvanceInterruptibly(1));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000717 assertEquals(2, phaser.awaitAdvanceInterruptibly(1, MEDIUM_DELAY_MS, MILLISECONDS));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100718 }
719 }
720
721 /**
722 * awaitAdvance returns when the phaser is externally terminated
723 */
724 public void testAwaitAdvance6() {
725 final Phaser phaser = new Phaser(3);
726 final CountDownLatch pleaseForceTermination = new CountDownLatch(2);
727 final List<Thread> threads = new ArrayList<Thread>();
728 for (int i = 0; i < 2; i++) {
729 Runnable r = new CheckedRunnable() {
730 public void realRun() {
731 assertEquals(0, phaser.arrive());
732 pleaseForceTermination.countDown();
733 assertTrue(phaser.awaitAdvance(0) < 0);
734 assertTrue(phaser.isTerminated());
735 assertTrue(phaser.getPhase() < 0);
736 assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
737 assertEquals(3, phaser.getRegisteredParties());
738 }};
739 threads.add(newStartedThread(r));
740 }
741 await(pleaseForceTermination);
742 phaser.forceTermination();
743 assertTrue(phaser.isTerminated());
744 assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
745 for (Thread thread : threads)
746 awaitTermination(thread);
747 assertEquals(3, phaser.getRegisteredParties());
748 }
749
750 /**
751 * arriveAndAwaitAdvance throws IllegalStateException with no
752 * unarrived parties
753 */
754 public void testArriveAndAwaitAdvance1() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000755 Phaser phaser = new Phaser();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100756 try {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100757 phaser.arriveAndAwaitAdvance();
758 shouldThrow();
759 } catch (IllegalStateException success) {}
760 }
761
762 /**
763 * arriveAndAwaitAdvance waits for all threads to arrive, the
764 * number of arrived parties is the same number that is accounted
765 * for when the main thread awaitsAdvance
766 */
767 public void testArriveAndAwaitAdvance3() {
768 final Phaser phaser = new Phaser(1);
769 final int THREADS = 3;
770 final CountDownLatch pleaseArrive = new CountDownLatch(THREADS);
771 final List<Thread> threads = new ArrayList<Thread>();
772 for (int i = 0; i < THREADS; i++)
773 threads.add(newStartedThread(new CheckedRunnable() {
774 public void realRun() {
775 assertEquals(0, phaser.register());
776 pleaseArrive.countDown();
777 assertEquals(1, phaser.arriveAndAwaitAdvance());
778 }}));
779
780 await(pleaseArrive);
781 long startTime = System.nanoTime();
782 while (phaser.getArrivedParties() < THREADS)
783 Thread.yield();
784 assertEquals(THREADS, phaser.getArrivedParties());
785 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
786 for (Thread thread : threads)
Tobias Thierercff661d2017-02-19 15:01:51 +0000787 waitForThreadToEnterWaitState(thread);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100788 for (Thread thread : threads)
789 assertTrue(thread.isAlive());
790 assertState(phaser, 0, THREADS + 1, 1);
791 phaser.arriveAndAwaitAdvance();
792 for (Thread thread : threads)
793 awaitTermination(thread);
794 assertState(phaser, 1, THREADS + 1, THREADS + 1);
795 }
796
797}