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