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