ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/RecursiveActionTest.java
Revision: 1.26
Committed: Tue Nov 23 07:38:40 2010 UTC (13 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.25: +97 -0 lines
Log Message:
new test testJoinIgnoresInterruptsOutsideForkJoinPool

File Contents

# Content
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
5 */
6
7 import junit.framework.*;
8 import java.util.concurrent.CancellationException;
9 import java.util.concurrent.SynchronousQueue;
10 import java.util.concurrent.ExecutionException;
11 import java.util.concurrent.ForkJoinPool;
12 import java.util.concurrent.ForkJoinWorkerThread;
13 import java.util.concurrent.RecursiveAction;
14 import java.util.concurrent.TimeUnit;
15 import java.util.concurrent.TimeoutException;
16 import static java.util.concurrent.TimeUnit.SECONDS;
17 import java.util.HashSet;
18
19 public class RecursiveActionTest extends JSR166TestCase {
20
21 public static void main(String[] args) {
22 junit.textui.TestRunner.run(suite());
23 }
24
25 public static Test suite() {
26 return new TestSuite(RecursiveActionTest.class);
27 }
28
29 private static ForkJoinPool mainPool() {
30 return new ForkJoinPool();
31 }
32
33 private static ForkJoinPool singletonPool() {
34 return new ForkJoinPool(1);
35 }
36
37 private static ForkJoinPool asyncSingletonPool() {
38 return new ForkJoinPool(1,
39 ForkJoinPool.defaultForkJoinWorkerThreadFactory,
40 null, true);
41 }
42
43 private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
44 try {
45 checkNotDone(a);
46
47 assertNull(pool.invoke(a));
48
49 checkCompletedNormally(a);
50 } finally {
51 joinPool(pool);
52 }
53 }
54
55 void checkNotDone(RecursiveAction a) {
56 assertFalse(a.isDone());
57 assertFalse(a.isCompletedNormally());
58 assertFalse(a.isCompletedAbnormally());
59 assertFalse(a.isCancelled());
60 assertNull(a.getException());
61 assertNull(a.getRawResult());
62
63 if (! (Thread.currentThread() instanceof ForkJoinWorkerThread)) {
64 Thread.currentThread().interrupt();
65 try {
66 a.get();
67 shouldThrow();
68 } catch (InterruptedException success) {
69 } catch (Throwable fail) { threadUnexpectedException(fail); }
70
71 Thread.currentThread().interrupt();
72 try {
73 a.get(5L, SECONDS);
74 shouldThrow();
75 } catch (InterruptedException success) {
76 } catch (Throwable fail) { threadUnexpectedException(fail); }
77 }
78
79 try {
80 a.get(0L, SECONDS);
81 shouldThrow();
82 } catch (TimeoutException success) {
83 } catch (Throwable fail) { threadUnexpectedException(fail); }
84 }
85
86 void checkCompletedNormally(RecursiveAction a) {
87 assertTrue(a.isDone());
88 assertFalse(a.isCancelled());
89 assertTrue(a.isCompletedNormally());
90 assertFalse(a.isCompletedAbnormally());
91 assertNull(a.getException());
92 assertNull(a.getRawResult());
93 assertNull(a.join());
94 assertFalse(a.cancel(false));
95 assertFalse(a.cancel(true));
96 try {
97 assertNull(a.get());
98 } catch (Throwable fail) { threadUnexpectedException(fail); }
99 try {
100 assertNull(a.get(5L, SECONDS));
101 } catch (Throwable fail) { threadUnexpectedException(fail); }
102 }
103
104 void checkCancelled(RecursiveAction a) {
105 assertTrue(a.isDone());
106 assertTrue(a.isCancelled());
107 assertFalse(a.isCompletedNormally());
108 assertTrue(a.isCompletedAbnormally());
109 assertTrue(a.getException() instanceof CancellationException);
110 assertNull(a.getRawResult());
111
112 try {
113 a.join();
114 shouldThrow();
115 } catch (CancellationException success) {
116 } catch (Throwable fail) { threadUnexpectedException(fail); }
117
118 try {
119 a.get();
120 shouldThrow();
121 } catch (CancellationException success) {
122 } catch (Throwable fail) { threadUnexpectedException(fail); }
123
124 try {
125 a.get(5L, SECONDS);
126 shouldThrow();
127 } catch (CancellationException success) {
128 } catch (Throwable fail) { threadUnexpectedException(fail); }
129 }
130
131 void checkCompletedAbnormally(RecursiveAction a, Throwable t) {
132 assertTrue(a.isDone());
133 assertFalse(a.isCancelled());
134 assertFalse(a.isCompletedNormally());
135 assertTrue(a.isCompletedAbnormally());
136 assertSame(t, a.getException());
137 assertNull(a.getRawResult());
138 assertFalse(a.cancel(false));
139 assertFalse(a.cancel(true));
140
141 try {
142 a.join();
143 shouldThrow();
144 } catch (Throwable expected) {
145 assertSame(t, expected);
146 }
147
148 try {
149 a.get();
150 shouldThrow();
151 } catch (ExecutionException success) {
152 assertSame(t, success.getCause());
153 } catch (Throwable fail) { threadUnexpectedException(fail); }
154
155 try {
156 a.get(5L, SECONDS);
157 shouldThrow();
158 } catch (ExecutionException success) {
159 assertSame(t, success.getCause());
160 } catch (Throwable fail) { threadUnexpectedException(fail); }
161 }
162
163 static final class FJException extends RuntimeException {
164 FJException() { super(); }
165 }
166
167 // A simple recursive action for testing
168 final class FibAction extends CheckedRecursiveAction {
169 final int number;
170 int result;
171 FibAction(int n) { number = n; }
172 public void realCompute() {
173 int n = number;
174 if (n <= 1)
175 result = n;
176 else {
177 FibAction f1 = new FibAction(n - 1);
178 FibAction f2 = new FibAction(n - 2);
179 invokeAll(f1, f2);
180 result = f1.result + f2.result;
181 }
182 }
183 }
184
185 // A recursive action failing in base case
186 static final class FailingFibAction extends RecursiveAction {
187 final int number;
188 int result;
189 FailingFibAction(int n) { number = n; }
190 public void compute() {
191 int n = number;
192 if (n <= 1)
193 throw new FJException();
194 else {
195 FailingFibAction f1 = new FailingFibAction(n - 1);
196 FailingFibAction f2 = new FailingFibAction(n - 2);
197 invokeAll(f1, f2);
198 result = f1.result + f2.result;
199 }
200 }
201 }
202
203 /**
204 * invoke returns when task completes normally.
205 * isCompletedAbnormally and isCancelled return false for normally
206 * completed tasks. getRawResult of a RecursiveAction returns null;
207 */
208 public void testInvoke() {
209 RecursiveAction a = new CheckedRecursiveAction() {
210 public void realCompute() {
211 FibAction f = new FibAction(8);
212 assertNull(f.invoke());
213 assertEquals(21, f.result);
214 checkCompletedNormally(f);
215 }};
216 testInvokeOnPool(mainPool(), a);
217 }
218
219 /**
220 * quietlyInvoke task returns when task completes normally.
221 * isCompletedAbnormally and isCancelled return false for normally
222 * completed tasks
223 */
224 public void testQuietlyInvoke() {
225 RecursiveAction a = new CheckedRecursiveAction() {
226 public void realCompute() {
227 FibAction f = new FibAction(8);
228 f.quietlyInvoke();
229 assertEquals(21, f.result);
230 checkCompletedNormally(f);
231 }};
232 testInvokeOnPool(mainPool(), a);
233 }
234
235 /**
236 * join of a forked task returns when task completes
237 */
238 public void testForkJoin() {
239 RecursiveAction a = new CheckedRecursiveAction() {
240 public void realCompute() {
241 FibAction f = new FibAction(8);
242 assertSame(f, f.fork());
243 assertNull(f.join());
244 assertEquals(21, f.result);
245 checkCompletedNormally(f);
246 }};
247 testInvokeOnPool(mainPool(), a);
248 }
249
250 /**
251 * join/quietlyJoin of a forked task succeeds in the presence of interrupts
252 */
253 public void testJoinIgnoresInterrupts() {
254 RecursiveAction a = new CheckedRecursiveAction() {
255 public void realCompute() {
256 FibAction f = new FibAction(8);
257
258 // test join()
259 assertSame(f, f.fork());
260 Thread.currentThread().interrupt();
261 assertNull(f.join());
262 Thread.interrupted();
263 assertEquals(21, f.result);
264 checkCompletedNormally(f);
265
266 f.reinitialize();
267 f.cancel(true);
268 assertSame(f, f.fork());
269 Thread.currentThread().interrupt();
270 try {
271 f.join();
272 shouldThrow();
273 } catch (CancellationException success) {
274 Thread.interrupted();
275 checkCancelled(f);
276 }
277
278 f.reinitialize();
279 f.completeExceptionally(new FJException());
280 assertSame(f, f.fork());
281 Thread.currentThread().interrupt();
282 try {
283 f.join();
284 shouldThrow();
285 } catch (FJException success) {
286 Thread.interrupted();
287 checkCompletedAbnormally(f, success);
288 }
289
290 // test quietlyJoin()
291 f.reinitialize();
292 assertSame(f, f.fork());
293 Thread.currentThread().interrupt();
294 f.quietlyJoin();
295 Thread.interrupted();
296 assertEquals(21, f.result);
297 checkCompletedNormally(f);
298
299 f.reinitialize();
300 f.cancel(true);
301 assertSame(f, f.fork());
302 Thread.currentThread().interrupt();
303 f.quietlyJoin();
304 Thread.interrupted();
305 checkCancelled(f);
306
307 f.reinitialize();
308 f.completeExceptionally(new FJException());
309 assertSame(f, f.fork());
310 Thread.currentThread().interrupt();
311 f.quietlyJoin();
312 Thread.interrupted();
313 checkCompletedAbnormally(f, f.getException());
314 }};
315 testInvokeOnPool(mainPool(), a);
316 a.reinitialize();
317 testInvokeOnPool(singletonPool(), a);
318 }
319
320 /**
321 * join/quietlyJoin of a forked task when not in ForkJoinPool
322 * succeeds in the presence of interrupts
323 */
324 public void testJoinIgnoresInterruptsOutsideForkJoinPool() {
325 final SynchronousQueue<FibAction[]> sq =
326 new SynchronousQueue<FibAction[]>();
327 RecursiveAction a = new CheckedRecursiveAction() {
328 public void realCompute() throws InterruptedException {
329 FibAction[] fibActions = new FibAction[6];
330 for (int i = 0; i < fibActions.length; i++)
331 fibActions[i] = new FibAction(8);
332
333 fibActions[1].cancel(false);
334 fibActions[2].completeExceptionally(new FJException());
335 fibActions[4].cancel(true);
336 fibActions[5].completeExceptionally(new FJException());
337
338 for (int i = 0; i < fibActions.length; i++)
339 fibActions[i].fork();
340
341 sq.put(fibActions);
342
343 helpQuiesce();
344 }};
345
346 Runnable r = new CheckedRunnable() {
347 public void realRun() throws InterruptedException {
348 FibAction[] fibActions = sq.take();
349 FibAction f;
350
351 // test join() ------------
352
353 f = fibActions[0];
354 assertFalse(f.inForkJoinPool());
355 Thread.currentThread().interrupt();
356 assertNull(f.join());
357 assertTrue(Thread.interrupted());
358 assertEquals(21, f.result);
359 checkCompletedNormally(f);
360
361 f = fibActions[1];
362 Thread.currentThread().interrupt();
363 try {
364 f.join();
365 shouldThrow();
366 } catch (CancellationException success) {
367 assertTrue(Thread.interrupted());
368 checkCancelled(f);
369 }
370
371 f = fibActions[2];
372 Thread.currentThread().interrupt();
373 try {
374 f.join();
375 shouldThrow();
376 } catch (FJException success) {
377 assertTrue(Thread.interrupted());
378 checkCompletedAbnormally(f, success);
379 }
380
381 // test quietlyJoin() ---------
382
383 f = fibActions[3];
384 Thread.currentThread().interrupt();
385 f.quietlyJoin();
386 assertTrue(Thread.interrupted());
387 assertEquals(21, f.result);
388 checkCompletedNormally(f);
389
390 f = fibActions[4];
391 Thread.currentThread().interrupt();
392 f.quietlyJoin();
393 assertTrue(Thread.interrupted());
394 checkCancelled(f);
395
396 f = fibActions[5];
397 Thread.currentThread().interrupt();
398 f.quietlyJoin();
399 assertTrue(Thread.interrupted());
400 assertTrue(f.getException() instanceof FJException);
401 checkCompletedAbnormally(f, f.getException());
402 }};
403
404 Thread t;
405
406 t = newStartedThread(r);
407 testInvokeOnPool(mainPool(), a);
408 awaitTermination(t, LONG_DELAY_MS);
409
410 a.reinitialize();
411 t = newStartedThread(r);
412 testInvokeOnPool(singletonPool(), a);
413 awaitTermination(t, LONG_DELAY_MS);
414 }
415
416 /**
417 * get of a forked task returns when task completes
418 */
419 public void testForkGet() {
420 RecursiveAction a = new CheckedRecursiveAction() {
421 public void realCompute() throws Exception {
422 FibAction f = new FibAction(8);
423 assertSame(f, f.fork());
424 assertNull(f.get());
425 assertEquals(21, f.result);
426 checkCompletedNormally(f);
427 }};
428 testInvokeOnPool(mainPool(), a);
429 }
430
431 /**
432 * timed get of a forked task returns when task completes
433 */
434 public void testForkTimedGet() {
435 RecursiveAction a = new CheckedRecursiveAction() {
436 public void realCompute() throws Exception {
437 FibAction f = new FibAction(8);
438 assertSame(f, f.fork());
439 assertNull(f.get(5L, SECONDS));
440 assertEquals(21, f.result);
441 checkCompletedNormally(f);
442 }};
443 testInvokeOnPool(mainPool(), a);
444 }
445
446 /**
447 * timed get with null time unit throws NPE
448 */
449 public void testForkTimedGetNPE() {
450 RecursiveAction a = new CheckedRecursiveAction() {
451 public void realCompute() throws Exception {
452 FibAction f = new FibAction(8);
453 assertSame(f, f.fork());
454 try {
455 f.get(5L, null);
456 shouldThrow();
457 } catch (NullPointerException success) {}
458 }};
459 testInvokeOnPool(mainPool(), a);
460 }
461
462 /**
463 * quietlyJoin of a forked task returns when task completes
464 */
465 public void testForkQuietlyJoin() {
466 RecursiveAction a = new CheckedRecursiveAction() {
467 public void realCompute() {
468 FibAction f = new FibAction(8);
469 assertSame(f, f.fork());
470 f.quietlyJoin();
471 assertEquals(21, f.result);
472 checkCompletedNormally(f);
473 }};
474 testInvokeOnPool(mainPool(), a);
475 }
476
477
478 /**
479 * helpQuiesce returns when tasks are complete.
480 * getQueuedTaskCount returns 0 when quiescent
481 */
482 public void testForkHelpQuiesce() {
483 RecursiveAction a = new CheckedRecursiveAction() {
484 public void realCompute() {
485 FibAction f = new FibAction(8);
486 assertSame(f, f.fork());
487 f.helpQuiesce();
488 assertEquals(21, f.result);
489 assertEquals(0, getQueuedTaskCount());
490 checkCompletedNormally(f);
491 }};
492 testInvokeOnPool(mainPool(), a);
493 }
494
495
496 /**
497 * invoke task throws exception when task completes abnormally
498 */
499 public void testAbnormalInvoke() {
500 RecursiveAction a = new CheckedRecursiveAction() {
501 public void realCompute() {
502 FailingFibAction f = new FailingFibAction(8);
503 try {
504 f.invoke();
505 shouldThrow();
506 } catch (FJException success) {
507 checkCompletedAbnormally(f, success);
508 }
509 }};
510 testInvokeOnPool(mainPool(), a);
511 }
512
513 /**
514 * quietlyInvoke task returns when task completes abnormally
515 */
516 public void testAbnormalQuietlyInvoke() {
517 RecursiveAction a = new CheckedRecursiveAction() {
518 public void realCompute() {
519 FailingFibAction f = new FailingFibAction(8);
520 f.quietlyInvoke();
521 assertTrue(f.getException() instanceof FJException);
522 checkCompletedAbnormally(f, f.getException());
523 }};
524 testInvokeOnPool(mainPool(), a);
525 }
526
527 /**
528 * join of a forked task throws exception when task completes abnormally
529 */
530 public void testAbnormalForkJoin() {
531 RecursiveAction a = new CheckedRecursiveAction() {
532 public void realCompute() {
533 FailingFibAction f = new FailingFibAction(8);
534 assertSame(f, f.fork());
535 try {
536 f.join();
537 shouldThrow();
538 } catch (FJException success) {
539 checkCompletedAbnormally(f, success);
540 }
541 }};
542 testInvokeOnPool(mainPool(), a);
543 }
544
545 /**
546 * get of a forked task throws exception when task completes abnormally
547 */
548 public void testAbnormalForkGet() {
549 RecursiveAction a = new CheckedRecursiveAction() {
550 public void realCompute() throws Exception {
551 FailingFibAction f = new FailingFibAction(8);
552 assertSame(f, f.fork());
553 try {
554 f.get();
555 shouldThrow();
556 } catch (ExecutionException success) {
557 Throwable cause = success.getCause();
558 assertTrue(cause instanceof FJException);
559 checkCompletedAbnormally(f, cause);
560 }
561 }};
562 testInvokeOnPool(mainPool(), a);
563 }
564
565 /**
566 * timed get of a forked task throws exception when task completes abnormally
567 */
568 public void testAbnormalForkTimedGet() {
569 RecursiveAction a = new CheckedRecursiveAction() {
570 public void realCompute() throws Exception {
571 FailingFibAction f = new FailingFibAction(8);
572 assertSame(f, f.fork());
573 try {
574 f.get(5L, TimeUnit.SECONDS);
575 shouldThrow();
576 } catch (ExecutionException success) {
577 Throwable cause = success.getCause();
578 assertTrue(cause instanceof FJException);
579 checkCompletedAbnormally(f, cause);
580 }
581 }};
582 testInvokeOnPool(mainPool(), a);
583 }
584
585 /**
586 * quietlyJoin of a forked task returns when task completes abnormally
587 */
588 public void testAbnormalForkQuietlyJoin() {
589 RecursiveAction a = new CheckedRecursiveAction() {
590 public void realCompute() {
591 FailingFibAction f = new FailingFibAction(8);
592 assertSame(f, f.fork());
593 f.quietlyJoin();
594 assertTrue(f.getException() instanceof FJException);
595 checkCompletedAbnormally(f, f.getException());
596 }};
597 testInvokeOnPool(mainPool(), a);
598 }
599
600 /**
601 * invoke task throws exception when task cancelled
602 */
603 public void testCancelledInvoke() {
604 RecursiveAction a = new CheckedRecursiveAction() {
605 public void realCompute() {
606 FibAction f = new FibAction(8);
607 assertTrue(f.cancel(true));
608 try {
609 f.invoke();
610 shouldThrow();
611 } catch (CancellationException success) {
612 checkCancelled(f);
613 }
614 }};
615 testInvokeOnPool(mainPool(), a);
616 }
617
618 /**
619 * join of a forked task throws exception when task cancelled
620 */
621 public void testCancelledForkJoin() {
622 RecursiveAction a = new CheckedRecursiveAction() {
623 public void realCompute() {
624 FibAction f = new FibAction(8);
625 assertTrue(f.cancel(true));
626 assertSame(f, f.fork());
627 try {
628 f.join();
629 shouldThrow();
630 } catch (CancellationException success) {
631 checkCancelled(f);
632 }
633 }};
634 testInvokeOnPool(mainPool(), a);
635 }
636
637 /**
638 * get of a forked task throws exception when task cancelled
639 */
640 public void testCancelledForkGet() {
641 RecursiveAction a = new CheckedRecursiveAction() {
642 public void realCompute() throws Exception {
643 FibAction f = new FibAction(8);
644 assertTrue(f.cancel(true));
645 assertSame(f, f.fork());
646 try {
647 f.get();
648 shouldThrow();
649 } catch (CancellationException success) {
650 checkCancelled(f);
651 }
652 }};
653 testInvokeOnPool(mainPool(), a);
654 }
655
656 /**
657 * timed get of a forked task throws exception when task cancelled
658 */
659 public void testCancelledForkTimedGet() {
660 RecursiveAction a = new CheckedRecursiveAction() {
661 public void realCompute() throws Exception {
662 FibAction f = new FibAction(8);
663 assertTrue(f.cancel(true));
664 assertSame(f, f.fork());
665 try {
666 f.get(5L, SECONDS);
667 shouldThrow();
668 } catch (CancellationException success) {
669 checkCancelled(f);
670 }
671 }};
672 testInvokeOnPool(mainPool(), a);
673 }
674
675 /**
676 * quietlyJoin of a forked task returns when task cancelled
677 */
678 public void testCancelledForkQuietlyJoin() {
679 RecursiveAction a = new CheckedRecursiveAction() {
680 public void realCompute() {
681 FibAction f = new FibAction(8);
682 assertTrue(f.cancel(true));
683 assertSame(f, f.fork());
684 f.quietlyJoin();
685 checkCancelled(f);
686 }};
687 testInvokeOnPool(mainPool(), a);
688 }
689
690 /**
691 * getPool of executing task returns its pool
692 */
693 public void testGetPool() {
694 final ForkJoinPool mainPool = mainPool();
695 RecursiveAction a = new CheckedRecursiveAction() {
696 public void realCompute() {
697 assertSame(mainPool, getPool());
698 }};
699 testInvokeOnPool(mainPool, a);
700 }
701
702 /**
703 * getPool of non-FJ task returns null
704 */
705 public void testGetPool2() {
706 RecursiveAction a = new CheckedRecursiveAction() {
707 public void realCompute() {
708 assertNull(getPool());
709 }};
710 assertNull(a.invoke());
711 }
712
713 /**
714 * inForkJoinPool of executing task returns true
715 */
716 public void testInForkJoinPool() {
717 RecursiveAction a = new CheckedRecursiveAction() {
718 public void realCompute() {
719 assertTrue(inForkJoinPool());
720 }};
721 testInvokeOnPool(mainPool(), a);
722 }
723
724 /**
725 * inForkJoinPool of non-FJ task returns false
726 */
727 public void testInForkJoinPool2() {
728 RecursiveAction a = new CheckedRecursiveAction() {
729 public void realCompute() {
730 assertFalse(inForkJoinPool());
731 }};
732 assertNull(a.invoke());
733 }
734
735 /**
736 * getPool of current thread in pool returns its pool
737 */
738 public void testWorkerGetPool() {
739 final ForkJoinPool mainPool = mainPool();
740 RecursiveAction a = new CheckedRecursiveAction() {
741 public void realCompute() {
742 ForkJoinWorkerThread w =
743 (ForkJoinWorkerThread) Thread.currentThread();
744 assertSame(mainPool, w.getPool());
745 }};
746 testInvokeOnPool(mainPool, a);
747 }
748
749 /**
750 * getPoolIndex of current thread in pool returns 0 <= value < poolSize
751 */
752 public void testWorkerGetPoolIndex() {
753 final ForkJoinPool mainPool = mainPool();
754 RecursiveAction a = new CheckedRecursiveAction() {
755 public void realCompute() {
756 ForkJoinWorkerThread w =
757 (ForkJoinWorkerThread)(Thread.currentThread());
758 assertTrue(w.getPoolIndex() >= 0);
759 assertTrue(w.getPoolIndex() < mainPool.getPoolSize());
760 }};
761 testInvokeOnPool(mainPool, a);
762 }
763
764
765 /**
766 * setRawResult(null) succeeds
767 */
768 public void testSetRawResult() {
769 RecursiveAction a = new CheckedRecursiveAction() {
770 public void realCompute() {
771 setRawResult(null);
772 assertNull(getRawResult());
773 }};
774 assertNull(a.invoke());
775 }
776
777 /**
778 * A reinitialized task may be re-invoked
779 */
780 public void testReinitialize() {
781 RecursiveAction a = new CheckedRecursiveAction() {
782 public void realCompute() {
783 FibAction f = new FibAction(8);
784 checkNotDone(f);
785
786 for (int i = 0; i < 3; i++) {
787 assertNull(f.invoke());
788 assertEquals(21, f.result);
789 checkCompletedNormally(f);
790 f.reinitialize();
791 checkNotDone(f);
792 }
793 }};
794 testInvokeOnPool(mainPool(), a);
795 }
796
797 /**
798 * invoke task throws exception after invoking completeExceptionally
799 */
800 public void testCompleteExceptionally() {
801 RecursiveAction a = new CheckedRecursiveAction() {
802 public void realCompute() {
803 FibAction f = new FibAction(8);
804 f.completeExceptionally(new FJException());
805 try {
806 f.invoke();
807 shouldThrow();
808 } catch (FJException success) {
809 checkCompletedAbnormally(f, success);
810 }
811 }};
812 testInvokeOnPool(mainPool(), a);
813 }
814
815 /**
816 * invoke task suppresses execution invoking complete
817 */
818 public void testComplete() {
819 RecursiveAction a = new CheckedRecursiveAction() {
820 public void realCompute() {
821 FibAction f = new FibAction(8);
822 f.complete(null);
823 assertNull(f.invoke());
824 assertEquals(0, f.result);
825 checkCompletedNormally(f);
826 }};
827 testInvokeOnPool(mainPool(), a);
828 }
829
830 /**
831 * invokeAll(t1, t2) invokes all task arguments
832 */
833 public void testInvokeAll2() {
834 RecursiveAction a = new CheckedRecursiveAction() {
835 public void realCompute() {
836 FibAction f = new FibAction(8);
837 FibAction g = new FibAction(9);
838 invokeAll(f, g);
839 checkCompletedNormally(f);
840 assertEquals(21, f.result);
841 checkCompletedNormally(g);
842 assertEquals(34, g.result);
843 }};
844 testInvokeOnPool(mainPool(), a);
845 }
846
847 /**
848 * invokeAll(tasks) with 1 argument invokes task
849 */
850 public void testInvokeAll1() {
851 RecursiveAction a = new CheckedRecursiveAction() {
852 public void realCompute() {
853 FibAction f = new FibAction(8);
854 invokeAll(f);
855 checkCompletedNormally(f);
856 assertEquals(21, f.result);
857 }};
858 testInvokeOnPool(mainPool(), a);
859 }
860
861 /**
862 * invokeAll(tasks) with > 2 argument invokes tasks
863 */
864 public void testInvokeAll3() {
865 RecursiveAction a = new CheckedRecursiveAction() {
866 public void realCompute() {
867 FibAction f = new FibAction(8);
868 FibAction g = new FibAction(9);
869 FibAction h = new FibAction(7);
870 invokeAll(f, g, h);
871 assertTrue(f.isDone());
872 assertTrue(g.isDone());
873 assertTrue(h.isDone());
874 checkCompletedNormally(f);
875 assertEquals(21, f.result);
876 checkCompletedNormally(g);
877 assertEquals(34, g.result);
878 checkCompletedNormally(g);
879 assertEquals(13, h.result);
880 }};
881 testInvokeOnPool(mainPool(), a);
882 }
883
884 /**
885 * invokeAll(collection) invokes all tasks in the collection
886 */
887 public void testInvokeAllCollection() {
888 RecursiveAction a = new CheckedRecursiveAction() {
889 public void realCompute() {
890 FibAction f = new FibAction(8);
891 FibAction g = new FibAction(9);
892 FibAction h = new FibAction(7);
893 HashSet set = new HashSet();
894 set.add(f);
895 set.add(g);
896 set.add(h);
897 invokeAll(set);
898 assertTrue(f.isDone());
899 assertTrue(g.isDone());
900 assertTrue(h.isDone());
901 checkCompletedNormally(f);
902 assertEquals(21, f.result);
903 checkCompletedNormally(g);
904 assertEquals(34, g.result);
905 checkCompletedNormally(g);
906 assertEquals(13, h.result);
907 }};
908 testInvokeOnPool(mainPool(), a);
909 }
910
911
912 /**
913 * invokeAll(tasks) with any null task throws NPE
914 */
915 public void testInvokeAllNPE() {
916 RecursiveAction a = new CheckedRecursiveAction() {
917 public void realCompute() {
918 FibAction f = new FibAction(8);
919 FibAction g = new FibAction(9);
920 FibAction h = null;
921 try {
922 invokeAll(f, g, h);
923 shouldThrow();
924 } catch (NullPointerException success) {}
925 }};
926 testInvokeOnPool(mainPool(), a);
927 }
928
929 /**
930 * invokeAll(t1, t2) throw exception if any task does
931 */
932 public void testAbnormalInvokeAll2() {
933 RecursiveAction a = new CheckedRecursiveAction() {
934 public void realCompute() {
935 FibAction f = new FibAction(8);
936 FailingFibAction g = new FailingFibAction(9);
937 try {
938 invokeAll(f, g);
939 shouldThrow();
940 } catch (FJException success) {
941 checkCompletedAbnormally(g, success);
942 }
943 }};
944 testInvokeOnPool(mainPool(), a);
945 }
946
947 /**
948 * invokeAll(tasks) with 1 argument throws exception if task does
949 */
950 public void testAbnormalInvokeAll1() {
951 RecursiveAction a = new CheckedRecursiveAction() {
952 public void realCompute() {
953 FailingFibAction g = new FailingFibAction(9);
954 try {
955 invokeAll(g);
956 shouldThrow();
957 } catch (FJException success) {
958 checkCompletedAbnormally(g, success);
959 }
960 }};
961 testInvokeOnPool(mainPool(), a);
962 }
963
964 /**
965 * invokeAll(tasks) with > 2 argument throws exception if any task does
966 */
967 public void testAbnormalInvokeAll3() {
968 RecursiveAction a = new CheckedRecursiveAction() {
969 public void realCompute() {
970 FibAction f = new FibAction(8);
971 FailingFibAction g = new FailingFibAction(9);
972 FibAction h = new FibAction(7);
973 try {
974 invokeAll(f, g, h);
975 shouldThrow();
976 } catch (FJException success) {
977 checkCompletedAbnormally(g, success);
978 }
979 }};
980 testInvokeOnPool(mainPool(), a);
981 }
982
983 /**
984 * invokeAll(collection) throws exception if any task does
985 */
986 public void testAbnormalInvokeAllCollection() {
987 RecursiveAction a = new CheckedRecursiveAction() {
988 public void realCompute() {
989 FailingFibAction f = new FailingFibAction(8);
990 FibAction g = new FibAction(9);
991 FibAction h = new FibAction(7);
992 HashSet set = new HashSet();
993 set.add(f);
994 set.add(g);
995 set.add(h);
996 try {
997 invokeAll(set);
998 shouldThrow();
999 } catch (FJException success) {
1000 checkCompletedAbnormally(f, success);
1001 }
1002 }};
1003 testInvokeOnPool(mainPool(), a);
1004 }
1005
1006 /**
1007 * tryUnfork returns true for most recent unexecuted task,
1008 * and suppresses execution
1009 */
1010 public void testTryUnfork() {
1011 RecursiveAction a = new CheckedRecursiveAction() {
1012 public void realCompute() {
1013 FibAction g = new FibAction(9);
1014 assertSame(g, g.fork());
1015 FibAction f = new FibAction(8);
1016 assertSame(f, f.fork());
1017 assertTrue(f.tryUnfork());
1018 helpQuiesce();
1019 checkNotDone(f);
1020 checkCompletedNormally(g);
1021 }};
1022 testInvokeOnPool(singletonPool(), a);
1023 }
1024
1025 /**
1026 * getSurplusQueuedTaskCount returns > 0 when
1027 * there are more tasks than threads
1028 */
1029 public void testGetSurplusQueuedTaskCount() {
1030 RecursiveAction a = new CheckedRecursiveAction() {
1031 public void realCompute() {
1032 FibAction h = new FibAction(7);
1033 assertSame(h, h.fork());
1034 FibAction g = new FibAction(9);
1035 assertSame(g, g.fork());
1036 FibAction f = new FibAction(8);
1037 assertSame(f, f.fork());
1038 assertTrue(getSurplusQueuedTaskCount() > 0);
1039 helpQuiesce();
1040 assertEquals(0, getSurplusQueuedTaskCount());
1041 checkCompletedNormally(f);
1042 checkCompletedNormally(g);
1043 checkCompletedNormally(h);
1044 }};
1045 testInvokeOnPool(singletonPool(), a);
1046 }
1047
1048 /**
1049 * peekNextLocalTask returns most recent unexecuted task.
1050 */
1051 public void testPeekNextLocalTask() {
1052 RecursiveAction a = new CheckedRecursiveAction() {
1053 public void realCompute() {
1054 FibAction g = new FibAction(9);
1055 assertSame(g, g.fork());
1056 FibAction f = new FibAction(8);
1057 assertSame(f, f.fork());
1058 assertSame(f, peekNextLocalTask());
1059 assertNull(f.join());
1060 checkCompletedNormally(f);
1061 helpQuiesce();
1062 checkCompletedNormally(f);
1063 checkCompletedNormally(g);
1064 }};
1065 testInvokeOnPool(singletonPool(), a);
1066 }
1067
1068 /**
1069 * pollNextLocalTask returns most recent unexecuted task
1070 * without executing it
1071 */
1072 public void testPollNextLocalTask() {
1073 RecursiveAction a = new CheckedRecursiveAction() {
1074 public void realCompute() {
1075 FibAction g = new FibAction(9);
1076 assertSame(g, g.fork());
1077 FibAction f = new FibAction(8);
1078 assertSame(f, f.fork());
1079 assertSame(f, pollNextLocalTask());
1080 helpQuiesce();
1081 checkNotDone(f);
1082 checkCompletedNormally(g);
1083 }};
1084 testInvokeOnPool(singletonPool(), a);
1085 }
1086
1087 /**
1088 * pollTask returns an unexecuted task without executing it
1089 */
1090 public void testPollTask() {
1091 RecursiveAction a = new CheckedRecursiveAction() {
1092 public void realCompute() {
1093 FibAction g = new FibAction(9);
1094 assertSame(g, g.fork());
1095 FibAction f = new FibAction(8);
1096 assertSame(f, f.fork());
1097 assertSame(f, pollTask());
1098 helpQuiesce();
1099 checkNotDone(f);
1100 checkCompletedNormally(g);
1101 }};
1102 testInvokeOnPool(singletonPool(), a);
1103 }
1104
1105 /**
1106 * peekNextLocalTask returns least recent unexecuted task in async mode
1107 */
1108 public void testPeekNextLocalTaskAsync() {
1109 RecursiveAction a = new CheckedRecursiveAction() {
1110 public void realCompute() {
1111 FibAction g = new FibAction(9);
1112 assertSame(g, g.fork());
1113 FibAction f = new FibAction(8);
1114 assertSame(f, f.fork());
1115 assertSame(g, peekNextLocalTask());
1116 assertNull(f.join());
1117 helpQuiesce();
1118 checkCompletedNormally(f);
1119 checkCompletedNormally(g);
1120 }};
1121 testInvokeOnPool(asyncSingletonPool(), a);
1122 }
1123
1124 /**
1125 * pollNextLocalTask returns least recent unexecuted task without
1126 * executing it, in async mode
1127 */
1128 public void testPollNextLocalTaskAsync() {
1129 RecursiveAction a = new CheckedRecursiveAction() {
1130 public void realCompute() {
1131 FibAction g = new FibAction(9);
1132 assertSame(g, g.fork());
1133 FibAction f = new FibAction(8);
1134 assertSame(f, f.fork());
1135 assertSame(g, pollNextLocalTask());
1136 helpQuiesce();
1137 checkCompletedNormally(f);
1138 checkNotDone(g);
1139 }};
1140 testInvokeOnPool(asyncSingletonPool(), a);
1141 }
1142
1143 /**
1144 * pollTask returns an unexecuted task without executing it, in
1145 * async mode
1146 */
1147 public void testPollTaskAsync() {
1148 RecursiveAction a = new CheckedRecursiveAction() {
1149 public void realCompute() {
1150 FibAction g = new FibAction(9);
1151 assertSame(g, g.fork());
1152 FibAction f = new FibAction(8);
1153 assertSame(f, f.fork());
1154 assertSame(g, pollTask());
1155 helpQuiesce();
1156 checkCompletedNormally(f);
1157 checkNotDone(g);
1158 }};
1159 testInvokeOnPool(asyncSingletonPool(), a);
1160 }
1161
1162 }