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

Comparing jsr166/src/jsr166y/ForkJoinPool.java (file contents):
Revision 1.136 by dl, Mon Oct 29 17:23:34 2012 UTC vs.
Revision 1.137 by dl, Tue Oct 30 14:23:11 2012 UTC

# Line 691 | Line 691 | public class ForkJoinPool extends Abstra
691  
692          /**
693           * Takes next task, if one exists, in LIFO order.  Call only
694 <         * by owner in unshared queues. (We do not have a shared
695 <         * version of this method because it is never needed.)
694 >         * by owner in unshared queues.
695           */
696          final ForkJoinTask<?> pop() {
697              ForkJoinTask<?>[] a; ForkJoinTask<?> t; int m;
# Line 710 | Line 709 | public class ForkJoinPool extends Abstra
709              return null;
710          }
711  
712 +        final ForkJoinTask<?> sharedPop() {
713 +            ForkJoinTask<?> task = null;
714 +            if (runState == 0 && U.compareAndSwapInt(this, RUNSTATE, 0, 1)) {
715 +                try {
716 +                    ForkJoinTask<?>[] a; int m;
717 +                    if ((a = array) != null && (m = a.length - 1) >= 0) {
718 +                        for (int s; (s = top - 1) - base >= 0;) {
719 +                            long j = ((m & s) << ASHIFT) + ABASE;
720 +                            ForkJoinTask<?> t =
721 +                                (ForkJoinTask<?>)U.getObject(a, j);
722 +                            if (t == null)
723 +                                break;
724 +                            if (U.compareAndSwapObject(a, j, t, null)) {
725 +                                top = s;
726 +                                task = t;
727 +                                break;
728 +                            }
729 +                        }
730 +                    }
731 +                } finally {
732 +                    runState = 0;
733 +                }
734 +            }
735 +            return task;
736 +        }
737 +
738 +        /**
739 +         * Version of pop that takes top element only if it
740 +         * its root is the given CountedCompleter.
741 +         */
742 +        final ForkJoinTask<?> popCC(CountedCompleter<?> root) {
743 +            ForkJoinTask<?>[] a; int m;
744 +            if (root != null && (a = array) != null && (m = a.length - 1) >= 0) {
745 +                for (int s; (s = top - 1) - base >= 0;) {
746 +                    long j = ((m & s) << ASHIFT) + ABASE;
747 +                    ForkJoinTask<?> t =
748 +                        (ForkJoinTask<?>)U.getObject(a, j);
749 +                    if (t == null || !(t instanceof CountedCompleter) ||
750 +                        ((CountedCompleter<?>)t).getRoot() != root)
751 +                        break;
752 +                    if (U.compareAndSwapObject(a, j, t, null)) {
753 +                        top = s;
754 +                        return t;
755 +                    }
756 +                    if (root.status < 0)
757 +                        break;
758 +                }
759 +            }
760 +            return null;
761 +        }
762 +
763 +        /**
764 +         * Shared version of popCC
765 +         */
766 +        final ForkJoinTask<?> sharedPopCC(CountedCompleter<?> root) {
767 +            ForkJoinTask<?> task = null;
768 +            if (root != null &&
769 +                runState == 0 && U.compareAndSwapInt(this, RUNSTATE, 0, 1)) {
770 +                try {
771 +                    ForkJoinTask<?>[] a; int m;
772 +                    if ((a = array) != null && (m = a.length - 1) >= 0) {
773 +                        for (int s; (s = top - 1) - base >= 0;) {
774 +                            long j = ((m & s) << ASHIFT) + ABASE;
775 +                            ForkJoinTask<?> t =
776 +                                (ForkJoinTask<?>)U.getObject(a, j);
777 +                            if (t == null || !(t instanceof CountedCompleter) ||
778 +                                ((CountedCompleter<?>)t).getRoot() != root)
779 +                                break;
780 +                            if (U.compareAndSwapObject(a, j, t, null)) {
781 +                                top = s;
782 +                                task = t;
783 +                                break;
784 +                            }
785 +                            if (root.status < 0)
786 +                                break;
787 +                        }
788 +                    }
789 +                } finally {
790 +                    runState = 0;
791 +                }
792 +            }
793 +            return task;
794 +        }
795 +
796          /**
797           * Takes a task in FIFO order if b is base of queue and a task
798           * can be claimed without contention. Specialized versions
# Line 1507 | Line 1590 | public class ForkJoinPool extends Abstra
1590      }
1591  
1592      /**
1593 +     * Returns true if caller is (or may be) submitter to the common
1594 +     * pool, and not all workers are active, and there appear to be
1595 +     * tasks in the associated submission queue.
1596 +     */
1597 +    static boolean canHelpCommonPool() {
1598 +        ForkJoinPool p; WorkQueue[] ws; WorkQueue q;
1599 +        int k = submitters.get().seed & SQMASK;
1600 +        return ((p = commonPool) != null &&
1601 +                (int)(p.ctl >> AC_SHIFT) < 0 &&
1602 +                (ws = p.workQueues) != null &&
1603 +                ws.length > (k &= p.submitMask) &&
1604 +                (q = ws[k]) != null &&
1605 +                q.top - q.base > 0);
1606 +    }
1607 +
1608 +    /**
1609       * Returns true if the given task was submitted to common pool
1610       * and has not yet commenced execution, and is available for
1611       * removal according to execution policies; if so removing the
# Line 1519 | Line 1618 | public class ForkJoinPool extends Abstra
1618          // Peek, looking for task and eligibility before
1619          // using trySharedUnpush to actually take it under lock
1620          ForkJoinPool p; WorkQueue[] ws; WorkQueue q;
1621 <        ForkJoinTask<?>[] a; int t, s, n;
1621 >        ForkJoinTask<?>[] a; int s;
1622          int k = submitters.get().seed & SQMASK;
1623          return ((p = commonPool) != null &&
1624 +                (int)(p.ctl >> AC_SHIFT) < 0 &&
1625                  (ws = p.workQueues) != null &&
1626                  ws.length > (k &= p.submitMask) &&
1627                  (q = ws[k]) != null &&
1628                  (a = q.array) != null &&
1629 <                (n = (t = q.top) - q.base) > 0 &&
1630 <                (n > 1 || (int)(p.ctl >> AC_SHIFT) < 0) &&
1631 <                (s = t - 1) >= 0 && s < a.length && a[s] == task &&
1629 >                (s = q.top - 1) - q.base >= 0 &&
1630 >                s >= 0 && s < a.length &&
1631 >                a[s] == task &&
1632                  q.trySharedUnpush(task));
1633      }
1634  
1635 +    /**
1636 +     * Tries to pop a task from common pool with given root
1637 +     */
1638 +    static ForkJoinTask<?> popCCFromCommonPool(CountedCompleter<?> root) {
1639 +        ForkJoinPool p; WorkQueue[] ws; WorkQueue q;
1640 +        ForkJoinTask<?> t;
1641 +        int k = submitters.get().seed & SQMASK;
1642 +        if (root != null &&
1643 +            (p = commonPool) != null &&
1644 +            (int)(p.ctl >> AC_SHIFT) < 0 &&
1645 +            (ws = p.workQueues) != null &&
1646 +            ws.length > (k &= p.submitMask) &&
1647 +            (q = ws[k]) != null && q.top - q.base > 0 &&
1648 +            root.status < 0 &&
1649 +            (t = q.sharedPopCC(root)) != null)
1650 +            return t;
1651 +        return null;
1652 +    }
1653 +
1654 +
1655      // Maintaining ctl counts
1656  
1657      /**
# Line 2067 | Line 2187 | public class ForkJoinPool extends Abstra
2187       * Restricted version of helpQuiescePool for non-FJ callers
2188       */
2189      static void externalHelpQuiescePool() {
2190 <        ForkJoinPool p; WorkQueue[] ws; WorkQueue w, q;
2191 <        ForkJoinTask<?> t; int b;
2190 >        ForkJoinPool p; WorkQueue[] ws; WorkQueue q, sq;
2191 >        ForkJoinTask<?>[] a; int b;
2192 >        ForkJoinTask<?> t = null;
2193          int k = submitters.get().seed & SQMASK;
2194          if ((p = commonPool) != null &&
2195 +            (int)(p.ctl >> AC_SHIFT) < 0 &&
2196              (ws = p.workQueues) != null &&
2197              ws.length > (k &= p.submitMask) &&
2198 <            (w = ws[k]) != null &&
2199 <            (q = p.findNonEmptyStealQueue(w)) != null &&
2200 <            (b = q.base) - q.top < 0 &&
2201 <            (t = q.pollAt(b)) != null)
2202 <            t.doExec();
2198 >            (q = ws[k]) != null) {
2199 >            while (q.top - q.base > 0) {
2200 >                if ((t = q.sharedPop()) != null)
2201 >                    break;
2202 >            }
2203 >            if (t == null && (sq = p.findNonEmptyStealQueue(q)) != null &&
2204 >                (b = sq.base) - sq.top < 0)
2205 >                t = sq.pollAt(b);
2206 >            if (t != null)
2207 >                t.doExec();
2208 >        }
2209      }
2210  
2211      /**

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines