ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/PhaserTest.java
(Generate patch)

Comparing jsr166/src/test/tck/PhaserTest.java (file contents):
Revision 1.12 by dl, Wed Dec 2 10:50:48 2009 UTC vs.
Revision 1.38 by jsr166, Wed Dec 31 16:44:02 2014 UTC

# Line 1 | Line 1
1   /*
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/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   * Other contributors include John Vint
6   */
7  
8 + import junit.framework.*;
9   import java.util.ArrayList;
10   import java.util.List;
11 + import java.util.concurrent.Phaser;
12 + import java.util.concurrent.CountDownLatch;
13 + import java.util.concurrent.TimeoutException;
14 + import static java.util.concurrent.TimeUnit.MILLISECONDS;
15   import java.util.concurrent.atomic.AtomicInteger;
11 import java.util.concurrent.*;
12 import junit.framework.Test;
13 import junit.framework.TestSuite;
16  
17   public class PhaserTest extends JSR166TestCase {
18  
# Line 22 | Line 24 | public class PhaserTest extends JSR166Te
24          return new TestSuite(PhaserTest.class);
25      }
26  
27 +    private static final int maxParties = 65535;
28 +
29 +    /** Checks state of unterminated phaser. */
30 +    protected void assertState(Phaser phaser,
31 +                               int phase, int parties, int unarrived) {
32 +        assertEquals(phase, phaser.getPhase());
33 +        assertEquals(parties, phaser.getRegisteredParties());
34 +        assertEquals(unarrived, phaser.getUnarrivedParties());
35 +        assertEquals(parties - unarrived, phaser.getArrivedParties());
36 +        assertFalse(phaser.isTerminated());
37 +    }
38 +
39 +    /** Checks state of terminated phaser. */
40 +    protected void assertTerminated(Phaser phaser, int maxPhase, int parties) {
41 +        assertTrue(phaser.isTerminated());
42 +        int expectedPhase = maxPhase + Integer.MIN_VALUE;
43 +        assertEquals(expectedPhase, phaser.getPhase());
44 +        assertEquals(parties, phaser.getRegisteredParties());
45 +        assertEquals(expectedPhase, phaser.register());
46 +        assertEquals(expectedPhase, phaser.arrive());
47 +        assertEquals(expectedPhase, phaser.arriveAndDeregister());
48 +    }
49 +
50 +    protected void assertTerminated(Phaser phaser, int maxPhase) {
51 +        assertTerminated(phaser, maxPhase, 0);
52 +    }
53 +
54      /**
55       * Empty constructor builds a new Phaser with no parent, no registered
56       * parties and initial phase number of 0
57       */
58 <    public void testConstructor1() {
58 >    public void testConstructorDefaultValues() {
59          Phaser phaser = new Phaser();
60          assertNull(phaser.getParent());
61 +        assertEquals(0, phaser.getRegisteredParties());
62          assertEquals(0, phaser.getArrivedParties());
63 +        assertEquals(0, phaser.getUnarrivedParties());
64          assertEquals(0, phaser.getPhase());
65      }
66  
67      /**
68 <     * A negative party number for the constructor throws illegal argument
69 <     * exception
68 >     * Constructing with a negative number of parties throws
69 >     * IllegalArgumentException
70       */
71 <    public void testConstructor2() {
71 >    public void testConstructorNegativeParties() {
72          try {
73              new Phaser(-1);
74              shouldThrow();
# Line 45 | Line 76 | public class PhaserTest extends JSR166Te
76      }
77  
78      /**
79 <     * The parent being input into the constructor should equal the original
80 <     * parent when being returned
79 >     * Constructing with a negative number of parties throws
80 >     * IllegalArgumentException
81       */
82 <    public void testConstructor3() {
83 <        Phaser parent = new Phaser();
84 <        assertEquals(parent, new Phaser(parent).getParent());
82 >    public void testConstructorNegativeParties2() {
83 >        try {
84 >            new Phaser(new Phaser(), -1);
85 >            shouldThrow();
86 >        } catch (IllegalArgumentException success) {}
87      }
88  
89      /**
90 <     * A negative party number for the constructor throws illegal argument
91 <     * exception
90 >     * Constructing with a number of parties > 65535 throws
91 >     * IllegalArgumentException
92       */
93 <    public void testConstructor4() {
93 >    public void testConstructorPartiesExceedsLimit() {
94 >        new Phaser(maxParties);
95          try {
96 <            new Phaser(new Phaser(), -1);
96 >            new Phaser(maxParties + 1);
97 >            shouldThrow();
98 >        } catch (IllegalArgumentException success) {}
99 >
100 >        new Phaser(new Phaser(), maxParties);
101 >        try {
102 >            new Phaser(new Phaser(), maxParties + 1);
103              shouldThrow();
104          } catch (IllegalArgumentException success) {}
105      }
106  
107      /**
108 +     * The parent provided to the constructor should be returned from
109 +     * a later call to getParent
110 +     */
111 +    public void testConstructor3() {
112 +        Phaser parent = new Phaser();
113 +        assertSame(parent, new Phaser(parent).getParent());
114 +        assertNull(new Phaser(null).getParent());
115 +    }
116 +
117 +    /**
118       * The parent being input into the parameter should equal the original
119       * parent when being returned
120       */
121      public void testConstructor5() {
122          Phaser parent = new Phaser();
123 <        assertEquals(parent, new Phaser(parent, 0).getParent());
123 >        assertSame(parent, new Phaser(parent, 0).getParent());
124 >        assertNull(new Phaser(null, 0).getParent());
125      }
126  
127      /**
128 <     * register() will increment the number of unarrived parties by one and not
129 <     * affect its arrived parties
128 >     * register() will increment the number of unarrived parties by
129 >     * one and not affect its arrived parties
130       */
131      public void testRegister1() {
132          Phaser phaser = new Phaser();
133 <        assertEquals(0, phaser.getUnarrivedParties());
134 <        phaser.register();
135 <        assertEquals(1, phaser.getUnarrivedParties());
85 <        assertEquals(0, phaser.getArrivedParties());
133 >        assertState(phaser, 0, 0, 0);
134 >        assertEquals(0, phaser.register());
135 >        assertState(phaser, 0, 1, 1);
136      }
137  
138      /**
# Line 90 | Line 140 | public class PhaserTest extends JSR166Te
140       */
141      public void testRegister2() {
142          Phaser phaser = new Phaser(0);
143 <        int expectedUnnarivedParties = (1 << 16) - 1;
144 <        for (int i = 0; i < expectedUnnarivedParties; i++) {
145 <            phaser.register();
146 <            assertEquals(i + 1, phaser.getUnarrivedParties());
143 >        assertState(phaser, 0, 0, 0);
144 >        assertEquals(0, phaser.bulkRegister(maxParties - 10));
145 >        assertState(phaser, 0, maxParties - 10, maxParties - 10);
146 >        for (int i = 0; i < 10; i++) {
147 >            assertState(phaser, 0, maxParties - 10 + i, maxParties - 10 + i);
148 >            assertEquals(0, phaser.register());
149          }
150 +        assertState(phaser, 0, maxParties, maxParties);
151          try {
152              phaser.register();
153              shouldThrow();
154          } catch (IllegalStateException success) {}
155 +
156 +        try {
157 +            phaser.bulkRegister(Integer.MAX_VALUE);
158 +            shouldThrow();
159 +        } catch (IllegalStateException success) {}
160 +
161 +        assertEquals(0, phaser.bulkRegister(0));
162 +        assertState(phaser, 0, maxParties, maxParties);
163      }
164  
165      /**
166 <     * register() correctly returns the current barrier phase number when
167 <     * invoked
166 >     * register() correctly returns the current barrier phase number
167 >     * when invoked
168       */
169      public void testRegister3() {
170          Phaser phaser = new Phaser();
171          assertEquals(0, phaser.register());
172 <        phaser.arrive();
172 >        assertEquals(0, phaser.arrive());
173          assertEquals(1, phaser.register());
174 +        assertState(phaser, 1, 2, 2);
175      }
176  
177      /**
178 <     * register causes the next arrive to not increment the phase rather retain
179 <     * the phase number
178 >     * register causes the next arrive to not increment the phase
179 >     * rather retain the phase number
180       */
181      public void testRegister4() {
182          Phaser phaser = new Phaser(1);
183 <        phaser.arrive();
184 <        int expectedPhase = phaser.register();
185 <        phaser.arrive();
186 <        assertEquals(expectedPhase, phaser.getPhase());
183 >        assertEquals(0, phaser.arrive());
184 >        assertEquals(1, phaser.register());
185 >        assertEquals(1, phaser.arrive());
186 >        assertState(phaser, 1, 2, 1);
187      }
188  
189 <    public void testRegister5() {
190 <        Phaser phaser = new Phaser();
191 <        phaser.register();
192 <        assertEquals(1, phaser.getUnarrivedParties());
189 >    /**
190 >     * register on a subphaser that is currently empty succeeds, even
191 >     * in the presence of another non-empty subphaser
192 >     */
193 >    public void testRegisterEmptySubPhaser() {
194 >        Phaser root = new Phaser();
195 >        Phaser child1 = new Phaser(root, 1);
196 >        Phaser child2 = new Phaser(root, 0);
197 >        assertEquals(0, child2.register());
198 >        assertState(root, 0, 2, 2);
199 >        assertState(child1, 0, 1, 1);
200 >        assertState(child2, 0, 1, 1);
201 >        assertEquals(0, child2.arriveAndDeregister());
202 >        assertState(root, 0, 1, 1);
203 >        assertState(child1, 0, 1, 1);
204 >        assertState(child2, 0, 0, 0);
205 >        assertEquals(0, child2.register());
206 >        assertEquals(0, child2.arriveAndDeregister());
207 >        assertState(root, 0, 1, 1);
208 >        assertState(child1, 0, 1, 1);
209 >        assertState(child2, 0, 0, 0);
210 >        assertEquals(0, child1.arriveAndDeregister());
211 >        assertTerminated(root, 1);
212 >        assertTerminated(child1, 1);
213 >        assertTerminated(child2, 1);
214      }
215  
216      /**
# Line 142 | Line 225 | public class PhaserTest extends JSR166Te
225      }
226  
227      /**
228 <     * bulkRegister should correctly record the number of unarrived parties with
229 <     * the number of parties being registered
228 >     * bulkRegister should correctly record the number of unarrived
229 >     * parties with the number of parties being registered
230       */
231      public void testBulkRegister2() {
232          Phaser phaser = new Phaser();
233 <        phaser.bulkRegister(20);
234 <        assertEquals(20, phaser.getUnarrivedParties());
233 >        assertEquals(0, phaser.bulkRegister(0));
234 >        assertState(phaser, 0, 0, 0);
235 >        assertEquals(0, phaser.bulkRegister(20));
236 >        assertState(phaser, 0, 20, 20);
237      }
238  
239      /**
# Line 156 | Line 241 | public class PhaserTest extends JSR166Te
241       * throws IllegalStateException.
242       */
243      public void testBulkRegister3() {
244 +        assertEquals(0, new Phaser().bulkRegister((1 << 16) - 1));
245 +
246          try {
247              new Phaser().bulkRegister(1 << 16);
248              shouldThrow();
249          } catch (IllegalStateException success) {}
250 +
251 +        try {
252 +            new Phaser(2).bulkRegister((1 << 16) - 2);
253 +            shouldThrow();
254 +        } catch (IllegalStateException success) {}
255      }
256  
257      /**
# Line 176 | Line 268 | public class PhaserTest extends JSR166Te
268      }
269  
270      /**
271 <     *  Arrive() on a registered phaser increments phase.
271 >     * arrive() on a registered phaser increments phase.
272       */
273      public void testArrive1() {
274          Phaser phaser = new Phaser(1);
275 <        phaser.arrive();
276 <        assertEquals(1, phaser.getPhase());
275 >        assertState(phaser, 0, 1, 1);
276 >        assertEquals(0, phaser.arrive());
277 >        assertState(phaser, 1, 1, 1);
278      }
279  
280      /**
281       * arriveAndDeregister does not wait for others to arrive at barrier
282       */
283 <    public void testArrive2() throws InterruptedException {
283 >    public void testArriveAndDeregister() {
284          final Phaser phaser = new Phaser(1);
285 <        phaser.register();
285 >        for (int i = 0; i < 10; i++) {
286 >            assertState(phaser, 0, 1, 1);
287 >            assertEquals(0, phaser.register());
288 >            assertState(phaser, 0, 2, 2);
289 >            assertEquals(0, phaser.arriveAndDeregister());
290 >            assertState(phaser, 0, 1, 1);
291 >        }
292 >        assertEquals(0, phaser.arriveAndDeregister());
293 >        assertTerminated(phaser, 1);
294 >    }
295 >
296 >    /**
297 >     * arriveAndDeregister does not wait for others to arrive at barrier
298 >     */
299 >    public void testArrive2() {
300 >        final Phaser phaser = new Phaser();
301 >        assertEquals(0, phaser.register());
302          List<Thread> threads = new ArrayList<Thread>();
303 <        for (int i = 0; i < 10; i++)
304 <            phaser.register();
303 >        for (int i = 0; i < 10; i++) {
304 >            assertEquals(0, phaser.register());
305              threads.add(newStartedThread(new CheckedRunnable() {
306 <                public void realRun() throws InterruptedException {
307 <                    Thread.sleep(SMALL_DELAY_MS);
199 <                    phaser.arriveAndDeregister();
306 >                public void realRun() {
307 >                    assertEquals(0, phaser.arriveAndDeregister());
308                  }}));
309 +        }
310  
202        phaser.arrive();
203        assertTrue(threads.get(0).isAlive());
204        assertFalse(phaser.isTerminated());
311          for (Thread thread : threads)
312 <            thread.join();
312 >            awaitTermination(thread);
313 >        assertState(phaser, 0, 1, 1);
314 >        assertEquals(0, phaser.arrive());
315 >        assertState(phaser, 1, 1, 1);
316      }
317  
318      /**
# Line 212 | Line 321 | public class PhaserTest extends JSR166Te
321      public void testArrive3() {
322          Phaser phaser = new Phaser(1);
323          phaser.forceTermination();
324 +        assertTerminated(phaser, 0, 1);
325 +        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
326          assertTrue(phaser.arrive() < 0);
327 +        assertTrue(phaser.register() < 0);
328 +        assertTrue(phaser.arriveAndDeregister() < 0);
329 +        assertTrue(phaser.awaitAdvance(1) < 0);
330 +        assertTrue(phaser.getPhase() < 0);
331      }
332  
333      /**
# Line 228 | Line 343 | public class PhaserTest extends JSR166Te
343      }
344  
345      /**
346 <     * arriveAndDeregister deregisters reduces the number of arrived parties
346 >     * arriveAndDeregister reduces the number of arrived parties
347       */
348 <    public void testArriveAndDergeister2() {
348 >    public void testArriveAndDeregister2() {
349          final Phaser phaser = new Phaser(1);
350 <        phaser.register();
351 <        phaser.arrive();
352 <        int p = phaser.getArrivedParties();
353 <        assertTrue(p == 1);
354 <        phaser.arriveAndDeregister();
240 <        assertTrue(phaser.getArrivedParties() < p);
350 >        assertEquals(0, phaser.register());
351 >        assertEquals(0, phaser.arrive());
352 >        assertState(phaser, 0, 2, 1);
353 >        assertEquals(0, phaser.arriveAndDeregister());
354 >        assertState(phaser, 1, 1, 1);
355      }
356  
357      /**
358 <     * arriveAndDeregister arrives to the barrier on a phaser with a parent and
358 >     * arriveAndDeregister arrives at the barrier on a phaser with a parent and
359       * when a deregistration occurs and causes the phaser to have zero parties
360       * its parent will be deregistered as well
361       */
362 <    public void testArriveAndDeregsiter3() {
362 >    public void testArriveAndDeregister3() {
363          Phaser parent = new Phaser();
364 <        Phaser root = new Phaser(parent);
365 <        root.register();
366 <        assertTrue(parent.getUnarrivedParties() > 0);
367 <        assertTrue(root.getUnarrivedParties() > 0);
368 <        root.arriveAndDeregister();
369 <        assertTrue(parent.getUnarrivedParties() == 0);
370 <        assertTrue(root.getUnarrivedParties() == 0);
371 <        assertTrue(root.isTerminated() && parent.isTerminated());
364 >        Phaser child = new Phaser(parent);
365 >        assertState(child, 0, 0, 0);
366 >        assertState(parent, 0, 0, 0);
367 >        assertEquals(0, child.register());
368 >        assertState(child, 0, 1, 1);
369 >        assertState(parent, 0, 1, 1);
370 >        assertEquals(0, child.arriveAndDeregister());
371 >        assertTerminated(child, 1);
372 >        assertTerminated(parent, 1);
373      }
374  
375      /**
376       * arriveAndDeregister deregisters one party from its parent when
377 <     * the number of parties of root is zero after deregistration
377 >     * the number of parties of child is zero after deregistration
378       */
379 <    public void testArriveAndDeregsiter4() {
379 >    public void testArriveAndDeregister4() {
380          Phaser parent = new Phaser();
381 <        Phaser root = new Phaser(parent);
382 <        parent.register();
383 <        root.register();
384 <        int parentParties = parent.getUnarrivedParties();
385 <        root.arriveAndDeregister();
386 <        assertEquals(parentParties - 1, parent.getUnarrivedParties());
381 >        Phaser child = new Phaser(parent);
382 >        assertEquals(0, parent.register());
383 >        assertEquals(0, child.register());
384 >        assertState(child, 0, 1, 1);
385 >        assertState(parent, 0, 2, 2);
386 >        assertEquals(0, child.arriveAndDeregister());
387 >        assertState(child, 0, 0, 0);
388 >        assertState(parent, 0, 1, 1);
389      }
390  
391      /**
# Line 276 | Line 393 | public class PhaserTest extends JSR166Te
393       * the number of parties of root is nonzero after deregistration.
394       */
395      public void testArriveAndDeregister5() {
396 <        Phaser parent = new Phaser();
396 >        Phaser root = new Phaser();
397 >        Phaser parent = new Phaser(root);
398          Phaser child = new Phaser(parent);
399 <        Phaser root = new Phaser(child);
400 <        assertTrue(parent.getUnarrivedParties() > 0);
401 <        assertTrue(child.getUnarrivedParties() > 0);
402 <        root.register();
403 <        root.arriveAndDeregister();
404 <        assertTrue(parent.getUnarrivedParties() == 0);
405 <        assertTrue(child.getUnarrivedParties() == 0);
406 <        assertTrue(root.isTerminated());
399 >        assertState(root, 0, 0, 0);
400 >        assertState(parent, 0, 0, 0);
401 >        assertState(child, 0, 0, 0);
402 >        assertEquals(0, child.register());
403 >        assertState(root, 0, 1, 1);
404 >        assertState(parent, 0, 1, 1);
405 >        assertState(child, 0, 1, 1);
406 >        assertEquals(0, child.arriveAndDeregister());
407 >        assertTerminated(child, 1);
408 >        assertTerminated(parent, 1);
409 >        assertTerminated(root, 1);
410      }
411  
412      /**
413       * arriveAndDeregister returns the phase in which it leaves the
414       * phaser in after deregistration
415       */
416 <    public void testArriveAndDeregister6() throws InterruptedException {
416 >    public void testArriveAndDeregister6() {
417          final Phaser phaser = new Phaser(2);
418          Thread t = newStartedThread(new CheckedRunnable() {
419              public void realRun() {
420 <                sleepTillInterrupted(SHORT_DELAY_MS);
300 <                phaser.arrive();
420 >                assertEquals(0, phaser.arrive());
421              }});
422 <        phaser.arriveAndAwaitAdvance();
423 <        int phase = phaser.arriveAndDeregister();
424 <        assertEquals(phase, phaser.getPhase());
425 <        t.join();
422 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
423 >        assertState(phaser, 1, 2, 2);
424 >        assertEquals(1, phaser.arriveAndDeregister());
425 >        assertState(phaser, 1, 1, 1);
426 >        assertEquals(1, phaser.arriveAndDeregister());
427 >        assertTerminated(phaser, 2);
428 >        awaitTermination(t);
429      }
430  
431      /**
# Line 310 | Line 433 | public class PhaserTest extends JSR166Te
433       */
434      public void testAwaitAdvance1() {
435          final Phaser phaser = new Phaser(1);
436 <        phaser.awaitAdvance(phaser.arrive());
436 >        assertEquals(0, phaser.arrive());
437 >        assertEquals(1, phaser.awaitAdvance(0));
438      }
439  
440      /**
# Line 319 | Line 443 | public class PhaserTest extends JSR166Te
443       */
444      public void testAwaitAdvance2() {
445          Phaser phaser = new Phaser();
446 <        phaser.awaitAdvance(-1);
446 >        assertTrue(phaser.awaitAdvance(-1) < 0);
447 >        assertState(phaser, 0, 0, 0);
448 >    }
449 >
450 >    /**
451 >     * awaitAdvanceInterruptibly blocks interruptibly
452 >     */
453 >    public void testAwaitAdvanceInterruptibly_interruptible() throws InterruptedException {
454 >        final Phaser phaser = new Phaser(1);
455 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
456 >
457 >        Thread t1 = newStartedThread(new CheckedRunnable() {
458 >            public void realRun() {
459 >                Thread.currentThread().interrupt();
460 >                try {
461 >                    phaser.awaitAdvanceInterruptibly(0);
462 >                    shouldThrow();
463 >                } catch (InterruptedException success) {}
464 >                assertFalse(Thread.interrupted());
465 >
466 >                pleaseInterrupt.countDown();
467 >                try {
468 >                    phaser.awaitAdvanceInterruptibly(0);
469 >                    shouldThrow();
470 >                } catch (InterruptedException success) {}
471 >                assertFalse(Thread.interrupted());
472 >            }});
473 >
474 >        Thread t2 = newStartedThread(new CheckedRunnable() {
475 >            public void realRun() throws TimeoutException {
476 >                Thread.currentThread().interrupt();
477 >                try {
478 >                    phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
479 >                    shouldThrow();
480 >                } catch (InterruptedException success) {}
481 >                assertFalse(Thread.interrupted());
482 >
483 >                pleaseInterrupt.countDown();
484 >                try {
485 >                    phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
486 >                    shouldThrow();
487 >                } catch (InterruptedException success) {}
488 >                assertFalse(Thread.interrupted());
489 >            }});
490 >
491 >        await(pleaseInterrupt);
492 >        assertState(phaser, 0, 1, 1);
493 >        assertThreadsStayAlive(t1, t2);
494 >        t1.interrupt();
495 >        t2.interrupt();
496 >        awaitTermination(t1);
497 >        awaitTermination(t2);
498 >        assertState(phaser, 0, 1, 1);
499 >        assertEquals(0, phaser.arrive());
500 >        assertState(phaser, 1, 1, 1);
501      }
502  
503      /**
504 <     * awaitAdvance while waiting does not abort on interrupt.
504 >     * awaitAdvance continues waiting if interrupted before waiting
505       */
506 <    public void testAwaitAdvance3() throws InterruptedException {
506 >    public void testAwaitAdvanceAfterInterrupt() {
507          final Phaser phaser = new Phaser();
508 <        phaser.register();
508 >        assertEquals(0, phaser.register());
509 >        final CountDownLatch pleaseArrive = new CountDownLatch(1);
510  
511          Thread t = newStartedThread(new CheckedRunnable() {
512 <            public void realRun() throws InterruptedException {
513 <                phaser.register();
514 <                sleepTillInterrupted(LONG_DELAY_MS);
515 <                phaser.awaitAdvance(phaser.arrive());
512 >            public void realRun() {
513 >                Thread.currentThread().interrupt();
514 >                assertEquals(0, phaser.register());
515 >                assertEquals(0, phaser.arrive());
516 >                pleaseArrive.countDown();
517 >                assertTrue(Thread.currentThread().isInterrupted());
518 >                assertEquals(1, phaser.awaitAdvance(0));
519 >                assertTrue(Thread.interrupted());
520              }});
521 <        Thread.sleep(SMALL_DELAY_MS);
521 >
522 >        await(pleaseArrive);
523 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
524 >        assertEquals(0, phaser.arrive());
525 >        awaitTermination(t);
526 >
527 >        Thread.currentThread().interrupt();
528 >        assertEquals(1, phaser.awaitAdvance(0));
529 >        assertTrue(Thread.interrupted());
530 >    }
531 >
532 >    /**
533 >     *  awaitAdvance continues waiting if interrupted while waiting
534 >     */
535 >    public void testAwaitAdvanceBeforeInterrupt() {
536 >        final Phaser phaser = new Phaser();
537 >        assertEquals(0, phaser.register());
538 >        final CountDownLatch pleaseArrive = new CountDownLatch(1);
539 >
540 >        Thread t = newStartedThread(new CheckedRunnable() {
541 >            public void realRun() {
542 >                assertEquals(0, phaser.register());
543 >                assertEquals(0, phaser.arrive());
544 >                assertFalse(Thread.currentThread().isInterrupted());
545 >                pleaseArrive.countDown();
546 >                assertEquals(1, phaser.awaitAdvance(0));
547 >                assertTrue(Thread.interrupted());
548 >            }});
549 >
550 >        await(pleaseArrive);
551 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
552          t.interrupt();
553 <        Thread.sleep(SMALL_DELAY_MS);
554 <        phaser.arrive();
555 <        assertFalse(t.isInterrupted());
556 <        t.join();
553 >        assertEquals(0, phaser.arrive());
554 >        awaitTermination(t);
555 >
556 >        Thread.currentThread().interrupt();
557 >        assertEquals(1, phaser.awaitAdvance(0));
558 >        assertTrue(Thread.interrupted());
559 >    }
560 >
561 >    /**
562 >     * arriveAndAwaitAdvance continues waiting if interrupted before waiting
563 >     */
564 >    public void testArriveAndAwaitAdvanceAfterInterrupt() {
565 >        final Phaser phaser = new Phaser();
566 >        assertEquals(0, phaser.register());
567 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
568 >
569 >        Thread t = newStartedThread(new CheckedRunnable() {
570 >            public void realRun() {
571 >                Thread.currentThread().interrupt();
572 >                assertEquals(0, phaser.register());
573 >                pleaseInterrupt.countDown();
574 >                assertTrue(Thread.currentThread().isInterrupted());
575 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
576 >                assertTrue(Thread.currentThread().isInterrupted());
577 >            }});
578 >
579 >        await(pleaseInterrupt);
580 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
581 >        Thread.currentThread().interrupt();
582 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
583 >        assertTrue(Thread.interrupted());
584 >        awaitTermination(t);
585 >    }
586 >
587 >    /**
588 >     * arriveAndAwaitAdvance continues waiting if interrupted while waiting
589 >     */
590 >    public void testArriveAndAwaitAdvanceBeforeInterrupt() {
591 >        final Phaser phaser = new Phaser();
592 >        assertEquals(0, phaser.register());
593 >        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
594 >
595 >        Thread t = newStartedThread(new CheckedRunnable() {
596 >            public void realRun() {
597 >                assertEquals(0, phaser.register());
598 >                assertFalse(Thread.currentThread().isInterrupted());
599 >                pleaseInterrupt.countDown();
600 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
601 >                assertTrue(Thread.currentThread().isInterrupted());
602 >            }});
603 >
604 >        await(pleaseInterrupt);
605 >        waitForThreadToEnterWaitState(t, SHORT_DELAY_MS);
606 >        t.interrupt();
607 >        Thread.currentThread().interrupt();
608 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
609 >        assertTrue(Thread.interrupted());
610 >        awaitTermination(t);
611      }
612  
613      /**
614       * awaitAdvance atomically waits for all parties within the same phase to
615       * complete before continuing
616       */
617 <    public void testAwaitAdvance4() throws InterruptedException {
617 >    public void testAwaitAdvance4() {
618          final Phaser phaser = new Phaser(4);
619 <        final AtomicInteger phaseCount = new AtomicInteger(0);
619 >        final AtomicInteger count = new AtomicInteger(0);
620          List<Thread> threads = new ArrayList<Thread>();
621 <        for (int i = 0; i < 4; i++) {
621 >        for (int i = 0; i < 4; i++)
622              threads.add(newStartedThread(new CheckedRunnable() {
623                  public void realRun() {
624 <                    int phase = phaser.arrive();
625 <                    phaseCount.incrementAndGet();
626 <                    sleepTillInterrupted(SMALL_DELAY_MS);
627 <                    phaser.awaitAdvance(phase);
628 <                    assertEquals(phaseCount.get(), 4);
629 <                }}));
630 <        }
624 >                    for (int k = 0; k < 3; k++) {
625 >                        assertEquals(2*k+1, phaser.arriveAndAwaitAdvance());
626 >                        count.incrementAndGet();
627 >                        assertEquals(2*k+1, phaser.arrive());
628 >                        assertEquals(2*k+2, phaser.awaitAdvance(2*k+1));
629 >                        assertEquals(4*(k+1), count.get());
630 >                    }}}));
631 >
632          for (Thread thread : threads)
633 <            thread.join();
633 >            awaitTermination(thread);
634      }
635  
636      /**
637       * awaitAdvance returns the current phase
638       */
639 <    public void testAwaitAdvance5() throws InterruptedException {
639 >    public void testAwaitAdvance5() {
640          final Phaser phaser = new Phaser(1);
641 <        int phase = phaser.awaitAdvance(phaser.arrive());
642 <        assertEquals(phase, phaser.getPhase());
643 <        phaser.register();
641 >        assertEquals(1, phaser.awaitAdvance(phaser.arrive()));
642 >        assertEquals(1, phaser.getPhase());
643 >        assertEquals(1, phaser.register());
644          List<Thread> threads = new ArrayList<Thread>();
645          for (int i = 0; i < 8; i++) {
646 +            final CountDownLatch latch = new CountDownLatch(1);
647 +            final boolean goesFirst = ((i & 1) == 0);
648              threads.add(newStartedThread(new CheckedRunnable() {
649                  public void realRun() {
650 <                    sleepTillInterrupted(SHORT_DELAY_MS);
650 >                    if (goesFirst)
651 >                        latch.countDown();
652 >                    else
653 >                        await(latch);
654                      phaser.arrive();
655                  }}));
656 <            phase = phaser.awaitAdvance(phaser.arrive());
657 <            assertEquals(phase, phaser.getPhase());
656 >            if (goesFirst)
657 >                await(latch);
658 >            else
659 >                latch.countDown();
660 >            assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive()));
661 >            assertEquals(i + 2, phaser.getPhase());
662          }
663          for (Thread thread : threads)
664 <            thread.join();
664 >            awaitTermination(thread);
665 >    }
666 >
667 >    /**
668 >     * awaitAdvance returns the current phase in child phasers
669 >     */
670 >    public void testAwaitAdvanceTieredPhaser() throws Exception {
671 >        final Phaser parent = new Phaser();
672 >        final List<Phaser> zeroPartyChildren = new ArrayList<Phaser>(3);
673 >        final List<Phaser> onePartyChildren = new ArrayList<Phaser>(3);
674 >        for (int i = 0; i < 3; i++) {
675 >            zeroPartyChildren.add(new Phaser(parent, 0));
676 >            onePartyChildren.add(new Phaser(parent, 1));
677 >        }
678 >        final List<Phaser> phasers = new ArrayList<Phaser>();
679 >        phasers.addAll(zeroPartyChildren);
680 >        phasers.addAll(onePartyChildren);
681 >        phasers.add(parent);
682 >        for (Phaser phaser : phasers) {
683 >            assertEquals(-42, phaser.awaitAdvance(-42));
684 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
685 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
686 >        }
687 >
688 >        for (Phaser child : onePartyChildren)
689 >            assertEquals(0, child.arrive());
690 >        for (Phaser phaser : phasers) {
691 >            assertEquals(-42, phaser.awaitAdvance(-42));
692 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
693 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
694 >            assertEquals(1, phaser.awaitAdvance(0));
695 >            assertEquals(1, phaser.awaitAdvanceInterruptibly(0));
696 >            assertEquals(1, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
697 >        }
698 >
699 >        for (Phaser child : onePartyChildren)
700 >            assertEquals(1, child.arrive());
701 >        for (Phaser phaser : phasers) {
702 >            assertEquals(-42, phaser.awaitAdvance(-42));
703 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
704 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
705 >            assertEquals(2, phaser.awaitAdvance(0));
706 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(0));
707 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
708 >            assertEquals(2, phaser.awaitAdvance(1));
709 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(1));
710 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(1, SMALL_DELAY_MS, MILLISECONDS));
711 >        }
712      }
713  
714      /**
715       * awaitAdvance returns when the phaser is externally terminated
716       */
717 <    public void testAwaitAdvance6() throws InterruptedException {
717 >    public void testAwaitAdvance6() {
718          final Phaser phaser = new Phaser(3);
719 <        /*
720 <         * Start new thread. This thread waits a small amount of time
721 <         * and waits for the other two parties to arrive.  The party
722 <         * in the main thread arrives quickly so at best this thread
723 <         * waits for the second thread's party to arrive
724 <         */
725 <        Thread t1 = newStartedThread(new CheckedRunnable() {
726 <            public void realRun() {
727 <                sleepTillInterrupted(SMALL_DELAY_MS);
728 <                int phase = phaser.awaitAdvance(phaser.arrive());
729 <                /*
730 <                 * This point is reached when force termination is called in which phase = -1
731 <                 */
732 <                assertTrue(phase < 0);
733 <                assertTrue(phaser.isTerminated());
734 <            }});
411 <        /*
412 <         * This thread will cause the first thread run to wait, in doing so
413 <         * the main thread will force termination in which the first thread
414 <         * should exit peacefully as this one
415 <         */
416 <        Thread t2 = newStartedThread(new CheckedRunnable() {
417 <            public void realRun() {
418 <                sleepTillInterrupted(MEDIUM_DELAY_MS);
419 <                int p1 = phaser.arrive();
420 <                int phase = phaser.awaitAdvance(p1);
421 <                assertTrue(phase < 0);
422 <                assertTrue(phaser.isTerminated());
423 <            }});
424 <
425 <        phaser.arrive();
719 >        final CountDownLatch pleaseForceTermination = new CountDownLatch(2);
720 >        final List<Thread> threads = new ArrayList<Thread>();
721 >        for (int i = 0; i < 2; i++) {
722 >            Runnable r = new CheckedRunnable() {
723 >                public void realRun() {
724 >                    assertEquals(0, phaser.arrive());
725 >                    pleaseForceTermination.countDown();
726 >                    assertTrue(phaser.awaitAdvance(0) < 0);
727 >                    assertTrue(phaser.isTerminated());
728 >                    assertTrue(phaser.getPhase() < 0);
729 >                    assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
730 >                    assertEquals(3, phaser.getRegisteredParties());
731 >                }};
732 >            threads.add(newStartedThread(r));
733 >        }
734 >        await(pleaseForceTermination);
735          phaser.forceTermination();
736 <        t1.join();
737 <        t2.join();
736 >        assertTrue(phaser.isTerminated());
737 >        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
738 >        for (Thread thread : threads)
739 >            awaitTermination(thread);
740 >        assertEquals(3, phaser.getRegisteredParties());
741      }
742  
743      /**
# Line 441 | Line 753 | public class PhaserTest extends JSR166Te
753      }
754  
755      /**
444     * Interrupted arriveAndAwaitAdvance does not throw InterruptedException
445     */
446    public void testArriveAndAwaitAdvance2() throws InterruptedException {
447        final Phaser phaser = new Phaser(2);
448        Thread th = newStartedThread(new CheckedRunnable() {
449            public void realRun() {
450                phaser.arriveAndAwaitAdvance();
451            }});
452
453        Thread.sleep(SMALL_DELAY_MS);
454        th.interrupt();
455        Thread.sleep(SMALL_DELAY_MS);
456        phaser.arrive();
457        assertFalse(th.isInterrupted());
458        th.join();
459    }
460
461    /**
756       * arriveAndAwaitAdvance waits for all threads to arrive, the
757       * number of arrived parties is the same number that is accounted
758       * for when the main thread awaitsAdvance
759       */
760 <    public void testArriveAndAwaitAdvance3() throws InterruptedException {
760 >    public void testArriveAndAwaitAdvance3() {
761          final Phaser phaser = new Phaser(1);
762 +        final int THREADS = 3;
763 +        final CountDownLatch pleaseArrive = new CountDownLatch(THREADS);
764          final List<Thread> threads = new ArrayList<Thread>();
765 <        for (int i = 0; i < 3; i++) {
765 >        for (int i = 0; i < THREADS; i++)
766              threads.add(newStartedThread(new CheckedRunnable() {
767 <                    public void realRun() throws InterruptedException {
768 <                        phaser.register();
769 <                        phaser.arriveAndAwaitAdvance();
770 <                    }}));
771 <        }
772 <        Thread.sleep(LONG_DELAY_MS);
773 <        assertEquals(phaser.getArrivedParties(), 3);
767 >                public void realRun() {
768 >                    assertEquals(0, phaser.register());
769 >                    pleaseArrive.countDown();
770 >                    assertEquals(1, phaser.arriveAndAwaitAdvance());
771 >                }}));
772 >
773 >        await(pleaseArrive);
774 >        long startTime = System.nanoTime();
775 >        while (phaser.getArrivedParties() < THREADS)
776 >            Thread.yield();
777 >        assertEquals(THREADS, phaser.getArrivedParties());
778 >        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
779 >        for (Thread thread : threads)
780 >            waitForThreadToEnterWaitState(thread, SHORT_DELAY_MS);
781 >        for (Thread thread : threads)
782 >            assertTrue(thread.isAlive());
783 >        assertState(phaser, 0, THREADS + 1, 1);
784          phaser.arriveAndAwaitAdvance();
785          for (Thread thread : threads)
786 <            thread.join();
786 >            awaitTermination(thread);
787 >        assertState(phaser, 1, THREADS + 1, THREADS + 1);
788      }
789  
790   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines