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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines