1 //****************************************************************************** 2 // 3 // File: ParallelRegion.java 4 // Package: edu.rit.pj 5 // Unit: Class edu.rit.pj.ParallelRegion 6 // 7 // This Java source file is copyright (C) 2007 by Alan Kaminsky. All rights 8 // reserved. For further information, contact the author, Alan Kaminsky, at 9 // ark@cs.rit.edu. 10 // 11 // This Java source file is part of the Parallel Java Library ("PJ"). PJ is free 12 // software; you can redistribute it and/or modify it under the terms of the GNU 13 // General Public License as published by the Free Software Foundation; either 14 // version 3 of the License, or (at your option) any later version. 15 // 16 // PJ is distributed in the hope that it will be useful, but WITHOUT ANY 17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 18 // A PARTICULAR PURPOSE. See the GNU General Public License for more details. 19 // 20 // Linking this library statically or dynamically with other modules is making a 21 // combined work based on this library. Thus, the terms and conditions of the GNU 22 // General Public License cover the whole combination. 23 // 24 // As a special exception, the copyright holders of this library give you 25 // permission to link this library with independent modules to produce an 26 // executable, regardless of the license terms of these independent modules, and 27 // to copy and distribute the resulting executable under terms of your choice, 28 // provided that you also meet, for each linked independent module, the terms 29 // and conditions of the license of that module. An independent module is a module 30 // which is not derived from or based on this library. If you modify this library, 31 // you may extend this exception to your version of the library, but you are not 32 // obligated to do so. If you do not wish to do so, delete this exception 33 // statement from your version. 34 // 35 // A copy of the GNU General Public License is provided in the file gpl.txt. You 36 // may also obtain a copy of the GNU General Public License on the World Wide 37 // Web at http://www.gnu.org/licenses/gpl.html. 38 // 39 //****************************************************************************** 40 package edu.rit.pj; 41 42 import java.util.Iterator; 43 44 import edu.rit.util.LongRange; 45 import edu.rit.util.Range; 46 47 /** 48 * Class ParallelRegion is the abstract base class for a parallel region that is 49 * executed by a {@linkplain ParallelTeam} of threads. 50 * <P> 51 * To execute a parallel region, create a {@linkplain ParallelTeam} object; 52 * create an instance of a concrete subclass of class ParallelRegion; and pass 53 * this instance to the parallel team's <code>execute()</code> method. You can do 54 * all this using an anonymous inner class; for example: 55 * <PRE> 56 * new ParallelTeam().execute (new ParallelRegion() 57 * { 58 * // Shared variable declarations 59 * . . . 60 * public void start() 61 * { 62 * // Initialization code 63 * . . . 64 * } 65 * public void run() 66 * { 67 * // Thread private variable declarations 68 * // Parallel code 69 * . . . 70 * } 71 * public void finish() 72 * { 73 * // Finalization code 74 * . . . 75 * } 76 * }); 77 * </PRE> 78 * <P> 79 * The parallel team's <code>execute()</code> method does the following. The 80 * parallel team has a certain number of threads <I>K</I>, where <I>K</I> was 81 * specified when the parallel team was constructed. The main thread is the 82 * thread calling the parallel team's <code>execute()</code> method. The main thread 83 * calls the parallel region's <code>start()</code> method. When the 84 * <code>start()</code> method returns, all the team threads call the parallel 85 * region's <code>run()</code> method concurrently. When all the team threads have 86 * returned from the <code>run()</code> method, the main thread calls the parallel 87 * region's <code>finish()</code> method. When the <code>finish()</code> method returns, 88 * the main thread returns from the parallel team's <code>execute()</code> method. 89 * <P> 90 * Variables to be shared by all threads in the team may be declared as fields 91 * of the ParallelRegion subclass. The <code>start()</code> method is intended for 92 * performing initialization in a single thread before parallel execution 93 * begins. If no such initialization is needed, omit the <code>start()</code> 94 * method. The <code>run()</code> method contains code to be executed in parallel by 95 * all threads in the team. Variables that are private to each thread may be 96 * declared inside the <code>run()</code> method. The <code>finish()</code> method is 97 * intended for performing finalization in a single thread after parallel 98 * execution ends. If no such finalization is needed, omit the <code>finish()</code> 99 * method. 100 * <P> 101 * If the parallel region's <code>start()</code> method throws an exception, the 102 * parallel team's <code>execute()</code> method throws that same exception, and the 103 * <code>run()</code> method is not called. 104 * <P> 105 * If the parallel region's <code>run()</code> method throws an exception in one of 106 * the team threads, the exception's stack trace is printed on the standard 107 * error, the parallel team waits until all the other team threads have returned 108 * from the <code>run()</code> method, then the parallel team's <code>execute()</code> 109 * method throws that same exception, and the parallel region's 110 * <code>finish()</code> method is not called. If the parallel region's 111 * <code>run()</code> method throws an exception in more than one of the team 112 * threads, each exception's stack trace is printed on the standard error, the 113 * parallel team waits until all the other team threads have returned from the 114 * <code>run()</code> method, then the parallel team's <code>execute()</code> method 115 * throws a {@linkplain MultipleParallelException} wrapping all the thrown 116 * exceptions, and the parallel region's <code>finish()</code> method is not called. 117 * <P> 118 * If the parallel region's <code>finish()</code> method throws an exception, the 119 * parallel team's <code>execute()</code> method throws that same exception. 120 * 121 * @author Alan Kaminsky 122 * @version 11-Nov-2007 123 */ 124 public abstract class ParallelRegion 125 extends ParallelConstruct { 126 127 // Hidden data members. 128 // Default lock for critical() and criticalNonexclusive() methods. 129 private Lock myLock = new Lock(); 130 131 // Exported constructors. 132 /** 133 * Construct a new parallel region. 134 */ 135 public ParallelRegion() { 136 super(); 137 } 138 139 // Exported operations. 140 /** 141 * Perform initialization actions before parallel execution begins. Only one 142 * thread calls the <code>start()</code> method. 143 * <P> 144 * The <code>start()</code> method may be overridden in a subclass. If not 145 * overridden, the <code>start()</code> method does nothing. 146 * 147 * @exception Exception The <code>start()</code> method may throw any exception. 148 * @throws java.lang.Exception if any. 149 */ 150 public void start() 151 throws Exception { 152 } 153 154 /** 155 * Execute parallel code. All threads of the parallel team call the 156 * <code>run()</code> method concurrently. 157 * <P> 158 * The <code>run()</code> method must be implemented in a subclass. 159 * 160 * @exception Exception The <code>run()</code> method may throw any exception. 161 * @throws java.lang.Exception if any. 162 */ 163 public abstract void run() 164 throws Exception; 165 166 /** 167 * Perform finalization actions after parallel execution ends. Only one 168 * thread calls the <code>finish()</code> method. 169 * <P> 170 * The <code>finish()</code> method may be overridden in a subclass. If not 171 * overridden, the <code>finish()</code> method does nothing. 172 * 173 * @exception Exception The <code>finish()</code> method may throw any 174 * exception. 175 * @throws java.lang.Exception if any. 176 */ 177 public void finish() 178 throws Exception { 179 } 180 181 /** 182 * Execute a parallel for loop within this parallel region. For further 183 * information, see class {@linkplain IntegerForLoop}. The loop index goes 184 * from <code>first</code> (inclusive) to <code>last</code> (inclusive) in steps of 185 * +1. If <code>first</code> is greater than <code>last</code>, then no loop 186 * iterations are performed. At the end of the parallel for loop, the 187 * parallel team threads wait for each other at a barrier. 188 * <P> 189 * <I>Note:</I> Either all threads in the parallel team must call the 190 * <code>execute()</code> method with identical arguments, or none of the 191 * threads must call the <code>execute()</code> method. 192 * 193 * @param first First loop index. 194 * @param last Last loop index. 195 * @param theLoop Parallel for loop. 196 * @exception NullPointerException (unchecked exception) Thrown if 197 * <code>theLoop</code> is null. 198 * @exception IllegalStateException (unchecked exception) Thrown if no 199 * parallel team is executing this parallel region. 200 * @exception Exception Thrown if one of <code>theLoop</code>'s methods throws 201 * an exception. 202 * @throws java.lang.Exception if any. 203 */ 204 public final void execute(int first, 205 int last, 206 IntegerForLoop theLoop) 207 throws Exception { 208 execute(first, last, theLoop, BarrierAction.WAIT); 209 } 210 211 /** 212 * Execute a parallel for loop within this parallel region. For further 213 * information, see class {@linkplain IntegerForLoop}. The loop index goes 214 * from <code>first</code> (inclusive) to <code>last</code> (inclusive) in steps of 215 * +1. If <code>first</code> is greater than <code>last</code>, then no loop 216 * iterations are performed. At the end of the parallel for loop, the 217 * parallel team threads encounter a barrier, and their behavior depends on 218 * the given {@linkplain BarrierAction}. 219 * <P> 220 * <I>Note:</I> Either all threads in the parallel team must call the 221 * <code>execute()</code> method with identical arguments, or none of the 222 * threads must call the <code>execute()</code> method. 223 * 224 * @param first First loop index. 225 * @param last Last loop index. 226 * @param theLoop Parallel for loop. 227 * @param action Barrier action. 228 * @exception NullPointerException (unchecked exception) Thrown if 229 * <code>theLoop</code> is null. Thrown if 230 * <code>action</code> is null. 231 * @exception IllegalStateException (unchecked exception) Thrown if no 232 * parallel team is executing this parallel region. 233 * @exception Exception Thrown if one of <code>theLoop</code>'s methods throws 234 * an exception. 235 * @throws java.lang.Exception if any. 236 */ 237 public final void execute(int first, 238 int last, 239 IntegerForLoop theLoop, 240 BarrierAction action) 241 throws Exception { 242 // Verify preconditions. 243 if (theLoop == null) { 244 throw new NullPointerException("ParallelRegion.execute(): Parallel for loop is null"); 245 } 246 if (action == null) { 247 throw new NullPointerException("ParallelRegion.execute(): Barrier action is null"); 248 } 249 if (myTeam == null) { 250 throw new IllegalStateException("ParallelRegion.execute(): No parallel team executing"); 251 } 252 253 try { 254 // Record parallel team. 255 theLoop.myTeam = this.myTeam; 256 257 // Get current parallel team thread. 258 ParallelTeamThread currentThread = getCurrentThread(); 259 int currentIndex = currentThread.myIndex; 260 261 // Do top-of-parallel-construct processing. 262 IntegerSchedule schedule = null; 263 if (currentThread.arriveAtParallelConstruct()) { 264 // First thread to arrive sets up the shared parallel for loop 265 // schedule object and stores it (or an exception if any) in 266 // each team thread. 267 try { 268 schedule = theLoop.schedule(); 269 schedule.commonStart(myTeam.K, new Range(first, last)); 270 for (ParallelTeamThread thread : myTeam.myThread) { 271 thread.setIntegerSchedule(schedule); 272 } 273 } catch (Throwable exc) { 274 for (ParallelTeamThread thread : myTeam.myThread) { 275 thread.setConstructException(exc); 276 } 277 } 278 } 279 280 // Get the shared parallel for loop schedule object. 281 schedule = currentThread.getIntegerSchedule(); 282 theLoop.mySchedule = schedule; 283 284 // Prepare to catch exceptions thrown by the parallel for loop body. 285 Throwable runException = null; 286 try { 287 // Perform per-thread initialization. 288 theLoop.start(); 289 290 // Repeatedly get and process a chunk of loop iterations. 291 Range chunk; 292 while ((chunk = schedule.commonNext(currentIndex)) != null) { 293 theLoop.commonRun(chunk.lb(), chunk.ub()); 294 } 295 296 // Perform per-thread finalization. 297 theLoop.finish(); 298 } catch (Throwable exc) { 299 runException = exc; 300 schedule.myBreak = true; 301 } 302 303 // Barrier synchronization. 304 action.doBarrier(currentThread); 305 306 // Propagate any exception thrown by the run() method. 307 ParallelTeam.rethrow(runException); 308 } finally { 309 // Forget parallel team. 310 theLoop.myTeam = null; 311 theLoop.mySchedule = null; 312 } 313 } 314 315 /** 316 * Execute a parallel for loop within this parallel region. For further 317 * information, see class {@linkplain IntegerStrideForLoop}. The loop index 318 * goes from <code>first</code> (inclusive) to <code>last</code> (inclusive) in 319 * steps of <code>stride</code>. The stride must be positive. If <code>first</code> 320 * is greater than <code>last</code>, then no loop iterations are performed. At 321 * the end of the parallel for loop, the parallel team threads wait for each 322 * other at a barrier. 323 * <P> 324 * <I>Note:</I> Either all threads in the parallel team must call the 325 * <code>execute()</code> method with identical arguments, or none of the 326 * threads must call the <code>execute()</code> method. 327 * 328 * @param first First loop index. 329 * @param last Last loop index. 330 * @param stride Loop index stride, >= 1. 331 * @param theLoop Parallel for loop. 332 * @exception IllegalArgumentException (unchecked exception) Thrown if 333 * <code>stride</code> < 1. 334 * @exception NullPointerException (unchecked exception) Thrown if 335 * <code>theLoop</code> is null. 336 * @exception IllegalStateException (unchecked exception) Thrown if no 337 * parallel team is executing this parallel region. 338 * @exception Exception Thrown if one of <code>theLoop</code>'s methods throws 339 * an exception. 340 * @throws java.lang.Exception if any. 341 */ 342 public final void execute(int first, 343 int last, 344 int stride, 345 IntegerStrideForLoop theLoop) 346 throws Exception { 347 execute(first, last, stride, theLoop, BarrierAction.WAIT); 348 } 349 350 /** 351 * Execute a parallel for loop within this parallel region. For further 352 * information, see class {@linkplain IntegerStrideForLoop}. The loop index 353 * goes from <code>first</code> (inclusive) to <code>last</code> (inclusive) in 354 * steps of <code>stride</code>. The stride must be positive. If <code>first</code> 355 * is greater than <code>last</code>, then no loop iterations are performed. At 356 * the end of the parallel for loop, the parallel team threads encounter a 357 * barrier, and their behavior depends on the given {@linkplain 358 * BarrierAction}. 359 * <P> 360 * <I>Note:</I> Either all threads in the parallel team must call the 361 * <code>execute()</code> method with identical arguments, or none of the 362 * threads must call the <code>execute()</code> method. 363 * 364 * @param first First loop index. 365 * @param last Last loop index. 366 * @param stride Loop index stride, >= 1. 367 * @param theLoop Parallel for loop. 368 * @param action Barrier action. 369 * @exception IllegalArgumentException (unchecked exception) Thrown if 370 * <code>stride</code> < 1. 371 * @exception NullPointerException (unchecked exception) Thrown if 372 * <code>theLoop</code> is null. Thrown if 373 * <code>action</code> is null. 374 * @exception IllegalStateException (unchecked exception) Thrown if no 375 * parallel team is executing this parallel region. 376 * @exception Exception Thrown if one of <code>theLoop</code>'s methods throws 377 * an exception. 378 * @throws java.lang.Exception if any. 379 */ 380 public final void execute(int first, 381 int last, 382 int stride, 383 IntegerStrideForLoop theLoop, 384 BarrierAction action) 385 throws Exception { 386 // Verify preconditions. 387 if (stride <= 0) { 388 throw new IllegalArgumentException("ParallelRegion.execute(): Stride = " + stride + " illegal"); 389 } 390 if (theLoop == null) { 391 throw new NullPointerException("ParallelRegion.execute(): Parallel for loop is null"); 392 } 393 if (action == null) { 394 throw new NullPointerException("ParallelRegion.execute(): Barrier action is null"); 395 } 396 if (myTeam == null) { 397 throw new IllegalStateException("ParallelRegion.execute(): No parallel team executing"); 398 } 399 400 try { 401 // Record parallel team. 402 theLoop.myTeam = this.myTeam; 403 404 // Get current parallel team thread. 405 ParallelTeamThread currentThread = getCurrentThread(); 406 int currentIndex = currentThread.myIndex; 407 408 // Do top-of-parallel-construct processing. 409 IntegerSchedule schedule = null; 410 if (currentThread.arriveAtParallelConstruct()) { 411 // First thread to arrive sets up the shared parallel for loop 412 // schedule object and stores it (or an exception if any) in 413 // each team thread. 414 try { 415 schedule = theLoop.schedule(); 416 schedule.commonStart(myTeam.K, new Range(first, last, stride)); 417 for (ParallelTeamThread thread : myTeam.myThread) { 418 thread.setIntegerSchedule(schedule); 419 } 420 } catch (Throwable exc) { 421 for (ParallelTeamThread thread : myTeam.myThread) { 422 thread.setConstructException(exc); 423 } 424 } 425 } 426 427 // Get the shared parallel for loop schedule object. 428 schedule = currentThread.getIntegerSchedule(); 429 theLoop.mySchedule = schedule; 430 431 // Prepare to catch exceptions thrown by the parallel for loop body. 432 Throwable runException = null; 433 try { 434 // Perform per-thread initialization. 435 theLoop.start(); 436 437 // Repeatedly get and process a chunk of loop iterations. 438 Range chunk; 439 while ((chunk = schedule.commonNext(currentIndex)) != null) { 440 theLoop.commonRun(chunk.lb(), chunk.ub(), chunk.stride()); 441 } 442 443 // Perform per-thread finalization. 444 theLoop.finish(); 445 } catch (Throwable exc) { 446 runException = exc; 447 schedule.myBreak = true; 448 } 449 450 // Barrier synchronization. 451 action.doBarrier(currentThread); 452 453 // Propagate any exception thrown by the run() method. 454 ParallelTeam.rethrow(runException); 455 } finally { 456 // Forget parallel team. 457 theLoop.myTeam = null; 458 theLoop.mySchedule = null; 459 } 460 } 461 462 /** 463 * Execute a parallel for loop within this parallel region. For further 464 * information, see class {@linkplain LongForLoop}. The loop index goes from 465 * <code>first</code> (inclusive) to <code>last</code> (inclusive) in steps of +1. 466 * If <code>first</code> is greater than <code>last</code>, then no loop iterations 467 * are performed. At the end of the parallel for loop, the parallel team 468 * threads wait for each other at a barrier. 469 * <P> 470 * <I>Note:</I> Either all threads in the parallel team must call the 471 * <code>execute()</code> method with identical arguments, or none of the 472 * threads must call the <code>execute()</code> method. 473 * 474 * @param first First loop index. 475 * @param last Last loop index. 476 * @param theLoop Parallel for loop. 477 * @exception NullPointerException (unchecked exception) Thrown if 478 * <code>theLoop</code> is null. 479 * @exception IllegalStateException (unchecked exception) Thrown if no 480 * parallel team is executing this parallel region. 481 * @exception Exception Thrown if one of <code>theLoop</code>'s methods throws 482 * an exception. 483 * @throws java.lang.Exception if any. 484 */ 485 public final void execute(long first, 486 long last, 487 LongForLoop theLoop) 488 throws Exception { 489 execute(first, last, theLoop, BarrierAction.WAIT); 490 } 491 492 /** 493 * Execute a parallel for loop within this parallel region. For further 494 * information, see class {@linkplain LongForLoop}. The loop index goes from 495 * <code>first</code> (inclusive) to <code>last</code> (inclusive) in steps of +1. 496 * If <code>first</code> is greater than <code>last</code>, then no loop iterations 497 * are performed. At the end of the parallel for loop, the parallel team 498 * threads encounter a barrier, and their behavior depends on the given 499 * {@linkplain BarrierAction}. 500 * <P> 501 * <I>Note:</I> Either all threads in the parallel team must call the 502 * <code>execute()</code> method with identical arguments, or none of the 503 * threads must call the <code>execute()</code> method. 504 * 505 * @param first First loop index. 506 * @param last Last loop index. 507 * @param theLoop Parallel for loop. 508 * @param action Barrier action. 509 * @exception NullPointerException (unchecked exception) Thrown if 510 * <code>theLoop</code> is null. Thrown if 511 * <code>action</code> is null. 512 * @exception IllegalStateException (unchecked exception) Thrown if no 513 * parallel team is executing this parallel region. 514 * @exception Exception Thrown if one of <code>theLoop</code>'s methods throws 515 * an exception. 516 * @throws java.lang.Exception if any. 517 */ 518 public final void execute(long first, 519 long last, 520 LongForLoop theLoop, 521 BarrierAction action) 522 throws Exception { 523 // Verify preconditions. 524 if (theLoop == null) { 525 throw new NullPointerException("ParallelRegion.execute(): Parallel for loop is null"); 526 } 527 if (action == null) { 528 throw new NullPointerException("ParallelRegion.execute(): Barrier action is null"); 529 } 530 if (myTeam == null) { 531 throw new IllegalStateException("ParallelRegion.execute(): No parallel team executing"); 532 } 533 534 try { 535 // Record parallel team. 536 theLoop.myTeam = this.myTeam; 537 538 // Get current parallel team thread. 539 ParallelTeamThread currentThread = getCurrentThread(); 540 int currentIndex = currentThread.myIndex; 541 542 // Do top-of-parallel-construct processing. 543 LongSchedule schedule = null; 544 if (currentThread.arriveAtParallelConstruct()) { 545 // First thread to arrive sets up the shared parallel for loop 546 // schedule object and stores it (or an exception if any) in 547 // each team thread. 548 try { 549 schedule = theLoop.schedule(); 550 schedule.commonStart(myTeam.K, new LongRange(first, last)); 551 for (ParallelTeamThread thread : myTeam.myThread) { 552 thread.setLongSchedule(schedule); 553 } 554 } catch (Throwable exc) { 555 for (ParallelTeamThread thread : myTeam.myThread) { 556 thread.setConstructException(exc); 557 } 558 } 559 } 560 561 // Get the shared parallel for loop schedule object. 562 schedule = currentThread.getLongSchedule(); 563 theLoop.mySchedule = schedule; 564 565 // Prepare to catch exceptions thrown by the parallel for loop body. 566 Throwable runException = null; 567 try { 568 // Perform per-thread initialization. 569 theLoop.start(); 570 571 // Repeatedly get and process a chunk of loop iterations. 572 LongRange chunk; 573 while ((chunk = schedule.commonNext(currentIndex)) != null) { 574 theLoop.commonRun(chunk.lb(), chunk.ub()); 575 } 576 577 // Perform per-thread finalization. 578 theLoop.finish(); 579 } catch (Throwable exc) { 580 runException = exc; 581 schedule.myBreak = true; 582 } 583 584 // Barrier synchronization. 585 action.doBarrier(currentThread); 586 587 // Propagate any exception thrown by the run() method. 588 ParallelTeam.rethrow(runException); 589 } finally { 590 // Forget parallel team. 591 theLoop.myTeam = null; 592 theLoop.mySchedule = null; 593 } 594 } 595 596 /** 597 * Execute a parallel for loop within this parallel region. For further 598 * information, see class {@linkplain LongStrideForLoop}. The loop index 599 * goes from <code>first</code> (inclusive) to <code>last</code> (inclusive) in 600 * steps of <code>stride</code>. The stride must be positive. If <code>first</code> 601 * is greater than <code>last</code>, then no loop iterations are performed. At 602 * the end of the parallel for loop, the parallel team threads wait for each 603 * other at a barrier. 604 * <P> 605 * <I>Note:</I> Either all threads in the parallel team must call the 606 * <code>execute()</code> method with identical arguments, or none of the 607 * threads must call the <code>execute()</code> method. 608 * 609 * @param first First loop index. 610 * @param last Last loop index. 611 * @param stride Loop index stride, >= 1. 612 * @param theLoop Parallel for loop. 613 * @exception IllegalArgumentException (unchecked exception) Thrown if 614 * <code>stride</code> < 1. 615 * @exception NullPointerException (unchecked exception) Thrown if 616 * <code>theLoop</code> is null. 617 * @exception IllegalStateException (unchecked exception) Thrown if no 618 * parallel team is executing this parallel region. 619 * @exception Exception Thrown if one of <code>theLoop</code>'s methods throws 620 * an exception. 621 * @throws java.lang.Exception if any. 622 */ 623 public final void execute(long first, 624 long last, 625 long stride, 626 LongStrideForLoop theLoop) 627 throws Exception { 628 execute(first, last, stride, theLoop, BarrierAction.WAIT); 629 } 630 631 /** 632 * Execute a parallel for loop within this parallel region. For further 633 * information, see class {@linkplain LongStrideForLoop}. The loop index 634 * goes from <code>first</code> (inclusive) to <code>last</code> (inclusive) in 635 * steps of <code>stride</code>. The stride must be positive. If <code>first</code> 636 * is greater than <code>last</code>, then no loop iterations are performed. At 637 * the end of the parallel for loop, the parallel team threads encounter a 638 * barrier, and their behavior depends on the given {@linkplain 639 * BarrierAction}. 640 * <P> 641 * <I>Note:</I> Either all threads in the parallel team must call the 642 * <code>execute()</code> method with identical arguments, or none of the 643 * threads must call the <code>execute()</code> method. 644 * 645 * @param first First loop index. 646 * @param last Last loop index. 647 * @param stride Loop index stride, >= 1. 648 * @param theLoop Parallel for loop. 649 * @param action Barrier action. 650 * @exception IllegalArgumentException (unchecked exception) Thrown if 651 * <code>stride</code> < 1. 652 * @exception NullPointerException (unchecked exception) Thrown if 653 * <code>theLoop</code> is null. Thrown if 654 * <code>action</code> is null. 655 * @exception IllegalStateException (unchecked exception) Thrown if no 656 * parallel team is executing this parallel region. 657 * @exception Exception Thrown if one of <code>theLoop</code>'s methods throws 658 * an exception. 659 * @throws java.lang.Exception if any. 660 */ 661 public final void execute(long first, 662 long last, 663 long stride, 664 LongStrideForLoop theLoop, 665 BarrierAction action) 666 throws Exception { 667 // Verify preconditions. 668 if (stride <= 0) { 669 throw new IllegalArgumentException("ParallelRegion.execute(): Stride = " + stride + " illegal"); 670 } 671 if (theLoop == null) { 672 throw new NullPointerException("ParallelRegion.execute(): Parallel for loop is null"); 673 } 674 if (action == null) { 675 throw new NullPointerException("ParallelRegion.execute(): Barrier action is null"); 676 } 677 if (myTeam == null) { 678 throw new IllegalStateException("ParallelRegion.execute(): No parallel team executing"); 679 } 680 681 try { 682 // Record parallel team. 683 theLoop.myTeam = this.myTeam; 684 685 // Get current parallel team thread. 686 ParallelTeamThread currentThread = getCurrentThread(); 687 int currentIndex = currentThread.myIndex; 688 689 // Do top-of-parallel-construct processing. 690 LongSchedule schedule = null; 691 if (currentThread.arriveAtParallelConstruct()) { 692 // First thread to arrive sets up the shared parallel for loop 693 // schedule object and stores it (or an exception if any) in 694 // each team thread. 695 try { 696 schedule = theLoop.schedule(); 697 schedule.commonStart(myTeam.K, new LongRange(first, last, stride)); 698 for (ParallelTeamThread thread : myTeam.myThread) { 699 thread.setLongSchedule(schedule); 700 } 701 } catch (Throwable exc) { 702 for (ParallelTeamThread thread : myTeam.myThread) { 703 thread.setConstructException(exc); 704 } 705 } 706 } 707 708 // Get the shared parallel for loop schedule object. 709 schedule = currentThread.getLongSchedule(); 710 theLoop.mySchedule = schedule; 711 712 // Prepare to catch exceptions thrown by the parallel for loop body. 713 Throwable runException = null; 714 try { 715 // Perform per-thread initialization. 716 theLoop.start(); 717 718 // Repeatedly get and process a chunk of loop iterations. 719 LongRange chunk; 720 while ((chunk = schedule.commonNext(currentIndex)) != null) { 721 theLoop.commonRun(chunk.lb(), chunk.ub(), chunk.stride()); 722 } 723 724 // Perform per-thread finalization. 725 theLoop.finish(); 726 } catch (Throwable exc) { 727 runException = exc; 728 schedule.myBreak = true; 729 } 730 731 // Barrier synchronization. 732 action.doBarrier(currentThread); 733 734 // Propagate any exception thrown by the run() method. 735 ParallelTeam.rethrow(runException); 736 } finally { 737 // Forget parallel team. 738 theLoop.myTeam = null; 739 theLoop.mySchedule = null; 740 } 741 } 742 743 /** 744 * Execute a parallel iteration within this parallel region. For further 745 * information, see class {@linkplain ParallelIteration}. The items 746 * processed by the iteration are the elements of the given array. The 747 * iteration order is from index 0 upwards. At the end of the parallel 748 * iteration, the parallel team threads wait for each other at a barrier. 749 * <P> 750 * <I>Note:</I> Either all threads in the parallel team must call the 751 * <code>execute()</code> method with identical arguments, or none of the 752 * threads must call the <code>execute()</code> method. 753 * 754 * @param <T> Data type of the items iterated over. 755 * @param theArray Array containing the items. 756 * @param theIteration Parallel iteration. 757 * @exception NullPointerException (unchecked exception) Thrown if 758 * <code>theArray</code> is null or 759 * <code>theIteration</code> is null. 760 * @exception IllegalStateException (unchecked exception) Thrown if no 761 * parallel team is executing this parallel region. 762 * @exception Exception Thrown if one of <code>theIteration</code>'s methods 763 * throws an exception. 764 * @throws java.lang.Exception if any. 765 */ 766 public final <T> void execute(T[] theArray, 767 ParallelIteration<T> theIteration) 768 throws Exception { 769 execute(theArray, theIteration, BarrierAction.WAIT); 770 } 771 772 /** 773 * Suppress warnings for casts of ItemGenerator. 774 * @param obj The ItemGenerator instance. 775 * @param <T> Data type of the items iterated over. 776 * @return 777 */ 778 @SuppressWarnings("unchecked") 779 private static <T> ItemGenerator<T> castItemGenerator(Object obj) { 780 return (ItemGenerator<T>) obj; 781 } 782 783 /** 784 * Execute a parallel iteration within this parallel region. For further 785 * information, see class {@linkplain ParallelIteration}. The items 786 * processed by the iteration are the elements of the given array. The 787 * iteration order is from index 0 upwards. At the end of the parallel 788 * iteration, the parallel team threads encounter a barrier, and their 789 * behavior depends on the given {@linkplain BarrierAction}. 790 * <P> 791 * <I>Note:</I> Either all threads in the parallel team must call the 792 * <code>execute()</code> method with identical arguments, or none of the 793 * threads must call the <code>execute()</code> method. 794 * 795 * @param <T> Data type of the items iterated over. 796 * @param theArray Array containing the items. 797 * @param theIteration Parallel iteration. 798 * @param action Barrier action. 799 * @exception NullPointerException (unchecked exception) Thrown if 800 * <code>theArray</code> is null. Thrown if 801 * <code>theIteration</code> is null. Thrown if <code>action</code> is null. 802 * @exception IllegalStateException (unchecked exception) Thrown if no 803 * parallel team is executing this parallel region. 804 * @exception Exception Thrown if one of <code>theIteration</code>'s methods 805 * throws an exception. 806 * @throws java.lang.Exception if any. 807 */ 808 public final <T> void execute(T[] theArray, 809 ParallelIteration<T> theIteration, 810 BarrierAction action) 811 throws Exception { 812 // Verify preconditions. 813 if (theArray == null) { 814 throw new NullPointerException("ParallelRegion.execute(): Array is null"); 815 } 816 if (theIteration == null) { 817 throw new NullPointerException("ParallelRegion.execute(): Parallel iteration is null"); 818 } 819 if (action == null) { 820 throw new NullPointerException("ParallelRegion.execute(): Barrier action is null"); 821 } 822 if (myTeam == null) { 823 throw new IllegalStateException("ParallelRegion.execute(): No parallel team executing"); 824 } 825 826 try { 827 // Record parallel team. 828 theIteration.myTeam = this.myTeam; 829 830 // Get current parallel team thread. 831 ParallelTeamThread currentThread = getCurrentThread(); 832 833 // Do top-of-parallel-construct processing. 834 ItemGenerator<T> generator = null; 835 if (currentThread.arriveAtParallelConstruct()) { 836 // First thread to arrive sets up the shared item generator 837 // object and stores it (or an exception if any) in each team 838 // thread. 839 try { 840 generator = new ArrayItemGenerator<T>(theArray); 841 for (ParallelTeamThread thread : myTeam.myThread) { 842 thread.setItemGenerator(generator); 843 } 844 } catch (Throwable exc) { 845 for (ParallelTeamThread thread : myTeam.myThread) { 846 thread.setConstructException(exc); 847 } 848 } 849 } 850 851 // Get the shared item generator object. 852 generator = castItemGenerator(currentThread.getItemGenerator()); 853 theIteration.myItemGenerator = generator; 854 855 // Prepare to catch exceptions thrown by the parallel iteration 856 // body. 857 Throwable runException = null; 858 try { 859 // Perform per-thread initialization. 860 theIteration.start(); 861 862 // Repeatedly get and process an item. 863 ItemHolder<T> itemholder; 864 while ((itemholder = generator.nextItem()) != null) { 865 theIteration.commonRun(itemholder.mySequenceNumber, itemholder.myItem); 866 } 867 868 // Perform per-thread finalization. 869 theIteration.finish(); 870 } catch (Throwable exc) { 871 runException = exc; 872 generator.myBreak = true; 873 } 874 875 // Barrier synchronization. 876 action.doBarrier(currentThread); 877 878 // Propagate any exception thrown by the run() method. 879 ParallelTeam.rethrow(runException); 880 } finally { 881 // Forget parallel team. 882 theIteration.myTeam = null; 883 theIteration.myItemGenerator = null; 884 } 885 } 886 887 /** 888 * Execute a parallel iteration within this parallel region. For further 889 * information, see class {@linkplain ParallelIteration}. The items 890 * processed by the iteration are the items returned by the given iterator. 891 * The iteration order is that of the given iterator. At the end of the 892 * parallel iteration, the parallel team threads wait for each other at a 893 * barrier. 894 * <P> 895 * <I>Note:</I> Either all threads in the parallel team must call the 896 * <code>execute()</code> method with identical arguments, or none of the 897 * threads must call the <code>execute()</code> method. 898 * 899 * @param <T> Data type of the items iterated over. 900 * @param theIterator Iterator over the items. 901 * @param theIteration Parallel iteration. 902 * @exception NullPointerException (unchecked exception) Thrown if 903 * <code>theIterator</code> is null or 904 * <code>theIteration</code> is null. 905 * @exception IllegalStateException (unchecked exception) Thrown if no 906 * parallel team is executing this parallel region. 907 * @exception Exception Thrown if one of <code>theIteration</code>'s methods 908 * throws an exception. 909 * @throws java.lang.Exception if any. 910 */ 911 public final <T> void execute(Iterator<T> theIterator, 912 ParallelIteration<T> theIteration) 913 throws Exception { 914 execute(theIterator, theIteration, BarrierAction.WAIT); 915 } 916 917 /** 918 * Execute a parallel iteration within this parallel region. For further 919 * information, see class {@linkplain ParallelIteration}. The items 920 * processed by the iteration are the items returned by the given iterator. 921 * The iteration order is that of the given iterator. At the end of the 922 * parallel iteration, the parallel team threads encounter a barrier, and 923 * their behavior depends on the given {@linkplain BarrierAction}. 924 * <P> 925 * <I>Note:</I> Either all threads in the parallel team must call the 926 * <code>execute()</code> method with identical arguments, or none of the 927 * threads must call the <code>execute()</code> method. 928 * 929 * @param <T> Data type of the items iterated over. 930 * @param theIterator Iterator over the items. 931 * @param theIteration Parallel iteration. 932 * @param action Barrier action. 933 * @exception NullPointerException (unchecked exception) Thrown if 934 * <code>theIterator</code> is null. Thrown if <code>theIteration</code> is null. 935 * Thrown if <code>action</code> is null. 936 * @exception IllegalStateException (unchecked exception) Thrown if no 937 * parallel team is executing this parallel region. 938 * @exception Exception Thrown if one of <code>theIteration</code>'s methods 939 * throws an exception. 940 * @throws java.lang.Exception if any. 941 */ 942 public final <T> void execute(Iterator<T> theIterator, 943 ParallelIteration<T> theIteration, 944 BarrierAction action) 945 throws Exception { 946 // Verify preconditions. 947 if (theIterator == null) { 948 throw new NullPointerException("ParallelRegion.execute(): Iterator is null"); 949 } 950 if (theIteration == null) { 951 throw new NullPointerException("ParallelRegion.execute(): Parallel iteration is null"); 952 } 953 if (action == null) { 954 throw new NullPointerException("ParallelRegion.execute(): Barrier action is null"); 955 } 956 if (myTeam == null) { 957 throw new IllegalStateException("ParallelRegion.execute(): No parallel team executing"); 958 } 959 960 try { 961 // Record parallel team. 962 theIteration.myTeam = this.myTeam; 963 964 // Get current parallel team thread. 965 ParallelTeamThread currentThread = getCurrentThread(); 966 967 // Do top-of-parallel-construct processing. 968 ItemGenerator<T> generator = null; 969 if (currentThread.arriveAtParallelConstruct()) { 970 // First thread to arrive sets up the shared item generator 971 // object and stores it (or an exception if any) in each team 972 // thread. 973 try { 974 generator = new IteratorItemGenerator<T>(theIterator); 975 for (ParallelTeamThread thread : myTeam.myThread) { 976 thread.setItemGenerator(generator); 977 } 978 } catch (Throwable exc) { 979 for (ParallelTeamThread thread : myTeam.myThread) { 980 thread.setConstructException(exc); 981 } 982 } 983 } 984 985 // Get the shared item generator object. 986 generator = castItemGenerator(currentThread.getItemGenerator()); 987 theIteration.myItemGenerator = generator; 988 989 // Prepare to catch exceptions thrown by the parallel iteration 990 // body. 991 Throwable runException = null; 992 try { 993 // Perform per-thread initialization. 994 theIteration.start(); 995 996 // Repeatedly get and process an item. 997 ItemHolder<T> itemholder; 998 while ((itemholder = generator.nextItem()) != null) { 999 theIteration.commonRun(itemholder.mySequenceNumber, itemholder.myItem); 1000 } 1001 1002 // Perform per-thread finalization. 1003 theIteration.finish(); 1004 } catch (Throwable exc) { 1005 runException = exc; 1006 generator.myBreak = true; 1007 } 1008 1009 // Barrier synchronization. 1010 action.doBarrier(currentThread); 1011 1012 // Propagate any exception thrown by the run() method. 1013 ParallelTeam.rethrow(runException); 1014 } finally { 1015 // Forget parallel team. 1016 theIteration.myTeam = null; 1017 theIteration.myItemGenerator = null; 1018 } 1019 } 1020 1021 /** 1022 * Execute a parallel iteration within this parallel region. For further 1023 * information, see class {@linkplain ParallelIteration}. The items 1024 * processed by the iteration are the items contained in the given iterable 1025 * collection. The iteration order is that of the given iterable 1026 * collection's iterator. At the end of the parallel iteration, the parallel 1027 * team threads wait for each other at a barrier. 1028 * <P> 1029 * <I>Note:</I> Either all threads in the parallel team must call the 1030 * <code>execute()</code> method with identical arguments, or none of the 1031 * threads must call the <code>execute()</code> method. 1032 * 1033 * @param <T> Data type of the items iterated over. 1034 * @param theIterable Iterable collection containing the items. 1035 * @param theIteration Parallel iteration. 1036 * @exception NullPointerException (unchecked exception) Thrown if 1037 * <code>theIterable</code> is null or 1038 * <code>theIteration</code> is null. 1039 * @exception IllegalStateException (unchecked exception) Thrown if no 1040 * parallel team is executing this parallel region. 1041 * @exception Exception Thrown if one of <code>theIteration</code>'s methods 1042 * throws an exception. 1043 * @throws java.lang.Exception if any. 1044 */ 1045 public final <T> void execute(Iterable<T> theIterable, 1046 ParallelIteration<T> theIteration) 1047 throws Exception { 1048 execute(theIterable, theIteration, BarrierAction.WAIT); 1049 } 1050 1051 /** 1052 * Execute a parallel iteration within this parallel region. For further 1053 * information, see class {@linkplain ParallelIteration}. The items 1054 * processed by the iteration are the items contained in the given iterable 1055 * collection. The iteration order is that of the given iterable 1056 * collection's iterator. At the end of the parallel iteration, the parallel 1057 * team threads encounter a barrier, and their behavior depends on the given 1058 * {@linkplain BarrierAction}. 1059 * <P> 1060 * <I>Note:</I> Either all threads in the parallel team must call the 1061 * <code>execute()</code> method with identical arguments, or none of the 1062 * threads must call the <code>execute()</code> method. 1063 * 1064 * @param <T> Data type of the items iterated over. 1065 * @param theIterable Iterable collection containing the items. 1066 * @param theIteration Parallel iteration. 1067 * @param action Barrier action. 1068 * @exception NullPointerException (unchecked exception) Thrown if 1069 * <code>theIterable</code> is null. Thrown if <code>theIteration</code> is null. 1070 * Thrown if <code>action</code> is null. 1071 * @exception IllegalStateException (unchecked exception) Thrown if no 1072 * parallel team is executing this parallel region. 1073 * @exception Exception Thrown if one of <code>theIteration</code>'s methods 1074 * throws an exception. 1075 * @throws java.lang.Exception if any. 1076 */ 1077 public final <T> void execute(Iterable<T> theIterable, 1078 ParallelIteration<T> theIteration, 1079 BarrierAction action) 1080 throws Exception { 1081 // Verify preconditions. 1082 if (theIterable == null) { 1083 throw new NullPointerException("ParallelRegion.execute(): Iterable collection is null"); 1084 } 1085 if (theIteration == null) { 1086 throw new NullPointerException("ParallelRegion.execute(): Parallel iteration is null"); 1087 } 1088 if (action == null) { 1089 throw new NullPointerException("ParallelRegion.execute(): Barrier action is null"); 1090 } 1091 if (myTeam == null) { 1092 throw new IllegalStateException("ParallelRegion.execute(): No parallel team executing"); 1093 } 1094 1095 try { 1096 // Record parallel team. 1097 theIteration.myTeam = this.myTeam; 1098 1099 // Get current parallel team thread. 1100 ParallelTeamThread currentThread = getCurrentThread(); 1101 1102 // Do top-of-parallel-construct processing. 1103 ItemGenerator<T> generator = null; 1104 if (currentThread.arriveAtParallelConstruct()) { 1105 // First thread to arrive sets up the shared item generator 1106 // object and stores it (or an exception if any) in each team 1107 // thread. 1108 try { 1109 generator 1110 = new IteratorItemGenerator<T>(theIterable.iterator()); 1111 for (ParallelTeamThread thread : myTeam.myThread) { 1112 thread.setItemGenerator(generator); 1113 } 1114 } catch (Throwable exc) { 1115 for (ParallelTeamThread thread : myTeam.myThread) { 1116 thread.setConstructException(exc); 1117 } 1118 } 1119 } 1120 1121 // Get the shared item generator object. 1122 generator = castItemGenerator(currentThread.getItemGenerator()); 1123 theIteration.myItemGenerator = generator; 1124 1125 // Prepare to catch exceptions thrown by the parallel iteration 1126 // body. 1127 Throwable runException = null; 1128 try { 1129 // Perform per-thread initialization. 1130 theIteration.start(); 1131 1132 // Repeatedly get and process an item. 1133 ItemHolder<T> itemholder; 1134 while ((itemholder = generator.nextItem()) != null) { 1135 theIteration.commonRun(itemholder.mySequenceNumber, itemholder.myItem); 1136 } 1137 1138 // Perform per-thread finalization. 1139 theIteration.finish(); 1140 } catch (Throwable exc) { 1141 runException = exc; 1142 generator.myBreak = true; 1143 } 1144 1145 // Barrier synchronization. 1146 action.doBarrier(currentThread); 1147 1148 // Propagate any exception thrown by the run() method. 1149 ParallelTeam.rethrow(runException); 1150 } finally { 1151 // Forget parallel team. 1152 theIteration.myTeam = null; 1153 theIteration.myItemGenerator = null; 1154 } 1155 } 1156 1157 /** 1158 * Execute a parallel section within this parallel region. The parallel 1159 * section's <code>run()</code> method is called by one of the parallel team 1160 * threads. For further information, see class {@linkplain ParallelSection}. 1161 * At the end of the parallel section, the parallel team threads wait for 1162 * each other at a barrier. 1163 * <P> 1164 * <I>Note:</I> Either all threads in the parallel team must call the 1165 * <code>execute()</code> method with identical arguments, or none of the 1166 * threads must call the <code>execute()</code> method. 1167 * 1168 * @param section Parallel section. 1169 * @exception NullPointerException (unchecked exception) Thrown if 1170 * <code>section</code> is null. 1171 * @exception IllegalStateException (unchecked exception) Thrown if no 1172 * parallel team is executing this parallel region. 1173 * @exception Exception Thrown if the parallel section's <code>run()</code> 1174 * method throws an exception. 1175 * @throws java.lang.Exception if any. 1176 */ 1177 public final void execute(ParallelSection section) 1178 throws Exception { 1179 execute(new ParallelSection[]{section}, BarrierAction.WAIT); 1180 } 1181 1182 /** 1183 * Execute a parallel section within this parallel region. The parallel 1184 * section's <code>run()</code> method is called by one of the parallel team 1185 * threads. For further information, see class {@linkplain ParallelSection}. 1186 * At the end of the parallel section, the parallel team threads encounter a 1187 * barrier, and their behavior depends on the given {@linkplain 1188 * BarrierAction}. 1189 * <P> 1190 * <I>Note:</I> Either all threads in the parallel team must call the 1191 * <code>execute()</code> method with identical arguments, or none of the 1192 * threads must call the <code>execute()</code> method. 1193 * 1194 * @param section Parallel section. 1195 * @param action Barrier action. 1196 * @exception NullPointerException (unchecked exception) Thrown if 1197 * <code>section</code> is null. Thrown if 1198 * <code>action</code> is null. 1199 * @exception IllegalStateException (unchecked exception) Thrown if no 1200 * parallel team is executing this parallel region. 1201 * @exception Exception Thrown if the parallel section's <code>run()</code> 1202 * method throws an exception. 1203 * @throws java.lang.Exception if any. 1204 */ 1205 public final void execute(ParallelSection section, 1206 BarrierAction action) 1207 throws Exception { 1208 execute(new ParallelSection[]{section}, action); 1209 } 1210 1211 /** 1212 * Execute a group of two parallel sections concurrently within this 1213 * parallel region. Each parallel section's <code>run()</code> method is called 1214 * by a different parallel team thread. For further information, see class 1215 * {@linkplain ParallelSection}. At the end of the parallel section group, 1216 * the parallel team threads wait for each other at a barrier. 1217 * <P> 1218 * <I>Note:</I> Either all threads in the parallel team must call the 1219 * <code>execute()</code> method with identical arguments, or none of the 1220 * threads must call the <code>execute()</code> method. 1221 * 1222 * @param section1 First parallel section. 1223 * @param section2 Second parallel section. 1224 * @exception NullPointerException (unchecked exception) Thrown if 1225 * <code>section1</code> is null. Thrown if 1226 * <code>section2</code> is null. 1227 * @exception IllegalStateException (unchecked exception) Thrown if no 1228 * parallel team is executing this parallel region. 1229 * @exception Exception Thrown if one of the parallel sections' 1230 * <code>run()</code> methods throws an exception. 1231 * @throws java.lang.Exception if any. 1232 */ 1233 public final void execute(ParallelSection section1, 1234 ParallelSection section2) 1235 throws Exception { 1236 execute(new ParallelSection[]{section1, section2}, 1237 BarrierAction.WAIT); 1238 } 1239 1240 /** 1241 * Execute a group of two parallel sections concurrently within this 1242 * parallel region. Each parallel section's <code>run()</code> method is called 1243 * by a different parallel team thread. For further information, see class 1244 * {@linkplain ParallelSection}. At the end of the parallel section group, 1245 * the parallel team threads encounter a barrier, and their behavior depends 1246 * on the given {@linkplain BarrierAction}. 1247 * <P> 1248 * <I>Note:</I> Either all threads in the parallel team must call the 1249 * <code>execute()</code> method with identical arguments, or none of the 1250 * threads must call the <code>execute()</code> method. 1251 * 1252 * @param section1 First parallel section. 1253 * @param section2 Second parallel section. 1254 * @param action Barrier action. 1255 * @exception NullPointerException (unchecked exception) Thrown if 1256 * <code>section1</code> is null. Thrown if 1257 * <code>section2</code> is null. Thrown if <code>action</code> is null. 1258 * @exception IllegalStateException (unchecked exception) Thrown if no 1259 * parallel team is executing this parallel region. 1260 * @exception Exception Thrown if one of the parallel sections' 1261 * <code>run()</code> methods throws an exception. 1262 * @throws java.lang.Exception if any. 1263 */ 1264 public final void execute(ParallelSection section1, 1265 ParallelSection section2, 1266 BarrierAction action) 1267 throws Exception { 1268 execute(new ParallelSection[]{section1, section2}, 1269 action); 1270 } 1271 1272 /** 1273 * Execute a group of three parallel sections concurrently within this 1274 * parallel region. Each parallel section's <code>run()</code> method is called 1275 * by a different parallel team thread. For further information, see class 1276 * {@linkplain ParallelSection}. At the end of the parallel section group, 1277 * the parallel team threads wait for each other at a barrier. 1278 * <P> 1279 * <I>Note:</I> Either all threads in the parallel team must call the 1280 * <code>execute()</code> method with identical arguments, or none of the 1281 * threads must call the <code>execute()</code> method. 1282 * 1283 * @param section1 First parallel section. 1284 * @param section2 Second parallel section. 1285 * @param section3 Third parallel section. 1286 * @exception NullPointerException (unchecked exception) Thrown if 1287 * <code>section1</code> is null. Thrown if 1288 * <code>section2</code> is null. Thrown if <code>section3</code> is null. 1289 * @exception IllegalStateException (unchecked exception) Thrown if no 1290 * parallel team is executing this parallel region. 1291 * @exception Exception Thrown if one of the parallel sections' 1292 * <code>run()</code> methods throws an exception. 1293 * @throws java.lang.Exception if any. 1294 */ 1295 public final void execute(ParallelSection section1, 1296 ParallelSection section2, 1297 ParallelSection section3) 1298 throws Exception { 1299 execute(new ParallelSection[]{section1, section2, section3}, 1300 BarrierAction.WAIT); 1301 } 1302 1303 /** 1304 * Execute a group of three parallel sections concurrently within this 1305 * parallel region. Each parallel section's <code>run()</code> method is called 1306 * by a different parallel team thread. For further information, see class 1307 * {@linkplain ParallelSection}. At the end of the parallel section group, 1308 * the parallel team threads encounter a barrier, and their behavior depends 1309 * on the given {@linkplain BarrierAction}. 1310 * <P> 1311 * <I>Note:</I> Either all threads in the parallel team must call the 1312 * <code>execute()</code> method with identical arguments, or none of the 1313 * threads must call the <code>execute()</code> method. 1314 * 1315 * @param section1 First parallel section. 1316 * @param section2 Second parallel section. 1317 * @param section3 Third parallel section. 1318 * @param action Barrier action. 1319 * @exception NullPointerException (unchecked exception) Thrown if 1320 * <code>section1</code> is null. Thrown if 1321 * <code>section2</code> is null. Thrown if <code>section3</code> is null. Thrown if 1322 * <code>action</code> is null. 1323 * @exception IllegalStateException (unchecked exception) Thrown if no 1324 * parallel team is executing this parallel region. 1325 * @exception Exception Thrown if one of the parallel sections' 1326 * <code>run()</code> methods throws an exception. 1327 * @throws java.lang.Exception if any. 1328 */ 1329 public final void execute(ParallelSection section1, 1330 ParallelSection section2, 1331 ParallelSection section3, 1332 BarrierAction action) 1333 throws Exception { 1334 execute(new ParallelSection[]{section1, section2, section3}, 1335 action); 1336 } 1337 1338 /** 1339 * Execute a group of parallel sections concurrently within this parallel 1340 * region. Each parallel section's <code>run()</code> method is called by a 1341 * different parallel team thread. For further information, see class 1342 * {@linkplain ParallelSection}. At the end of the parallel section group, 1343 * the parallel team threads wait for each other at a barrier. 1344 * <P> 1345 * <I>Note:</I> Either all threads in the parallel team must call the 1346 * <code>execute()</code> method with identical arguments, or none of the 1347 * threads must call the <code>execute()</code> method. 1348 * 1349 * @param sections Parallel sections. 1350 * @exception NullPointerException (unchecked exception) Thrown if any of 1351 * the <code>sections</code> is null. 1352 * @exception IllegalStateException (unchecked exception) Thrown if no 1353 * parallel team is executing this parallel region. 1354 * @exception Exception Thrown if one of the parallel sections' 1355 * <code>run()</code> methods throws an exception. 1356 * @throws java.lang.Exception if any. 1357 */ 1358 public final void execute(ParallelSection[] sections) 1359 throws Exception { 1360 execute(sections, BarrierAction.WAIT); 1361 } 1362 1363 /** 1364 * Execute a group of parallel sections concurrently within this parallel 1365 * region. Each parallel section's <code>run()</code> method is called by a 1366 * different parallel team thread. For further information, see class 1367 * {@linkplain ParallelSection}. At the end of the parallel section group, 1368 * the parallel team threads encounter a barrier, and their behavior depends 1369 * on the given {@linkplain BarrierAction}. 1370 * <P> 1371 * <I>Note:</I> Either all threads in the parallel team must call the 1372 * <code>execute()</code> method with identical arguments, or none of the 1373 * threads must call the <code>execute()</code> method. 1374 * 1375 * @param sections Parallel sections. 1376 * @param action Barrier action. 1377 * @exception NullPointerException (unchecked exception) Thrown if any of 1378 * the <code>sections</code> is null. Thrown if <code>action</code> is null. 1379 * @exception IllegalStateException (unchecked exception) Thrown if no 1380 * parallel team is executing this parallel region. 1381 * @exception Exception Thrown if one of the parallel sections' 1382 * <code>run()</code> methods throws an exception. 1383 * @throws java.lang.Exception if any. 1384 */ 1385 public final void execute(ParallelSection[] sections, 1386 BarrierAction action) 1387 throws Exception { 1388 if (sections == null) { 1389 throw new NullPointerException("ParallelRegion.execute(): sections is null"); 1390 } 1391 for (ParallelSection section : sections) { 1392 if (section == null) { 1393 throw new NullPointerException("ParallelRegion.execute(): A parallel section is null"); 1394 } 1395 } 1396 if (action == null) { 1397 throw new NullPointerException("ParallelRegion.execute(): Barrier action is null"); 1398 } 1399 1400 execute(sections, new ParallelIteration<ParallelSection>() { 1401 public void run(ParallelSection section) throws Exception { 1402 try { 1403 section.myTeam = this.myTeam; 1404 section.run(); 1405 } finally { 1406 section.myTeam = null; 1407 } 1408 } 1409 }, 1410 action); 1411 } 1412 1413 /** 1414 * Perform a section of code in a critical region with exclusive locking. 1415 * The locking is performed using the default lock, a hidden {@linkplain 1416 * Lock} variable shared by all the parallel team threads. The thread 1417 * calling the <code>critical()</code> method waits until no other thread is 1418 * executing a critical region with exclusive locking using the default lock 1419 * and no other thread is executing a critical region with nonexclusive 1420 * locking using the default lock. The thread then calls 1421 * <code>theSection</code>'s <code>run()</code> method with exclusive locking using 1422 * the default lock. When the <code>run()</code> method returns, the thread 1423 * unlocks the lock and returns from the <code>critical()</code> method. 1424 * <P> 1425 * If the parallel section's <code>run()</code> method throws an exception, the 1426 * <code>critical()</code> method throws that same exception in the thread that 1427 * called the <code>run()</code> method (after unlocking the lock). 1428 * 1429 * @param theSection Parallel section to execute in the critical region. 1430 * @exception NullPointerException (unchecked exception) Thrown if 1431 * <code>theSection</code> is null. 1432 * @exception IllegalStateException (unchecked exception) Thrown if no 1433 * parallel team is executing this parallel region. 1434 * @exception Exception Thrown if <code>theSection</code>'s <code>run()</code> 1435 * method throws an exception. 1436 * @throws java.lang.Exception if any. 1437 */ 1438 public final void critical(ParallelSection theSection) 1439 throws Exception { 1440 critical(myLock, theSection); 1441 } 1442 1443 /** 1444 * Perform a section of code in a critical region with nonexclusive locking. 1445 * The locking is performed using the default lock, a hidden {@linkplain 1446 * Lock} variable shared by all the parallel team threads. The thread 1447 * calling the <code>critical()</code> method waits until no other thread is 1448 * executing a critical region with exclusive locking using the default 1449 * lock. However, any number of other threads may be executing a critical 1450 * region with nonexclusive locking using the default lock. The thread then 1451 * calls <code>theSection</code>'s <code>run()</code> method with nonexclusive 1452 * locking using the default lock. When the <code>run()</code> method returns, 1453 * the thread unlocks the lock and returns from the <code>critical()</code> 1454 * method. 1455 * <P> 1456 * If the parallel section's <code>run()</code> method throws an exception, the 1457 * <code>critical()</code> method throws that same exception in the thread that 1458 * called the <code>run()</code> method (after unlocking the lock). 1459 * 1460 * @param theSection Parallel section to execute in the critical region. 1461 * @exception NullPointerException (unchecked exception) Thrown if 1462 * <code>theSection</code> is null. 1463 * @exception IllegalStateException (unchecked exception) Thrown if no 1464 * parallel team is executing this parallel region. 1465 * @exception Exception Thrown if <code>theSection</code>'s <code>run()</code> 1466 * method throws an exception. 1467 * @throws java.lang.Exception if any. 1468 */ 1469 public final void criticalNonexclusive(ParallelSection theSection) 1470 throws Exception { 1471 criticalNonexclusive(myLock, theSection); 1472 } 1473 1474 /** 1475 * Perform a section of code in a critical region with exclusive locking 1476 * using the given lock. The thread calling the <code>critical()</code> method 1477 * waits until no other thread is executing a critical region with exclusive 1478 * locking using the given lock and no other thread is executing a critical 1479 * region with nonexclusive locking using the given lock. The thread then 1480 * calls <code>theSection</code>'s <code>run()</code> method with exclusive locking 1481 * using the given lock. When the <code>run()</code> method returns, the thread 1482 * unlocks the lock and returns from the <code>critical()</code> method. 1483 * <P> 1484 * If the parallel section's <code>run()</code> method throws an exception, the 1485 * <code>critical()</code> method throws that same exception in the thread that 1486 * called the <code>run()</code> method (after unlocking the lock). 1487 * 1488 * @param theLock Lock. 1489 * @param theSection Parallel section to execute in the critical region. 1490 * @exception NullPointerException (unchecked exception) Thrown if 1491 * <code>theLock</code> is null or 1492 * <code>theSection</code> is null. 1493 * @exception IllegalStateException (unchecked exception) Thrown if no 1494 * parallel team is executing this parallel region. 1495 * @exception Exception Thrown if <code>theSection</code>'s <code>run()</code> 1496 * method throws an exception. 1497 * @throws java.lang.Exception if any. 1498 */ 1499 public final void critical(Lock theLock, 1500 ParallelSection theSection) 1501 throws Exception { 1502 // Verify preconditions. 1503 if (theLock == null) { 1504 throw new NullPointerException("ParallelRegion.critical(): Lock is null"); 1505 } 1506 if (theSection == null) { 1507 throw new NullPointerException("ParallelRegion.critical(): Parallel section is null"); 1508 } 1509 if (myTeam == null) { 1510 throw new IllegalStateException("ParallelRegion.critical(): No parallel team executing"); 1511 } 1512 1513 // Lock the lock. 1514 theLock.lockExclusive(); 1515 1516 // Process the parallel section. 1517 try { 1518 theSection.myTeam = this.myTeam; 1519 theSection.run(); 1520 } // Unlock the lock. 1521 finally { 1522 theSection.myTeam = null; 1523 theLock.unlockExclusive(); 1524 } 1525 } 1526 1527 /** 1528 * Perform a section of code in a critical region with nonexclusive locking 1529 * using the given lock. The thread calling the <code>critical()</code> method 1530 * waits until no other thread is executing a critical region with exclusive 1531 * locking using the given lock. However, any number of other threads may be 1532 * executing a critical region with nonexclusive locking using the given 1533 * lock. The thread then calls <code>theSection</code>'s <code>run()</code> method 1534 * with nonexclusive locking using the given lock. When the <code>run()</code> 1535 * method returns, the thread unlocks the lock and returns from the 1536 * <code>critical()</code> method. 1537 * <P> 1538 * If the parallel section's <code>run()</code> method throws an exception, the 1539 * <code>critical()</code> method throws that same exception in the thread that 1540 * called the <code>run()</code> method (after unlocking the lock). 1541 * 1542 * @param theLock Lock. 1543 * @param theSection Parallel section to execute in the critical region. 1544 * @exception NullPointerException (unchecked exception) Thrown if 1545 * <code>theLock</code> is null or 1546 * <code>theSection</code> is null. 1547 * @exception IllegalStateException (unchecked exception) Thrown if no 1548 * parallel team is executing this parallel region. 1549 * @exception Exception Thrown if <code>theSection</code>'s <code>run()</code> 1550 * method throws an exception. 1551 * @throws java.lang.Exception if any. 1552 */ 1553 public final void criticalNonexclusive(Lock theLock, 1554 ParallelSection theSection) 1555 throws Exception { 1556 // Verify preconditions. 1557 if (theLock == null) { 1558 throw new NullPointerException("ParallelRegion.criticalNonexclusive(): Lock is null"); 1559 } 1560 if (theSection == null) { 1561 throw new NullPointerException("ParallelRegion.criticalNonexclusive(): Parallel section is null"); 1562 } 1563 if (myTeam == null) { 1564 throw new IllegalStateException("ParallelRegion.criticalNonexclusive(): No parallel team executing"); 1565 } 1566 1567 // Lock the lock. 1568 theLock.lockNonexclusive(); 1569 1570 // Process the parallel section. 1571 try { 1572 theSection.myTeam = this.myTeam; 1573 theSection.run(); 1574 } // Unlock the lock. 1575 finally { 1576 theSection.myTeam = null; 1577 theLock.unlockNonexclusive(); 1578 } 1579 } 1580 1581 /** 1582 * Perform a barrier. The parallel team threads wait for each other at a 1583 * barrier. 1584 * <P> 1585 * <I>Note:</I> Either all threads in the parallel team must call the 1586 * <code>barrier()</code> method, or none of the threads must call the 1587 * <code>barrier()</code> method. 1588 * 1589 * @exception IllegalStateException (unchecked exception) Thrown if no 1590 * parallel team is executing this parallel region. 1591 */ 1592 public final void barrier() { 1593 getCurrentThread().barrier(); 1594 } 1595 1596 /** 1597 * Perform a barrier, with a barrier action. The parallel team threads 1598 * encounter a barrier, and their behavior depends on the given {@linkplain 1599 * BarrierAction}. 1600 * <P> 1601 * <I>Note:</I> Either all threads in the parallel team must call the 1602 * <code>barrier()</code> method, or none of the threads must call the 1603 * <code>barrier()</code> method. 1604 * 1605 * @param action Barrier action. 1606 * @exception NullPointerException (unchecked exception) Thrown if 1607 * <code>action</code> is null. 1608 * @exception IllegalStateException (unchecked exception) Thrown if no 1609 * parallel team is executing this parallel region. 1610 * @exception Exception Thrown if <code>theSection</code>'s <code>run()</code> 1611 * method throws an exception. 1612 * @throws java.lang.Exception if any. 1613 */ 1614 public final void barrier(BarrierAction action) 1615 throws Exception { 1616 if (action == null) { 1617 throw new NullPointerException("ParallelRegion.barrier(): Barrier action is null"); 1618 } 1619 action.doBarrier(getCurrentThread()); 1620 } 1621 1622 }