ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/CountedCompleter.java
(Generate patch)

Comparing jsr166/src/jsr166y/CountedCompleter.java (file contents):
Revision 1.5 by jsr166, Sun Oct 21 05:28:08 2012 UTC vs.
Revision 1.6 by dl, Tue Oct 30 14:23:11 2012 UTC

# Line 142 | Line 142 | package jsr166y;
142   *
143   * As a further improvement, notice that the left task need not even
144   * exist.  Instead of creating a new one, we can iterate using the
145 < * original task, and add a pending count for each fork:
145 > * original task, and add a pending count for each fork. Additionally,
146 > * this version uses {@code helpComplete} to streamline assistance in
147 > * the execution of forked tasks.
148   *
149   * <pre> {@code
150   * class ForEach<E> ...
# Line 156 | Line 158 | package jsr166y;
158   *         }
159   *         if (h > l)
160   *             op.apply(array[l]);
161 < *         tryComplete();
161 > *         helpComplete();
162   *     }
163   * }</pre>
164   *
# Line 378 | Line 380 | public abstract class CountedCompleter<T
380      }
381  
382      /**
383 +     * Returns the root of the current computation; i.e., this
384 +     * task if it has no completer, else its completer's root.
385 +     *
386 +     * @return the root of the current computation
387 +     */
388 +    public final CountedCompleter<?> getRoot() {
389 +        CountedCompleter<?> a = this, p;
390 +        while ((p = a.completer) != null)
391 +            a = p;
392 +        return a;
393 +    }
394 +
395 +    /**
396       * If the pending count is nonzero, decrements the count;
397       * otherwise invokes {@link #onCompletion} and then similarly
398       * tries to complete this task's completer, if one exists,
# Line 399 | Line 414 | public abstract class CountedCompleter<T
414      }
415  
416      /**
417 +     * Identical to {@link #tryComplete}, but may additionally execute
418 +     * other tasks within the current computation (i.e., those
419 +     * with the same {@link #getRoot}.
420 +     */
421 +    public final void helpComplete() {
422 +        CountedCompleter<?> a = this, s = a;
423 +        for (int c;;) {
424 +            if ((c = a.pending) == 0) {
425 +                a.onCompletion(s);
426 +                if ((a = (s = a).completer) == null) {
427 +                    s.quietlyComplete();
428 +                    return;
429 +                }
430 +            }
431 +            else if (U.compareAndSwapInt(a, PENDING, c, c - 1)) {
432 +                CountedCompleter<?> root = a.getRoot();
433 +                Thread thread = Thread.currentThread();
434 +                ForkJoinPool.WorkQueue wq =
435 +                    (thread instanceof ForkJoinWorkerThread)?
436 +                    ((ForkJoinWorkerThread)thread).workQueue : null;
437 +                ForkJoinTask<?> t;
438 +                while ((t = (wq != null) ? wq.popCC(root) :
439 +                        ForkJoinPool.popCCFromCommonPool(root)) != null) {
440 +                    t.doExec();
441 +                    if (root.isDone())
442 +                        break;
443 +                }
444 +                return;
445 +            }
446 +        }
447 +    }
448 +
449 +    /**
450       * Regardless of pending count, invokes {@link #onCompletion},
451       * marks this task as complete and further triggers {@link
452       * #tryComplete} on this task's completer, if one exists. This
# Line 465 | Line 513 | public abstract class CountedCompleter<T
513          }
514      }
515  
468
516      /**
517       * Returns a sun.misc.Unsafe.  Suitable for use in a 3rd party package.
518       * Replace with a simple call to Unsafe.getUnsafe when integrating

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines