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