ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.27
Committed: Wed Aug 24 22:22:39 2016 UTC (7 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.26: +0 -1 lines
Log Message:
fix imports

File Contents

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