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 }