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