ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.18
Committed: Sun Oct 4 18:40:57 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.17: +22 -26 lines
Log Message:
PoolCleaning

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