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

Comparing jsr166/src/main/java/util/concurrent/ForkJoinPool.java (file contents):
Revision 1.224 by dl, Sat Sep 13 16:11:45 2014 UTC vs.
Revision 1.225 by dl, Sun Sep 14 23:22:11 2014 UTC

# Line 739 | Line 739 | public class ForkJoinPool extends Abstra
739      static final int FIFO_QUEUE   = 1 << 16;
740      static final int SHARED_QUEUE = 1 << 31;       // must be negative
741  
742 +    // This version uses array access methods in anticipation of JDK9 support
743 +    // that should eliminate their need
744 +
745 +    static final ForkJoinTask<?> getAt(ForkJoinTask<?>[] a, int i) {
746 +        return (ForkJoinTask<?>)U.getObjectVolatile(
747 +            a, (long)((i << ASHIFT) + ABASE));
748 +    }
749 +
750 +    static final void setAt(ForkJoinTask<?>[] a, int i, ForkJoinTask<?> x) {
751 +        U.putOrderedObject(a, (long)((i << ASHIFT) + ABASE), x);
752 +    }
753 +
754 +    static final boolean casAt(ForkJoinTask<?>[] a, int i,
755 +                               ForkJoinTask<?> c, ForkJoinTask<?> v) {
756 +        return U.compareAndSwapObject(
757 +            a, (long)((i << ASHIFT) + ABASE), c, v);
758 +    }
759 +
760 +    static final ForkJoinTask<?> xchgAt(ForkJoinTask<?>[] a, int i,
761 +                                        ForkJoinTask<?> x) {
762 +        return (ForkJoinTask<?>)U.getAndSetObject(
763 +            a, (long)((i << ASHIFT) + ABASE), x);
764 +    }
765 +
766      /**
767       * Queues supporting work-stealing as well as external task
768       * submission. See above for descriptions and algorithms.
# Line 787 | Line 811 | public class ForkJoinPool extends Abstra
811          volatile ForkJoinTask<?> currentJoin;  // task being joined in awaitJoin
812          volatile ForkJoinTask<?> currentSteal; // mainly used by helpStealer
813  
814 +        // Temporary repeats of array access methods
815 +
816 +        static final ForkJoinTask<?> getAt(ForkJoinTask<?>[] a, int i) {
817 +            return (ForkJoinTask<?>)U.getObjectVolatile(
818 +                a, (long)((i << ASHIFT) + ABASE));
819 +        }
820 +
821 +        static final void setAt(ForkJoinTask<?>[] a, int i, ForkJoinTask<?> x) {
822 +            U.putOrderedObject(a, (long)((i << ASHIFT) + ABASE), x);
823 +        }
824 +
825 +        static final boolean casAt(ForkJoinTask<?>[] a, int i,
826 +                                   ForkJoinTask<?> c, ForkJoinTask<?> v) {
827 +            return U.compareAndSwapObject(
828 +                a, (long)((i << ASHIFT) + ABASE), c, v);
829 +        }
830 +
831 +        static final ForkJoinTask<?> xchgAt(ForkJoinTask<?>[] a, int i,
832 +                                            ForkJoinTask<?> x) {
833 +            return (ForkJoinTask<?>)U.getAndSetObject(
834 +                a, (long)((i << ASHIFT) + ABASE), x);
835 +        }
836 +
837 +
838          WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner) {
839              this.pool = pool;
840              this.owner = owner;
# Line 815 | Line 863 | public class ForkJoinPool extends Abstra
863           * near-empty queue has at least one unclaimed task.
864           */
865          final boolean isEmpty() {
866 <            ForkJoinTask<?>[] a; int n, m, s;
866 >            ForkJoinTask<?>[] a; int n, al, s;
867              return ((n = base - (s = top)) >= 0 ||
868                      (n == -1 &&           // possibly one task
869 <                     ((a = array) == null || (m = a.length - 1) < 0 ||
870 <                      U.getObject
823 <                      (a, (long)((m & (s - 1)) << ASHIFT) + ABASE) == null)));
869 >                     ((a = array) == null || (al = a.length) == 0 ||
870 >                      getAt(a, (al - 1) & (s - 1)) == null)));
871          }
872  
873          /**
# Line 832 | Line 879 | public class ForkJoinPool extends Abstra
879           */
880          final void push(ForkJoinTask<?> task) {
881              ForkJoinTask<?>[] a; ForkJoinPool p;
882 <            if ((a = array) != null) {  // ignore if no queue
882 >            if ((a = array) != null) {  // ignore if queue removed
883                  int b = base, m = a.length - 1, s = top, n;
884 <                long j = ((m & s) << ASHIFT) + ABASE;
885 <                if (m >= 0) {
839 <                    U.putOrderedObject(a, j, task);
884 >                if (m > 0) {            // always true, but check required
885 >                    setAt(a, m & s, task);
886                      U.putOrderedInt(this, QTOP, s + 1);
887                      if ((n = s - b) <= 1) {
888                          if ((p = pool) != null)
# Line 856 | Line 902 | public class ForkJoinPool extends Abstra
902          final ForkJoinTask<?>[] growArray() {
903              ForkJoinTask<?>[] oldA = array;
904              int size = oldA != null ? oldA.length << 1 : INITIAL_QUEUE_CAPACITY;
905 <            if (size < 0 || size > MAXIMUM_QUEUE_CAPACITY)
905 >            if (size < INITIAL_QUEUE_CAPACITY || size > MAXIMUM_QUEUE_CAPACITY)
906                  throw new RejectedExecutionException("Queue capacity exceeded");
907              int oldMask, t, b;
908              ForkJoinTask<?>[] a = array = new ForkJoinTask<?>[size];
909 <            if (oldA != null && (oldMask = oldA.length - 1) >= 0 &&
909 >            if (oldA != null && (oldMask = oldA.length - 1) > 0 &&
910                  (t = top) - (b = base) > 0) {
911                  int mask = size - 1;
912                  do { // emulate poll from old array, push to new array
913                      ForkJoinTask<?> x;
914 <                    long oldj = ((b & oldMask) << ASHIFT) + ABASE;
915 <                    long j    = ((b &    mask) << ASHIFT) + ABASE;
916 <                    x = (ForkJoinTask<?>)U.getObjectVolatile(oldA, oldj);
917 <                    if (x != null &&
872 <                        U.compareAndSwapObject(oldA, oldj, x, null))
873 <                        U.putObjectVolatile(a, j, x);
914 >                    int oldj = b & oldMask, j = b & mask;
915 >                    if ((x = getAt(oldA, oldj)) != null &&
916 >                        casAt(oldA, oldj, x, null))
917 >                        setAt(a, j, x);
918                  } while (++b != t);
919              }
920              return a;
# Line 881 | Line 925 | public class ForkJoinPool extends Abstra
925           * by owner in unshared queues.
926           */
927          final ForkJoinTask<?> pop() {
928 <            ForkJoinTask<?>[] a; ForkJoinTask<?> t; int m;
929 <            if ((a = array) != null && (m = a.length - 1) >= 0) {
928 >            ForkJoinTask<?>[] a; ForkJoinTask<?> t; int al;
929 >            if ((a = array) != null && (al = a.length) > 0) {
930                  for (int s; (s = top - 1) - base >= 0;) {
931 <                    long j = ((m & s) << ASHIFT) + ABASE;
932 <                    if ((t = (ForkJoinTask<?>)U.getObject(a, j)) == null)
931 >                    int j = (al - 1) & s;
932 >                    if ((t = getAt(a, j)) == null)
933                          break;
934 <                    if (U.compareAndSwapObject(a, j, t, null)) {
934 >                    if (casAt(a, j, t, null)) {
935                          U.putOrderedInt(this, QTOP, s);
936                          return t;
937                      }
# Line 904 | Line 948 | public class ForkJoinPool extends Abstra
948          final ForkJoinTask<?> pollAt(int b) {
949              ForkJoinTask<?> t; ForkJoinTask<?>[] a;
950              if ((a = array) != null) {
951 <                int m = a.length - 1;
952 <                long j = ((m & b) << ASHIFT) + ABASE;
953 <                if (m >= 0 &&
910 <                    (t = (ForkJoinTask<?>)U.getObjectVolatile(a, j)) != null &&
911 <                    base == b && U.compareAndSwapObject(a, j, t, null)) {
951 >                int al = a.length, j = (al - 1) & b;
952 >                if (al > 0 && (t = getAt(a, j)) != null &&
953 >                    base == b && casAt(a, j, t, null)) {
954                      base = b + 1;
955                      return t;
956                  }
# Line 920 | Line 962 | public class ForkJoinPool extends Abstra
962           * Takes next task, if one exists, in FIFO order.
963           */
964          final ForkJoinTask<?> poll() {
965 <            ForkJoinTask<?>[] a; int b; ForkJoinTask<?> t;
966 <            while ((b = base) - top < 0 && (a = array) != null) {
967 <                int m = a.length - 1;
968 <                long j = ((m & b) << ASHIFT) + ABASE;
927 <                if (m < 0)
928 <                    break;
929 <                t = (ForkJoinTask<?>)U.getObjectVolatile(a, j);
965 >            ForkJoinTask<?>[] a; int b, al, j;
966 >            while ((b = base) - top < 0 && (a = array) != null &&
967 >                   (al = a.length) > 0) {
968 >                ForkJoinTask<?> t = getAt(a, j = (al - 1) & b);
969                  if (base == b) {
970                      if (t != null) {
971 <                        if (U.compareAndSwapObject(a, j, t, null)) {
971 >                        if (casAt(a, j, t, null)) {
972                              base = b + 1;
973                              return t;
974                          }
# Line 952 | Line 991 | public class ForkJoinPool extends Abstra
991           * Returns next task, if one exists, in order specified by mode.
992           */
993          final ForkJoinTask<?> peek() {
994 <            ForkJoinTask<?>[] a = array; int m;
995 <            if (a == null || (m = a.length - 1) < 0)
996 <                return null;
997 <            int i = (config & FIFO_QUEUE) == 0 ? top - 1 : base;
998 <            long j = ((i & m) << ASHIFT) + ABASE;
999 <            return (ForkJoinTask<?>)U.getObjectVolatile(a, j);
994 >            ForkJoinTask<?>[] a = array; int al;
995 >            if (a != null && (al = a.length) > 0) {
996 >                int i = (config & FIFO_QUEUE) == 0 ? top - 1 : base;
997 >                return getAt(a, (al - 1) & i);
998 >            }
999 >            return null;
1000          }
1001  
1002          /**
# Line 967 | Line 1006 | public class ForkJoinPool extends Abstra
1006          final boolean tryUnpush(ForkJoinTask<?> t) {
1007              ForkJoinTask<?>[] a;
1008              if ((a = array) != null) {
1009 <                int b = base, m = a.length - 1, s = top;
1010 <                long j = ((m & (s - 1)) << ASHIFT) + ABASE;
1011 <                if (s != b && m >= 0 &&
973 <                    U.compareAndSwapObject(a, j, t, null)) {
1009 >                int b = base, al = a.length, s = top;
1010 >                if (s != b && al > 0 &&
1011 >                    casAt(a, (al - 1) & (s - 1), t, null)) {
1012                      U.putOrderedInt(this, QTOP, s - 1);
1013                      return true;
1014                  }
# Line 1006 | Line 1044 | public class ForkJoinPool extends Abstra
1044          }
1045  
1046          /**
1047 <         * Removes and executes all local tasks. If LIFO, invokes
1048 <         * pollAndExecAll. Otherwise implements a specialized pop loop
1049 <         * to exec until empty.
1050 <         */
1051 <        final void execLocalTasks() {
1052 <            int b = base, m, s;
1053 <            ForkJoinTask<?>[] a = array;
1054 <            if (b - (s = top - 1) <= 0 && a != null &&
1055 <                (m = a.length - 1) >= 0) {
1056 <                if ((config & FIFO_QUEUE) == 0) {
1019 <                    for (ForkJoinTask<?> t;;) {
1020 <                        long j = ((m & s) << ASHIFT) + ABASE;
1021 <                        if ((t = (ForkJoinTask<?>)U.getAndSetObject
1022 <                             (a, j, null)) == null)
1023 <                            break;
1024 <                        U.putOrderedInt(this, QTOP, s);
1025 <                        t.doExec();
1026 <                        if (base - (s = top - 1) > 0)
1027 <                            break;
1028 <                    }
1047 >         * Pops and runs tasks until empty.
1048 >         */
1049 >        final void popAndExecAll() {
1050 >            ForkJoinTask<?>[] a; ForkJoinTask<?> t;
1051 >            while ((a = array) != null) {
1052 >                int b = base, al = a.length, s = top, i = (al - 1) & (s - 1);
1053 >                if (b != s && al > 0 &&
1054 >                    (t = xchgAt(a, i, null)) != null) {
1055 >                    U.putOrderedInt(this, QTOP, s - 1);
1056 >                    t.doExec();
1057                  }
1058                  else
1059 <                    pollAndExecAll();
1059 >                    break;
1060              }
1061          }
1062  
# Line 1040 | Line 1068 | public class ForkJoinPool extends Abstra
1068                  scanState &= ~SCANNING; // mark as busy
1069                  (currentSteal = task).doExec();
1070                  U.putOrderedObject(this, QCURRENTSTEAL, null); // release for GC
1071 <                execLocalTasks();
1071 >                if ((config & FIFO_QUEUE) != 0)
1072 >                    pollAndExecAll();
1073 >                else
1074 >                    popAndExecAll();
1075                  ForkJoinWorkerThread thread = owner;
1076                  if (++nsteals < 0)      // collect on overflow
1077                      transferStealCount(pool);
# Line 1069 | Line 1100 | public class ForkJoinPool extends Abstra
1100           * @return true if queue empty and task not known to be done
1101           */
1102          final boolean tryRemoveAndExec(ForkJoinTask<?> task) {
1103 <            ForkJoinTask<?>[] a; int m, s, b, n;
1104 <            if ((a = array) != null && (m = a.length - 1) >= 0 &&
1074 <                task != null) {
1103 >            ForkJoinTask<?>[] a; int al, s, b, n;
1104 >            if ((a = array) != null && (al = a.length) > 0 && task != null) {
1105                  while ((n = (s = top) - (b = base)) > 0) {
1106                      for (ForkJoinTask<?> t;;) {      // traverse from s to b
1107 <                        long j = ((--s & m) << ASHIFT) + ABASE;
1108 <                        if ((t = (ForkJoinTask<?>)U.getObject(a, j)) == null)
1107 >                        int j = --s & (al - 1);
1108 >                        if ((t = getAt(a, j)) == null)
1109                              return s + 1 == top;     // shorter than expected
1110                          else if (t == task) {
1111                              boolean removed = false;
1112                              if (s + 1 == top) {      // pop
1113 <                                if (U.compareAndSwapObject(a, j, task, null)) {
1113 >                                if (casAt(a, j, task, null)) {
1114                                      U.putOrderedInt(this, QTOP, s);
1115                                      removed = true;
1116                                  }
1117                              }
1118                              else if (base == b)      // replace with proxy
1119 <                                removed = U.compareAndSwapObject(
1090 <                                    a, j, task, new EmptyTask());
1119 >                                removed = casAt(a, j, task, new EmptyTask());
1120                              if (removed)
1121                                  task.doExec();
1122                              break;
1123                          }
1124                          else if (t.status < 0 && s + 1 == top) {
1125 <                            if (U.compareAndSwapObject(a, j, t, null))
1125 >                            if (casAt(a, j, t, null))
1126                                  U.putOrderedInt(this, QTOP, s);
1127                              break;                  // was cancelled
1128                          }
# Line 1112 | Line 1141 | public class ForkJoinPool extends Abstra
1141           * in either shared or owned mode. Used only by helpComplete.
1142           */
1143          final CountedCompleter<?> popCC(CountedCompleter<?> task, int mode) {
1144 <            int s; ForkJoinTask<?>[] a; Object o;
1145 <            if (base - (s = top) < 0 && (a = array) != null) {
1146 <                int m = a.length - 1;
1147 <                long j = ((m & (s - 1)) << ASHIFT) + ABASE;
1148 <                if (m >= 0 && (o = U.getObjectVolatile(a, j)) != null &&
1120 <                    (o instanceof CountedCompleter)) {
1144 >            ForkJoinTask<?>[] a; ForkJoinTask<?> o;
1145 >            if ((a = array) != null) {
1146 >                int b = base, al = a.length, s = top, i = (al - 1) & (s - 1);
1147 >                if (b != s && al > 0 &&
1148 >                    ((o = a[i]) instanceof CountedCompleter)) {
1149                      CountedCompleter<?> t = (CountedCompleter<?>)o;
1150                      for (CountedCompleter<?> r = t;;) {
1151                          if (r == task) {
1152                              if (mode < 0) { // must lock
1153                                  if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
1154                                      if (top == s && array == a &&
1155 <                                        U.compareAndSwapObject(a, j, t, null)) {
1155 >                                        casAt(a, i, t, null)) {
1156                                          U.putOrderedInt(this, QTOP, s - 1);
1157                                          U.putOrderedInt(this, QLOCK, 0);
1158                                          return t;
# Line 1132 | Line 1160 | public class ForkJoinPool extends Abstra
1160                                      U.compareAndSwapInt(this, QLOCK, 1, 0);
1161                                  }
1162                              }
1163 <                            else if (U.compareAndSwapObject(a, j, t, null)) {
1163 >                            else if (casAt(a, i, t, null)) {
1164                                  U.putOrderedInt(this, QTOP, s - 1);
1165                                  return t;
1166                              }
# Line 1157 | Line 1185 | public class ForkJoinPool extends Abstra
1185           * the base index, forced negative.
1186           */
1187          final int pollAndExecCC(CountedCompleter<?> task) {
1188 <            int b, h; ForkJoinTask<?>[] a; Object o;
1189 <            if ((b = base) - top >= 0 || (a = array) == null)
1188 >            int b, h, j, al; ForkJoinTask<?>[] a; Object o;
1189 >            if ((b = base) - top >= 0 || (a = array) == null ||
1190 >                (al = a.length) <= 0)
1191                  h = b | Integer.MIN_VALUE;  // to sense movement on re-poll
1192 +            else if ((o = getAt(a, j = (al - 1) & b)) == null)
1193 +                h = 2;                      // retryable
1194 +            else if (!(o instanceof CountedCompleter))
1195 +                h = -1;                     // unmatchable
1196              else {
1197 <                int m = a.length - 1;
1198 <                long j = ((m & b) << ASHIFT) + ABASE;
1199 <                if (m < 0 || (o = U.getObjectVolatile(a, j)) == null)
1200 <                    h = 2;                  // retryable
1201 <                else if (!(o instanceof CountedCompleter))
1202 <                    h = -1;                 // unmatchable
1203 <                else {
1171 <                    CountedCompleter<?> t = (CountedCompleter<?>)o;
1172 <                    for (CountedCompleter<?> r = t;;) {
1173 <                        if (r == task) {
1174 <                            if (base == b &&
1175 <                                U.compareAndSwapObject(a, j, t, null)) {
1176 <                                base = b + 1;
1177 <                                t.doExec();
1178 <                                h = 1;      // success
1179 <                            }
1180 <                            else
1181 <                                h = 2;      // lost CAS
1182 <                            break;
1183 <                        }
1184 <                        else if ((r = r.completer) == null) {
1185 <                            h = -1;         // unmatched
1186 <                            break;
1197 >                CountedCompleter<?> t = (CountedCompleter<?>)o;
1198 >                for (CountedCompleter<?> r = t;;) {
1199 >                    if (r == task) {
1200 >                        if (base == b && casAt(a, j, t, null)) {
1201 >                            base = b + 1;
1202 >                            t.doExec();
1203 >                            h = 1;          // success
1204                          }
1205 +                        else
1206 +                            h = 2;          // lost CAS
1207 +                        break;
1208 +                    }
1209 +                    else if ((r = r.completer) == null) {
1210 +                        h = -1;             // unmatched
1211 +                        break;
1212                      }
1213                  }
1214              }
# Line 1703 | Line 1727 | public class ForkJoinPool extends Abstra
1727          if ((ws = workQueues) != null && (m = ws.length - 1) > 0 && w != null) {
1728              int ss = w.scanState;                     // initially non-negative
1729              for (int origin = r & m, k = origin, oldSum = 0, checkSum = 0;;) {
1730 <                WorkQueue q; ForkJoinTask<?>[] a; ForkJoinTask<?> t;
1707 <                int b, am, n; long c;
1730 >                WorkQueue q; ForkJoinTask<?> t; int al, i, n; long c;
1731                  if ((q = ws[k]) != null) {
1732 <                    if ((n = (b = q.base) - q.top) < 0 &&  // non-empty
1733 <                        (a = q.array) != null) {
1734 <                        long i = (((am = a.length - 1) & b) << ASHIFT) + ABASE;
1735 <                        if (am >= 0 &&
1713 <                            (t = ((ForkJoinTask<?>)
1714 <                                  U.getObjectVolatile(a, i))) != null &&
1732 >                    int b = q.base; ForkJoinTask<?>[] a = q.array;
1733 >                    if ((n = b - q.top) < 0 && a != null &&
1734 >                        (al = a.length) > 0) {        // non-empty
1735 >                        if ((t = getAt(a, i = (al - 1)  & b)) != null &&
1736                              q.base == b) {
1737                              if (ss >= 0) {
1738 <                                if (U.compareAndSwapObject(a, i, t, null)) {
1738 >                                if (casAt(a, i, t, null)) {
1739                                      q.base = b + 1;
1740                                      if (n < -1)       // signal others
1741                                          signalWork(ws, q);
# Line 1843 | Line 1864 | public class ForkJoinPool extends Abstra
1864      final int helpComplete(WorkQueue w, CountedCompleter<?> task,
1865                             int maxTasks) {
1866          WorkQueue[] ws; int s = 0, m;
1867 <        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
1867 >        if ((ws = workQueues) != null && (m = ws.length - 1) > 0 &&
1868              task != null && w != null) {
1869              int mode = w.config;                 // for popCC
1870              int r = w.hint ^ w.top;              // arbitrary seed for origin
# Line 1899 | Line 1920 | public class ForkJoinPool extends Abstra
1920      private void helpStealer(WorkQueue w, ForkJoinTask<?> task) {
1921          WorkQueue[] ws = workQueues;
1922          int oldSum = 0, checkSum, m;
1923 <        if (ws != null && (m = ws.length - 1) >= 0 && w != null &&
1923 >        if (ws != null && (m = ws.length - 1) > 0 && w != null &&
1924              task != null) {
1925              do {                                       // restart point
1926                  checkSum = 0;                          // for stability check
# Line 1918 | Line 1939 | public class ForkJoinPool extends Abstra
1939                          }
1940                      }
1941                      for (;;) {                         // help v or descend
1942 <                        ForkJoinTask<?>[] a; int b, am;
1942 >                        ForkJoinTask<?>[] a; int b, al, i;
1943                          checkSum += (b = v.base);
1944                          ForkJoinTask<?> next = v.currentJoin;
1945                          if (subtask.status < 0 || j.currentJoin != subtask ||
1946                              v.currentSteal != subtask) // stale
1947                              break descent;
1948                          if (b - v.top >= 0 || (a = v.array) == null ||
1949 <                            (am = a.length - 1) < 0) {
1949 >                            (al = a.length) <= 0) {
1950                              if ((subtask = next) == null)
1951                                  break descent;
1952                              j = v;
1953                              break;
1954                          }
1955 <                        long i = ((am & b) << ASHIFT) + ABASE;
1935 <                        ForkJoinTask<?> t = ((ForkJoinTask<?>)
1936 <                                             U.getObjectVolatile(a, i));
1955 >                        ForkJoinTask<?> t = getAt(a, i = (al - 1) & b);
1956                          if (v.base == b) {
1957                              if (t == null)             // stale
1958                                  break descent;
1959 <                            if (U.compareAndSwapObject(a, i, t, null)) {
1959 >                            if (casAt(a, i, t, null)) {
1960                                  v.base = b + 1;
1961                                  ForkJoinTask<?> ps = w.currentSteal;
1962                                  int top = w.top;
# Line 2062 | Line 2081 | public class ForkJoinPool extends Abstra
2081      private WorkQueue findNonEmptyStealQueue() {
2082          WorkQueue[] ws; int m;  // one-shot version of scan loop
2083          int r = ThreadLocalRandom.nextSecondarySeed();
2084 <        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0) {
2084 >        if ((ws = workQueues) != null && (m = ws.length - 1) > 0) {
2085              for (int origin = r & m, k = origin, oldSum = 0, checkSum = 0;;) {
2086                  WorkQueue q; int b;
2087                  if ((q = ws[k]) != null) {
# Line 2090 | Line 2109 | public class ForkJoinPool extends Abstra
2109          ForkJoinTask<?> ps = w.currentSteal; // save context
2110          for (boolean active = true;;) {
2111              long c; WorkQueue q; ForkJoinTask<?> t; int b;
2112 <            w.execLocalTasks();     // run locals before each scan
2112 >            if ((w.config & FIFO_QUEUE) != 0)
2113 >                w.pollAndExecAll();  // run locals before each scan
2114 >            else
2115 >                w.popAndExecAll();
2116              if ((q = findNonEmptyStealQueue()) != null) {
2117                  if (!active) {      // re-establish active count
2118                      active = true;
# Line 2316 | Line 2338 | public class ForkJoinPool extends Abstra
2338                  throw new RejectedExecutionException();
2339              }
2340              else if ((rs & STARTED) == 0 ||     // initialize
2341 <                     ((ws = workQueues) == null || (m = ws.length - 1) < 0)) {
2341 >                     ((ws = workQueues) == null || (m = ws.length - 1) <= 0)) {
2342                  int ns = 0;
2343                  rs = lockRunState();
2344                  try {
# Line 2338 | Line 2360 | public class ForkJoinPool extends Abstra
2360              else if ((q = ws[k = r & m & SQMASK]) != null) {
2361                  if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) {
2362                      ForkJoinTask<?>[] a = q.array;
2363 <                    int s = q.top, am;
2363 >                    int s = q.top;
2364                      boolean submitted = false; // initial submission or resizing
2365                      try {                      // locked version of push
2366 <                        if (((a != null && a.length > s + 1 - q.base) ||
2367 <                             (a = q.growArray()) != null) &&
2368 <                            (am = a.length - 1) >= 0) {
2369 <                            long j = ((am & s) << ASHIFT) + ABASE;
2370 <                            U.putOrderedObject(a, j, task);
2371 <                            U.putOrderedInt(q, QTOP, s + 1);
2372 <                            submitted = true;
2366 >                        if ((a != null && a.length > s + 1 - q.base) ||
2367 >                            (a = q.growArray()) != null) {
2368 >                            int al = a.length, j = (al - 1) & s;
2369 >                            if (al > 0) {
2370 >                                setAt(a, j, task);
2371 >                                U.putOrderedInt(q, QTOP, s + 1);
2372 >                                submitted = true;
2373 >                            }
2374                          }
2375                      } finally {
2376                          U.compareAndSwapInt(q, QLOCK, 1, 0);
# Line 2389 | Line 2412 | public class ForkJoinPool extends Abstra
2412          WorkQueue[] ws; WorkQueue q; int m;
2413          int r = ThreadLocalRandom.getProbe();
2414          int rs = runState;
2415 <        if ((ws = workQueues) != null && (m = (ws.length - 1)) >= 0 &&
2415 >        if ((ws = workQueues) != null && (m = (ws.length - 1)) > 0 &&
2416              (q = ws[m & r & SQMASK]) != null && r != 0 && rs > 0 &&
2417              U.compareAndSwapInt(q, QLOCK, 0, 1)) {
2418              ForkJoinTask<?>[] a;
2419              if ((a = q.array) != null) {
2420 <                int b = q.base, am = a.length - 1, s, n;
2421 <                long j = ((am & (s = q.top)) << ASHIFT) + ABASE;
2422 <                if (am > (n = s - b) && am >= 0) {
2423 <                    U.putOrderedObject(a, j, task);
2424 <                    U.putOrderedInt(q, QTOP, s + 1);
2425 <                    U.putOrderedInt(q, QLOCK, 0);
2426 <                    if (n <= 1)
2427 <                        signalWork(ws, q);
2428 <                    return;
2420 >                int b = q.base, al = a.length, s = q.top;
2421 >                if (al > 0) {
2422 >                    int am = al - 1, j = am & s, n;
2423 >                    if ((n = s - b) < am) {
2424 >                        setAt(a, j, task);
2425 >                        U.putOrderedInt(q, QTOP, s + 1);
2426 >                        U.putOrderedInt(q, QLOCK, 0);
2427 >                        if (n <= 1)
2428 >                            signalWork(ws, q);
2429 >                        return;
2430 >                    }
2431                  }
2432              }
2433              U.compareAndSwapInt(q, QLOCK, 1, 0);
# Line 2418 | Line 2443 | public class ForkJoinPool extends Abstra
2443          int r = ThreadLocalRandom.getProbe();
2444          WorkQueue[] ws; int m;
2445          return (p != null && (ws = p.workQueues) != null &&
2446 <                (m = ws.length - 1) >= 0) ?
2446 >                (m = ws.length - 1) > 0) ?
2447              ws[m & r & SQMASK] : null;
2448      }
2449  
# Line 2430 | Line 2455 | public class ForkJoinPool extends Abstra
2455      final boolean tryExternalUnpush(ForkJoinTask<?> task) {
2456          WorkQueue[] ws; WorkQueue w; ForkJoinTask<?>[] a; int m;
2457          int r = ThreadLocalRandom.getProbe();
2458 <        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
2458 >        if ((ws = workQueues) != null && (m = ws.length - 1) > 0 &&
2459              (w = ws[m & r & SQMASK]) != null &&
2460              (a = w.array) != null) {
2461 <            int b = w.base, am = a.length - 1, s = w.top;
2462 <            long j = ((am & (s - 1)) << ASHIFT) + ABASE;
2463 <            if (s != b && am >= 0 && U.compareAndSwapInt(w, QLOCK, 0, 1)) {
2464 <                if (w.top == s && w.array == a &&
2465 <                    U.getObject(a, j) == task &&
2441 <                    U.compareAndSwapObject(a, j, task, null)) {
2461 >            int b = w.base, al = a.length, s = w.top;
2462 >            if (s != b && al > 0 &&
2463 >                U.compareAndSwapInt(w, QLOCK, 0, 1)) {
2464 >                int i = (al - 1) & (s - 1);
2465 >                if (w.top == s && w.array == a && casAt(a, i, task, null)) {
2466                      U.putOrderedInt(w, QTOP, s - 1);
2467                      U.putOrderedInt(w, QLOCK, 0);
2468                      return true;
# Line 3161 | Line 3185 | public class ForkJoinPool extends Abstra
3185          int r = 0, m;
3186          boolean found = true;
3187          while (!isQuiescent() && (ws = workQueues) != null &&
3188 <               (m = ws.length - 1) >= 0) {
3188 >               (m = ws.length - 1) > 0) {
3189              if (!found) {
3190                  if ((System.nanoTime() - startTime) > nanos)
3191                      return false;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines