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.5 by jsr166, Mon Aug 3 20:33:57 2009 UTC vs.
Revision 1.30 by jsr166, Mon Dec 13 07:44:16 2010 UTC

# Line 8 | Line 8
8   import java.util.ArrayList;
9   import java.util.List;
10   import java.util.concurrent.atomic.AtomicInteger;
11 + import java.util.concurrent.atomic.AtomicBoolean;
12   import java.util.concurrent.*;
13 + import static java.util.concurrent.TimeUnit.MILLISECONDS;
14 + import static java.util.concurrent.TimeUnit.NANOSECONDS;
15   import junit.framework.Test;
16   import junit.framework.TestSuite;
17  
# Line 22 | Line 25 | public class PhaserTest extends JSR166Te
25          return new TestSuite(PhaserTest.class);
26      }
27  
28 +    private static final int maxParties = 65535;
29 +
30 +    /** Checks state of unterminated phaser. */
31 +    protected void assertState(Phaser phaser,
32 +                               int phase, int parties, int unarrived) {
33 +        assertEquals(phase, phaser.getPhase());
34 +        assertEquals(parties, phaser.getRegisteredParties());
35 +        assertEquals(unarrived, phaser.getUnarrivedParties());
36 +        assertEquals(parties - unarrived, phaser.getArrivedParties());
37 +        assertFalse(phaser.isTerminated());
38 +    }
39 +
40 +    /** Checks state of terminated phaser. */
41 +    protected void assertTerminated(Phaser phaser, int maxPhase, int parties) {
42 +        assertTrue(phaser.isTerminated());
43 +        int expectedPhase = maxPhase + Integer.MIN_VALUE;
44 +        assertEquals(expectedPhase, phaser.getPhase());
45 +        assertEquals(parties, phaser.getRegisteredParties());
46 +        assertEquals(expectedPhase, phaser.register());
47 +        assertEquals(expectedPhase, phaser.arrive());
48 +        assertEquals(expectedPhase, phaser.arriveAndDeregister());
49 +    }
50 +
51 +    protected void assertTerminated(Phaser phaser, int maxPhase) {
52 +        assertTerminated(phaser, maxPhase, 0);
53 +    }
54 +
55      /**
56       * Empty constructor builds a new Phaser with no parent, no registered
57       * parties and initial phase number of 0
58       */
59 <    public void testConstructor1() {
59 >    public void testConstructorDefaultValues() {
60          Phaser phaser = new Phaser();
61          assertNull(phaser.getParent());
62 +        assertEquals(0, phaser.getRegisteredParties());
63          assertEquals(0, phaser.getArrivedParties());
64 +        assertEquals(0, phaser.getUnarrivedParties());
65          assertEquals(0, phaser.getPhase());
66      }
67  
68      /**
69 <     * A negative party number for the constructor throws illegal argument
70 <     * exception
69 >     * Constructing with a negative number of parties throws
70 >     * IllegalArgumentException
71       */
72 <    public void testConstructor2() {
72 >    public void testConstructorNegativeParties() {
73          try {
74              new Phaser(-1);
75 <            this.shouldThrow();
76 <        } catch (IllegalArgumentException success) {
45 <        }
75 >            shouldThrow();
76 >        } catch (IllegalArgumentException success) {}
77      }
78  
79      /**
80 <     * The parent being input into the constructor should equal the original
81 <     * parent when being returned
80 >     * Constructing with a negative number of parties throws
81 >     * IllegalArgumentException
82       */
83 <    public void testConstructor3() {
84 <        Phaser parent = new Phaser();
85 <        assertEquals(parent, new Phaser(parent).getParent());
83 >    public void testConstructorNegativeParties2() {
84 >        try {
85 >            new Phaser(new Phaser(), -1);
86 >            shouldThrow();
87 >        } catch (IllegalArgumentException success) {}
88      }
89  
90      /**
91 <     * A negative party number for the constructor throws illegal argument
92 <     * exception
91 >     * Constructing with a number of parties > 65535 throws
92 >     * IllegalArgumentException
93       */
94 <    public void testConstructor4() {
94 >    public void testConstructorPartiesExceedsLimit() {
95 >        new Phaser(maxParties);
96          try {
97 <            new Phaser(new Phaser(), -1);
97 >            new Phaser(maxParties + 1);
98              shouldThrow();
99 <        } catch (IllegalArgumentException success) {
100 <        }
99 >        } catch (IllegalArgumentException success) {}
100 >
101 >        new Phaser(new Phaser(), maxParties);
102 >        try {
103 >            new Phaser(new Phaser(), maxParties + 1);
104 >            shouldThrow();
105 >        } catch (IllegalArgumentException success) {}
106 >    }
107 >
108 >    /**
109 >     * The parent provided to the constructor should be returned from
110 >     * a later call to getParent
111 >     */
112 >    public void testConstructor3() {
113 >        Phaser parent = new Phaser();
114 >        assertSame(parent, new Phaser(parent).getParent());
115 >        assertNull(new Phaser(null).getParent());
116      }
117  
118      /**
# Line 72 | Line 121 | public class PhaserTest extends JSR166Te
121       */
122      public void testConstructor5() {
123          Phaser parent = new Phaser();
124 <        assertEquals(parent, new Phaser(parent, 0).getParent());
124 >        assertSame(parent, new Phaser(parent, 0).getParent());
125 >        assertNull(new Phaser(null, 0).getParent());
126      }
127  
128      /**
129 <     * register() will increment the number of unarrived parties by one and not
130 <     * affect its arrived parties
129 >     * register() will increment the number of unarrived parties by
130 >     * one and not affect its arrived parties
131       */
132      public void testRegister1() {
133          Phaser phaser = new Phaser();
134 <        assertEquals(0, phaser.getUnarrivedParties());
135 <        phaser.register();
136 <        assertEquals(1, phaser.getUnarrivedParties());
87 <        assertEquals(0, phaser.getArrivedParties());
134 >        assertState(phaser, 0, 0, 0);
135 >        assertEquals(0, phaser.register());
136 >        assertState(phaser, 0, 1, 1);
137      }
138  
139      /**
# Line 92 | Line 141 | public class PhaserTest extends JSR166Te
141       */
142      public void testRegister2() {
143          Phaser phaser = new Phaser(0);
144 <        int expectedUnnarivedParties = (1 << 16) - 1;
145 <        for (int i = 0; i < expectedUnnarivedParties; i++) {
146 <            phaser.register();
147 <            assertEquals(i + 1, phaser.getUnarrivedParties());
144 >        assertState(phaser, 0, 0, 0);
145 >        assertEquals(0, phaser.bulkRegister(maxParties - 10));
146 >        assertState(phaser, 0, maxParties - 10, maxParties - 10);
147 >        for (int i = 0; i < 10; i++) {
148 >            assertState(phaser, 0, maxParties - 10 + i, maxParties - 10 + i);
149 >            assertEquals(0, phaser.register());
150          }
151 +        assertState(phaser, 0, maxParties, maxParties);
152          try {
153              phaser.register();
154              shouldThrow();
155 <        } catch (IllegalStateException success) {
156 <        }
155 >        } catch (IllegalStateException success) {}
156 >
157 >        try {
158 >            phaser.bulkRegister(Integer.MAX_VALUE);
159 >            shouldThrow();
160 >        } catch (IllegalStateException success) {}
161 >
162 >        assertEquals(0, phaser.bulkRegister(0));
163 >        assertState(phaser, 0, maxParties, maxParties);
164      }
165  
166      /**
# Line 111 | Line 170 | public class PhaserTest extends JSR166Te
170      public void testRegister3() {
171          Phaser phaser = new Phaser();
172          assertEquals(0, phaser.register());
173 <        phaser.arrive();
173 >        assertEquals(0, phaser.arrive());
174          assertEquals(1, phaser.register());
175 +        assertState(phaser, 1, 2, 2);
176      }
177  
178      /**
# Line 121 | Line 181 | public class PhaserTest extends JSR166Te
181       */
182      public void testRegister4() {
183          Phaser phaser = new Phaser(1);
184 <        phaser.arrive();
185 <        int expectedPhase = phaser.register();
186 <        phaser.arrive();
187 <        assertEquals(expectedPhase, phaser.getPhase());
128 <    }
129 <
130 <    public void testRegister5() {
131 <        Phaser phaser = new Phaser();
132 <        phaser.register();
133 <        assertEquals(1, phaser.getUnarrivedParties());
184 >        assertEquals(0, phaser.arrive());
185 >        assertEquals(1, phaser.register());
186 >        assertEquals(1, phaser.arrive());
187 >        assertState(phaser, 1, 2, 1);
188      }
189  
190      /**
# Line 141 | Line 195 | public class PhaserTest extends JSR166Te
195          try {
196              new Phaser().bulkRegister(-1);
197              shouldThrow();
198 <        } catch (IllegalArgumentException success) {
145 <        }
198 >        } catch (IllegalArgumentException success) {}
199      }
200  
201      /**
# Line 151 | Line 204 | public class PhaserTest extends JSR166Te
204       */
205      public void testBulkRegister2() {
206          Phaser phaser = new Phaser();
207 <        phaser.bulkRegister(20);
208 <        assertEquals(20, phaser.getUnarrivedParties());
207 >        assertEquals(0, phaser.bulkRegister(0));
208 >        assertState(phaser, 0, 0, 0);
209 >        assertEquals(0, phaser.bulkRegister(20));
210 >        assertState(phaser, 0, 20, 20);
211      }
212  
213      /**
# Line 160 | Line 215 | public class PhaserTest extends JSR166Te
215       * throws IllegalStateException.
216       */
217      public void testBulkRegister3() {
218 +        assertEquals(0, new Phaser().bulkRegister((1 << 16) - 1));
219 +
220          try {
221              new Phaser().bulkRegister(1 << 16);
222              shouldThrow();
223 <        } catch (IllegalStateException success) {
224 <        }
223 >        } catch (IllegalStateException success) {}
224 >
225 >        try {
226 >            new Phaser(2).bulkRegister((1 << 16) - 2);
227 >            shouldThrow();
228 >        } catch (IllegalStateException success) {}
229      }
230  
231      /**
# Line 181 | Line 242 | public class PhaserTest extends JSR166Te
242      }
243  
244      /**
245 <     *  Arrive() on a registered phaser increments phase.
245 >     * arrive() on a registered phaser increments phase.
246       */
247      public void testArrive1() {
248          Phaser phaser = new Phaser(1);
249 <        phaser.arrive();
250 <        assertEquals(1, phaser.getPhase());
249 >        assertState(phaser, 0, 1, 1);
250 >        assertEquals(0, phaser.arrive());
251 >        assertState(phaser, 1, 1, 1);
252      }
253  
254      /**
255 <     * arrive does not wait for others to arrive at barrier
255 >     * arriveAndDeregister does not wait for others to arrive at barrier
256       */
257 <    public void testArrive2() {
257 >    public void testArriveAndDeregister() throws InterruptedException {
258          final Phaser phaser = new Phaser(1);
259 <        phaser.register();
260 <        Thread thread = null;
261 <        for (final Runnable r : getRunnables(10, SHORT_DELAY_MS)) {
262 <            phaser.register();
263 <            thread = new Thread(new CheckedRunnable() {
264 <                void realRun() {
203 <                    r.run();
204 <                    phaser.arriveAndDeregister();
205 <                }});
206 <            thread.start();
259 >        for (int i = 0; i < 10; i++) {
260 >            assertState(phaser, 0, 1, 1);
261 >            assertEquals(0, phaser.register());
262 >            assertState(phaser, 0, 2, 2);
263 >            assertEquals(0, phaser.arriveAndDeregister());
264 >            assertState(phaser, 0, 1, 1);
265          }
266 +        assertEquals(0, phaser.arriveAndDeregister());
267 +        assertTerminated(phaser, 1);
268 +    }
269  
270 <        phaser.arrive();
271 <        assertTrue(thread.isAlive());
272 <        assertFalse(phaser.isTerminated());
270 >    /**
271 >     * arriveAndDeregister does not wait for others to arrive at barrier
272 >     */
273 >    public void testArrive2() throws InterruptedException {
274 >        final Phaser phaser = new Phaser();
275 >        assertEquals(0, phaser.register());
276 >        List<Thread> threads = new ArrayList<Thread>();
277 >        for (int i = 0; i < 10; i++) {
278 >            assertEquals(0, phaser.register());
279 >            threads.add(newStartedThread(new CheckedRunnable() {
280 >                public void realRun() throws InterruptedException {
281 >                    assertEquals(0, phaser.arriveAndDeregister());
282 >                }}));
283 >        }
284 >
285 >        for (Thread thread : threads)
286 >            awaitTermination(thread, LONG_DELAY_MS);
287 >        assertState(phaser, 0, 1, 1);
288 >        assertEquals(0, phaser.arrive());
289 >        assertState(phaser, 1, 1, 1);
290      }
291  
292      /**
# Line 217 | Line 295 | public class PhaserTest extends JSR166Te
295      public void testArrive3() {
296          Phaser phaser = new Phaser(1);
297          phaser.forceTermination();
298 +        assertTerminated(phaser, 0, 1);
299 +        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
300          assertTrue(phaser.arrive() < 0);
301 <
301 >        assertTrue(phaser.register() < 0);
302 >        assertTrue(phaser.arriveAndDeregister() < 0);
303 >        assertTrue(phaser.awaitAdvance(1) < 0);
304 >        assertTrue(phaser.getPhase() < 0);
305      }
306  
307      /**
# Line 230 | Line 313 | public class PhaserTest extends JSR166Te
313              Phaser phaser = new Phaser();
314              phaser.arriveAndDeregister();
315              shouldThrow();
316 <
234 <        } catch (IllegalStateException success) {
235 <        }
316 >        } catch (IllegalStateException success) {}
317      }
318  
319      /**
320 <     * arriveAndDeregister deregisters reduces the number of arrived parties
320 >     * arriveAndDeregister reduces the number of arrived parties
321       */
322 <    public void testArriveAndDergeister2() {
322 >    public void testArriveAndDeregister2() {
323          final Phaser phaser = new Phaser(1);
324 <        phaser.register();
325 <        phaser.arrive();
326 <        int p = phaser.getArrivedParties();
327 <        assertTrue(p == 1);
328 <        phaser.arriveAndDeregister();
248 <        assertTrue(phaser.getArrivedParties() < p);
324 >        assertEquals(0, phaser.register());
325 >        assertEquals(0, phaser.arrive());
326 >        assertState(phaser, 0, 2, 1);
327 >        assertEquals(0, phaser.arriveAndDeregister());
328 >        assertState(phaser, 1, 1, 1);
329      }
330  
331      /**
332 <     * arriveAndDeregister arrives to the barrier on a phaser with a parent and
332 >     * arriveAndDeregister arrives at the barrier on a phaser with a parent and
333       * when a deregistration occurs and causes the phaser to have zero parties
334       * its parent will be deregistered as well
335       */
336 <    public void testArriveAndDeregsiter3() {
336 >    public void testArriveAndDeregister3() {
337          Phaser parent = new Phaser();
338 <        Phaser root = new Phaser(parent);
339 <        root.register();
340 <        assertTrue(parent.getUnarrivedParties() > 0);
341 <        assertTrue(root.getUnarrivedParties() > 0);
342 <        root.arriveAndDeregister();
343 <        assertTrue(parent.getUnarrivedParties() == 0);
344 <        assertTrue(root.getUnarrivedParties() == 0);
345 <        assertTrue(root.isTerminated() && parent.isTerminated());
338 >        Phaser child = new Phaser(parent);
339 >        assertState(child, 0, 0, 0);
340 >        assertState(parent, 0, 0, 0);
341 >        assertEquals(0, child.register());
342 >        assertState(child, 0, 1, 1);
343 >        assertState(parent, 0, 1, 1);
344 >        assertEquals(0, child.arriveAndDeregister());
345 >        assertTerminated(child, 1);
346 >        assertTerminated(parent, 1);
347      }
348  
349      /**
350       * arriveAndDeregister deregisters one party from its parent when
351 <     * the number of parties of root is zero after deregistration
351 >     * the number of parties of child is zero after deregistration
352       */
353 <    public void testArriveAndDeregsiter4() {
353 >    public void testArriveAndDeregister4() {
354          Phaser parent = new Phaser();
355 <        Phaser root = new Phaser(parent);
356 <        parent.register();
357 <        root.register();
358 <        int parentParties = parent.getUnarrivedParties();
359 <        root.arriveAndDeregister();
360 <        assertEquals(parentParties - 1, parent.getUnarrivedParties());
355 >        Phaser child = new Phaser(parent);
356 >        assertEquals(0, parent.register());
357 >        assertEquals(0, child.register());
358 >        assertState(child, 0, 1, 1);
359 >        assertState(parent, 0, 2, 2);
360 >        assertEquals(0, child.arriveAndDeregister());
361 >        assertState(child, 0, 0, 0);
362 >        assertState(parent, 0, 1, 1);
363      }
364  
365      /**
# Line 284 | Line 367 | public class PhaserTest extends JSR166Te
367       * the number of parties of root is nonzero after deregistration.
368       */
369      public void testArriveAndDeregister5() {
370 <        Phaser parent = new Phaser();
370 >        Phaser root = new Phaser();
371 >        Phaser parent = new Phaser(root);
372          Phaser child = new Phaser(parent);
373 <        Phaser root = new Phaser(child);
374 <        assertTrue(parent.getUnarrivedParties() > 0);
375 <        assertTrue(child.getUnarrivedParties() > 0);
376 <        root.register();
377 <        root.arriveAndDeregister();
378 <        assertTrue(parent.getUnarrivedParties() == 0);
379 <        assertTrue(child.getUnarrivedParties() == 0);
380 <        assertTrue(root.isTerminated());
373 >        assertState(root, 0, 0, 0);
374 >        assertState(parent, 0, 0, 0);
375 >        assertState(child, 0, 0, 0);
376 >        assertEquals(0, child.register());
377 >        assertState(root, 0, 1, 1);
378 >        assertState(parent, 0, 1, 1);
379 >        assertState(child, 0, 1, 1);
380 >        assertEquals(0, child.arriveAndDeregister());
381 >        assertTerminated(child, 1);
382 >        assertTerminated(parent, 1);
383 >        assertTerminated(root, 1);
384      }
385  
386      /**
387       * arriveAndDeregister returns the phase in which it leaves the
388       * phaser in after deregistration
389       */
390 <    public void testArriveAndDeregister6() {
390 >    public void testArriveAndDeregister6() throws InterruptedException {
391          final Phaser phaser = new Phaser(2);
392 <        new Thread(new CheckedRunnable() {
393 <            void realRun() {
394 <                getRunnable(SHORT_DELAY_MS).run();
395 <                phaser.arrive();
396 <            }}).start();
397 <        phaser.arriveAndAwaitAdvance();
398 <        int phase = phaser.arriveAndDeregister();
399 <        assertEquals(phase, phaser.getPhase());
392 >        Thread t = newStartedThread(new CheckedRunnable() {
393 >            public void realRun() {
394 >                assertEquals(0, phaser.arrive());
395 >            }});
396 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
397 >        assertState(phaser, 1, 2, 2);
398 >        assertEquals(1, phaser.arriveAndDeregister());
399 >        assertState(phaser, 1, 1, 1);
400 >        assertEquals(1, phaser.arriveAndDeregister());
401 >        assertTerminated(phaser, 2);
402 >        awaitTermination(t, SHORT_DELAY_MS);
403      }
404  
405      /**
# Line 317 | Line 407 | public class PhaserTest extends JSR166Te
407       */
408      public void testAwaitAdvance1() {
409          final Phaser phaser = new Phaser(1);
410 <        phaser.awaitAdvance(phaser.arrive());
410 >        assertEquals(0, phaser.arrive());
411 >        assertEquals(1, phaser.awaitAdvance(0));
412      }
413  
414      /**
# Line 325 | Line 416 | public class PhaserTest extends JSR166Te
416       * phaser
417       */
418      public void testAwaitAdvance2() {
419 <        try {
420 <            Phaser phaser = new Phaser();
421 <            phaser.awaitAdvance(-1);
331 <        } catch (Exception failure) {
332 <            this.unexpectedException();
333 <        }
419 >        Phaser phaser = new Phaser();
420 >        assertTrue(phaser.awaitAdvance(-1) < 0);
421 >        assertState(phaser, 0, 0, 0);
422      }
423  
424      /**
425 <     * awaitAdvance while waiting does not abort on interrupt.
425 >     * awaitAdvance continues waiting if interrupted before waiting
426       */
427 <    public void testAwaitAdvance3() {
427 >    public void testAwaitAdvanceAfterInterrupt() throws InterruptedException {
428          final Phaser phaser = new Phaser();
429 +        assertEquals(0, phaser.register());
430 +        final CountDownLatch threadStarted = new CountDownLatch(1);
431  
432 <        Thread th1 = new Thread(new CheckedRunnable() {
433 <            void realRun() throws InterruptedException {
434 <                phaser.register();
435 <                getRunnable(LONG_DELAY_MS).run();
436 <                phaser.awaitAdvance(phaser.arrive());
432 >        Thread t = newStartedThread(new CheckedRunnable() {
433 >            public void realRun() throws InterruptedException {
434 >                Thread.currentThread().interrupt();
435 >                assertEquals(0, phaser.register());
436 >                assertEquals(0, phaser.arrive());
437 >                threadStarted.countDown();
438 >                assertTrue(Thread.currentThread().isInterrupted());
439 >                assertEquals(1, phaser.awaitAdvance(0));
440 >                assertTrue(Thread.currentThread().isInterrupted());
441              }});
442 <        phaser.register();
443 <        th1.start();
444 <        try {
445 <            Thread.sleep(SHORT_DELAY_MS);
446 <            th1.interrupt();
447 <            Thread.sleep(LONG_DELAY_MS);
448 <            phaser.arrive();
449 <        } catch (InterruptedException failure) {
450 <            threadUnexpectedException(failure);
451 <        }
452 <        assertFalse(th1.isInterrupted());
442 >
443 >        assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
444 >        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
445 >        assertEquals(0, phaser.arrive());
446 >        awaitTermination(t, SMALL_DELAY_MS);
447 >
448 >        Thread.currentThread().interrupt();
449 >        assertEquals(1, phaser.awaitAdvance(0));
450 >        assertTrue(Thread.interrupted());
451 >    }
452 >
453 >    /**
454 >     * awaitAdvance continues waiting if interrupted while waiting
455 >     */
456 >    public void testAwaitAdvanceBeforeInterrupt() throws InterruptedException {
457 >        final Phaser phaser = new Phaser();
458 >        assertEquals(0, phaser.register());
459 >        final CountDownLatch threadStarted = new CountDownLatch(1);
460 >
461 >        Thread t = newStartedThread(new CheckedRunnable() {
462 >            public void realRun() throws InterruptedException {
463 >                assertEquals(0, phaser.register());
464 >                assertEquals(0, phaser.arrive());
465 >                threadStarted.countDown();
466 >                assertFalse(Thread.currentThread().isInterrupted());
467 >                assertEquals(1, phaser.awaitAdvance(0));
468 >                assertTrue(Thread.currentThread().isInterrupted());
469 >            }});
470 >
471 >        assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
472 >        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
473 >        t.interrupt();
474 >        assertEquals(0, phaser.arrive());
475 >        awaitTermination(t, SMALL_DELAY_MS);
476 >
477 >        Thread.currentThread().interrupt();
478 >        assertEquals(1, phaser.awaitAdvance(0));
479 >        assertTrue(Thread.interrupted());
480 >    }
481 >
482 >    /**
483 >     * arriveAndAwaitAdvance continues waiting if interrupted before waiting
484 >     */
485 >    public void testArriveAndAwaitAdvanceAfterInterrupt()
486 >            throws InterruptedException {
487 >        final Phaser phaser = new Phaser();
488 >        assertEquals(0, phaser.register());
489 >        final CountDownLatch threadStarted = new CountDownLatch(1);
490 >
491 >        Thread t = newStartedThread(new CheckedRunnable() {
492 >            public void realRun() throws InterruptedException {
493 >                Thread.currentThread().interrupt();
494 >                assertEquals(0, phaser.register());
495 >                threadStarted.countDown();
496 >                assertTrue(Thread.currentThread().isInterrupted());
497 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
498 >                assertTrue(Thread.currentThread().isInterrupted());
499 >            }});
500 >
501 >        assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
502 >        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
503 >        Thread.currentThread().interrupt();
504 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
505 >        assertTrue(Thread.interrupted());
506 >        awaitTermination(t, SMALL_DELAY_MS);
507 >    }
508 >
509 >    /**
510 >     * arriveAndAwaitAdvance continues waiting if interrupted while waiting
511 >     */
512 >    public void testArriveAndAwaitAdvanceBeforeInterrupt()
513 >            throws InterruptedException {
514 >        final Phaser phaser = new Phaser();
515 >        assertEquals(0, phaser.register());
516 >        final CountDownLatch threadStarted = new CountDownLatch(1);
517 >
518 >        Thread t = newStartedThread(new CheckedRunnable() {
519 >            public void realRun() throws InterruptedException {
520 >                assertEquals(0, phaser.register());
521 >                threadStarted.countDown();
522 >                assertFalse(Thread.currentThread().isInterrupted());
523 >                assertEquals(1, phaser.arriveAndAwaitAdvance());
524 >                assertTrue(Thread.currentThread().isInterrupted());
525 >            }});
526 >
527 >        assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
528 >        waitForThreadToEnterWaitState(t, SMALL_DELAY_MS);
529 >        t.interrupt();
530 >        Thread.currentThread().interrupt();
531 >        assertEquals(1, phaser.arriveAndAwaitAdvance());
532 >        assertTrue(Thread.interrupted());
533 >        awaitTermination(t, SMALL_DELAY_MS);
534      }
535  
536      /**
# Line 364 | Line 539 | public class PhaserTest extends JSR166Te
539       */
540      public void testAwaitAdvance4() throws InterruptedException {
541          final Phaser phaser = new Phaser(4);
542 <        final AtomicInteger phaseCount = new AtomicInteger(0);
542 >        final AtomicInteger count = new AtomicInteger(0);
543          List<Thread> threads = new ArrayList<Thread>();
544 <        for (int i = 0; i < 4; i++) {
545 <            threads.add(new Thread(new CheckedRunnable() {
546 <                void realRun() {
547 <                    int phase = phaser.arrive();
548 <                    phaseCount.incrementAndGet();
549 <                    getRunnable(LONG_DELAY_MS).run();
550 <                    phaser.awaitAdvance(phase);
551 <                    threadAssertTrue(phaseCount.get() == 4);
552 <                }}));
553 <        }
554 <        for (Thread thread : threads)
380 <            thread.start();
544 >        for (int i = 0; i < 4; i++)
545 >            threads.add(newStartedThread(new CheckedRunnable() {
546 >                public void realRun() {
547 >                    for (int k = 0; k < 3; k++) {
548 >                        assertEquals(2*k+1, phaser.arriveAndAwaitAdvance());
549 >                        count.incrementAndGet();
550 >                        assertEquals(2*k+1, phaser.arrive());
551 >                        assertEquals(2*k+2, phaser.awaitAdvance(2*k+1));
552 >                        assertEquals(count.get(), 4*(k+1));
553 >                    }}}));
554 >
555          for (Thread thread : threads)
556 <            thread.join();
556 >            awaitTermination(thread, MEDIUM_DELAY_MS);
557      }
558  
559      /**
560       * awaitAdvance returns the current phase
561       */
562 <    public void testAwaitAdvance5() {
562 >    public void testAwaitAdvance5() throws InterruptedException {
563          final Phaser phaser = new Phaser(1);
564 <        int phase = phaser.awaitAdvance(phaser.arrive());
565 <        assertEquals(phase, phaser.getPhase());
566 <        phaser.register();
567 <        for (int i = 0; i < eight; i++) {
568 <            new Thread(new CheckedRunnable() {
569 <                void realRun() {
570 <                    getRunnable(SHORT_DELAY_MS).run();
564 >        assertEquals(1, phaser.awaitAdvance(phaser.arrive()));
565 >        assertEquals(1, phaser.getPhase());
566 >        assertEquals(1, phaser.register());
567 >        List<Thread> threads = new ArrayList<Thread>();
568 >        for (int i = 0; i < 8; i++) {
569 >            final CountDownLatch latch = new CountDownLatch(1);
570 >            final boolean goesFirst = ((i & 1) == 0);
571 >            threads.add(newStartedThread(new CheckedRunnable() {
572 >                public void realRun() throws InterruptedException {
573 >                    if (goesFirst)
574 >                        latch.countDown();
575 >                    else
576 >                        assertTrue(latch.await(SMALL_DELAY_MS, MILLISECONDS));
577                      phaser.arrive();
578 <                }
579 <                }).start();
580 <            phase = phaser.awaitAdvance(phaser.arrive());
581 <            threadAssertEquals(phase, phaser.getPhase());
578 >                }}));
579 >            if (goesFirst)
580 >                assertTrue(latch.await(SMALL_DELAY_MS, MILLISECONDS));
581 >            else
582 >                latch.countDown();
583 >            assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive()));
584 >            assertEquals(i + 2, phaser.getPhase());
585 >        }
586 >        for (Thread thread : threads)
587 >            awaitTermination(thread, SMALL_DELAY_MS);
588 >    }
589 >
590 >    /**
591 >     * awaitAdvance returns the current phase in child phasers
592 >     */
593 >    public void testAwaitAdvanceTieredPhaser() throws Exception {
594 >        final Phaser parent = new Phaser();
595 >        final List<Phaser> zeroPartyChildren = new ArrayList<Phaser>(3);
596 >        final List<Phaser> onePartyChildren = new ArrayList<Phaser>(3);
597 >        for (int i = 0; i < 3; i++) {
598 >            zeroPartyChildren.add(new Phaser(parent, 0));
599 >            onePartyChildren.add(new Phaser(parent, 1));
600 >        }
601 >        final List<Phaser> phasers = new ArrayList<Phaser>();
602 >        phasers.addAll(zeroPartyChildren);
603 >        phasers.addAll(onePartyChildren);
604 >        phasers.add(parent);
605 >        for (Phaser phaser : phasers) {
606 >            assertEquals(-42, phaser.awaitAdvance(-42));
607 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
608 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
609 >        }
610 >
611 >        for (Phaser child : onePartyChildren)
612 >            assertEquals(0, child.arrive());
613 >        for (Phaser phaser : phasers) {
614 >            assertEquals(-42, phaser.awaitAdvance(-42));
615 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
616 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
617 >            assertEquals(1, phaser.awaitAdvance(0));
618 >            assertEquals(1, phaser.awaitAdvanceInterruptibly(0));
619 >            assertEquals(1, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
620 >        }
621 >
622 >        for (Phaser child : onePartyChildren)
623 >            assertEquals(1, child.arrive());
624 >        for (Phaser phaser : phasers) {
625 >            assertEquals(-42, phaser.awaitAdvance(-42));
626 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
627 >            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, SMALL_DELAY_MS, MILLISECONDS));
628 >            assertEquals(2, phaser.awaitAdvance(0));
629 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(0));
630 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(0, SMALL_DELAY_MS, MILLISECONDS));
631 >            assertEquals(2, phaser.awaitAdvance(1));
632 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(1));
633 >            assertEquals(2, phaser.awaitAdvanceInterruptibly(1, SMALL_DELAY_MS, MILLISECONDS));
634          }
635      }
636  
637      /**
638       * awaitAdvance returns when the phaser is externally terminated
639       */
640 <    public void testAwaitAdvance6() {
640 >    public void testAwaitAdvance6() throws InterruptedException {
641          final Phaser phaser = new Phaser(3);
642 <        /*
643 <         * Start new thread. This thread waits a small amount of time
644 <         * and waits for the other two parties to arrive.  The party
645 <         * in the main thread arrives quickly so at best this thread
646 <         * waits for the second thread's party to arrive
647 <         */
648 <        new Thread(new CheckedRunnable() {
649 <            void realRun() {
650 <                getRunnable(SMALL_DELAY_MS).run();
651 <                int phase = phaser.awaitAdvance(phaser.arrive());
652 <                /*
653 <                 * This point is reached when force termination is called in which phase = -1
654 <                 */
655 <                threadAssertTrue(phase < 0);
656 <                threadAssertTrue(phaser.isTerminated());
657 <            }}).start();
426 <        /*
427 <         * This thread will cause the first thread run to wait, in doing so
428 <         * the main thread will force termination in which the first thread
429 <         * should exit peacefully as this one
430 <         */
431 <        new Thread(new CheckedRunnable() {
432 <            void realRun() {
433 <                getRunnable(LONG_DELAY_MS).run();
434 <                int p1 = phaser.arrive();
435 <                int phase = phaser.awaitAdvance(p1);
436 <                threadAssertTrue(phase < 0);
437 <                threadAssertTrue(phaser.isTerminated());
438 <            }}).start();
439 <
440 <        phaser.arrive();
642 >        final CountDownLatch threadsStarted = new CountDownLatch(2);
643 >        final List<Thread> threads = new ArrayList<Thread>();
644 >        for (int i = 0; i < 2; i++) {
645 >            Runnable r = new CheckedRunnable() {
646 >                public void realRun() {
647 >                    assertEquals(0, phaser.arrive());
648 >                    threadsStarted.countDown();
649 >                    assertTrue(phaser.awaitAdvance(0) < 0);
650 >                    assertTrue(phaser.isTerminated());
651 >                    assertTrue(phaser.getPhase() < 0);
652 >                    assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
653 >                    assertEquals(3, phaser.getRegisteredParties());
654 >                }};
655 >            threads.add(newStartedThread(r));
656 >        }
657 >        threadsStarted.await();
658          phaser.forceTermination();
659 +        assertTrue(phaser.isTerminated());
660 +        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
661 +        for (Thread thread : threads)
662 +            awaitTermination(thread, SMALL_DELAY_MS);
663 +        assertEquals(3, phaser.getRegisteredParties());
664      }
665  
666      /**
# Line 450 | Line 672 | public class PhaserTest extends JSR166Te
672              Phaser phaser = new Phaser();
673              phaser.arriveAndAwaitAdvance();
674              shouldThrow();
675 <        } catch (IllegalStateException success) {
454 <        }
455 <    }
456 <
457 <    /**
458 <     * Interrupted arriveAndAwaitAdvance does not throw InterruptedException
459 <     */
460 <    public void testArriveAndAwaitAdvance2() {
461 <        final Phaser phaser = new Phaser(2);
462 <        Thread th = new Thread(new CheckedRunnable() {
463 <            void realRun() {
464 <                phaser.arriveAndAwaitAdvance();
465 <            }});
466 <
467 <        try {
468 <            th.start();
469 <            Thread.sleep(LONG_DELAY_MS);
470 <            th.interrupt();
471 <            Thread.sleep(LONG_DELAY_MS);
472 <            phaser.arrive();
473 <        } catch (InterruptedException failure) {
474 <            this.unexpectedException();
475 <        }
476 <        assertFalse(th.isInterrupted());
675 >        } catch (IllegalStateException success) {}
676      }
677  
678      /**
# Line 481 | Line 680 | public class PhaserTest extends JSR166Te
680       * number of arrived parties is the same number that is accounted
681       * for when the main thread awaitsAdvance
682       */
683 <    public void testArriveAndAwaitAdvance3() {
683 >    public void testArriveAndAwaitAdvance3() throws InterruptedException {
684          final Phaser phaser = new Phaser(1);
685 <        final AtomicInteger arrivingCount = new AtomicInteger(0);
686 <        for (final Runnable run : getRunnables(six, SHORT_DELAY_MS)) {
687 <            new Thread(new CheckedRunnable() {
688 <                void realRun() {
689 <                    phaser.register();
690 <                    run.run();
691 <                    arrivingCount.getAndIncrement();
692 <                    phaser.arrive();
693 <                }}).start();
694 <        }
496 <        int phaseNumber = phaser.arriveAndAwaitAdvance();
497 <        arrivingCount.incrementAndGet();
498 <        //the + 1 adds to expectedArrive to account for the main threads arrival
499 <        int expectedArrived = phaseNumber > 0 ? phaseNumber * six + 1 : phaser.getArrivedParties() + 1;
500 <        threadAssertEquals(expectedArrived, arrivingCount.get());
501 <    }
502 <    // .. initially called, for n tasks via
503 <    private List<Runnable> getRunnables(int size, long wait) {
504 <        List<Runnable> list = new ArrayList<Runnable>();
505 <        for (int i = 0; i < size; i++) {
506 <            list.add(getRunnable(wait));
507 <        }
508 <        return list;
509 <    }
685 >        final int THREADS = 3;
686 >        final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
687 >        final List<Thread> threads = new ArrayList<Thread>();
688 >        for (int i = 0; i < THREADS; i++)
689 >            threads.add(newStartedThread(new CheckedRunnable() {
690 >                public void realRun() throws InterruptedException {
691 >                    assertEquals(0, phaser.register());
692 >                    threadsStarted.countDown();
693 >                    assertEquals(1, phaser.arriveAndAwaitAdvance());
694 >                }}));
695  
696 <    private Runnable getRunnable(final long wait) {
697 <        return new CheckedRunnable() {
698 <            void realRun() {
699 <                try {
700 <                    Thread.sleep(wait);
701 <                } catch (InterruptedException noop) {
702 <                // sleep interruption isn't a problem case for these example
703 <                }
704 <            }
705 <        };
696 >        assertTrue(threadsStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
697 >        long t0 = System.nanoTime();
698 >        while (phaser.getArrivedParties() < THREADS)
699 >            Thread.yield();
700 >        assertEquals(THREADS, phaser.getArrivedParties());
701 >        assertTrue(NANOSECONDS.toMillis(System.nanoTime() - t0) < SMALL_DELAY_MS);
702 >        for (Thread thread : threads)
703 >            assertTrue(thread.isAlive());
704 >        assertState(phaser, 0, THREADS + 1, 1);
705 >        phaser.arriveAndAwaitAdvance();
706 >        for (Thread thread : threads)
707 >            awaitTermination(thread, SMALL_DELAY_MS);
708 >        assertState(phaser, 1, THREADS + 1, THREADS + 1);
709      }
710  
711   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines