/** * Execute the given section of code in order of the loop indexes. A call to the * <TT>ordered()</TT> method may appear in this parallel for loop's <TT>run()</TT> method. When * called, the <TT>ordered()</TT> method waits until the <TT>ordered()</TT> method has been called * and has returned in all loop iterations prior to the current loop iteration. Then the * <TT>ordered()</TT> method calls the <TT>run()</TT> method of <TT>theParallelSection</TT>. When * the parallel section's <TT>run()</TT> method returns, the <TT>ordered()</TT> method returns. If * the parallel section's <TT>run()</TT> method throws an exception, the <TT>ordered()</TT> method * throws that same exception. * * <p>The <TT>ordered()</TT> method is used when a portion of a parallel for loop has to be * executed sequentially in the order of the loop indexes, while the rest of the parallel for loop * can be executed concurrently. * * <p><I>Note:</I> Either the <TT>ordered()</TT> method must be called exactly once during each * call of the parallel for loop's <TT>run()</TT> method, or the <TT>ordered()</TT> method must * not be called at all. * * @param theSection Parallel section to execute in order. * @exception NullPointerException (unchecked exception) Thrown if <TT>theSection</TT> is null. * @exception IllegalStateException (unchecked exception) Thrown if no parallel team is executing * this parallel for loop. * @exception Exception Thrown if <TT>theSection</TT>'s <TT>run()</TT> method throws an exception. */ public final void ordered(ParallelSection theSection) throws Exception { // Verify preconditions. if (theSection == null) { throw new IllegalStateException("IntegerStrideForLoop.ordered(): Parallel section is null"); } if (myTeam == null) { throw new IllegalStateException("IntegerStrideForLoop.ordered(): No parallel team executing"); } // Wait until the ordered() construct has finished for all previous // iterations. if (mySchedule.myOrderedIndex != this.myOrderedIndex) { Spinner spinner = new Spinner(); while (mySchedule.myOrderedIndex != this.myOrderedIndex) { spinner.spin(); } } // Execute parallel section. Propagate any exception. theSection.myTeam = this.myTeam; try { theSection.run(); } finally { theSection.myTeam = null; // Notify that the ordered construct has finished for this // iteration. this.myOrderedIndex += this.myStride; mySchedule.myOrderedIndex = this.myOrderedIndex; } }
/** * Stop this parallel for loop. Once <TT>stopLoop()</TT> is called, after each parallel team * thread finishes executing its current chunk of iterations, each thread will execute no further * chunks and will proceed to finish this parallel for loop. * * @exception IllegalStateException (unchecked exception) Thrown if no parallel team is executing * this parallel for loop. */ public final void stopLoop() { if (myTeam == null) { throw new IllegalStateException("ParallelForLoop.stopLoop(): No parallel team executing"); } mySchedule.myBreak = true; }
/** * Determine this parallel for loop's schedule. The schedule determines how the loop iterations * are apportioned among the parallel team threads. For further information, see class {@linkplain * IntegerSchedule}. * * <p>The <TT>schedule()</TT> method may be overridden in a subclass to return the desired * schedule. If not overridden, the default is a runtime schedule (see {@link * IntegerSchedule#runtime()}). * * @return Schedule for this parallel for loop. */ public IntegerSchedule schedule() { return IntegerSchedule.runtime(); }