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.223 by dl, Fri Aug 29 13:40:09 2014 UTC vs.
Revision 1.224 by dl, Sat Sep 13 16:11:45 2014 UTC

# Line 832 | Line 832 | public class ForkJoinPool extends Abstra
832           */
833          final void push(ForkJoinTask<?> task) {
834              ForkJoinTask<?>[] a; ForkJoinPool p;
835 <            int b = base, s = top, n;
836 <            if ((a = array) != null) {    // ignore if queue removed
837 <                int m = a.length - 1;     // fenced write for task visibility
838 <                U.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task);
839 <                U.putOrderedInt(this, QTOP, s + 1);
840 <                if ((n = s - b) <= 1) {
841 <                    if ((p = pool) != null)
842 <                        p.signalWork(p.workQueues, this);
835 >            if ((a = array) != null) {  // ignore if no queue
836 >                int b = base, m = a.length - 1, s = top, n;
837 >                long j = ((m & s) << ASHIFT) + ABASE;
838 >                if (m >= 0) {
839 >                    U.putOrderedObject(a, j, task);
840 >                    U.putOrderedInt(this, QTOP, s + 1);
841 >                    if ((n = s - b) <= 1) {
842 >                        if ((p = pool) != null)
843 >                            p.signalWork(p.workQueues, this);
844 >                    }
845 >                    else if (n >= m)
846 >                        growArray();
847                  }
844                else if (n >= m)
845                    growArray();
848              }
849          }
850  
# Line 854 | Line 856 | public class ForkJoinPool extends Abstra
856          final ForkJoinTask<?>[] growArray() {
857              ForkJoinTask<?>[] oldA = array;
858              int size = oldA != null ? oldA.length << 1 : INITIAL_QUEUE_CAPACITY;
859 <            if (size > MAXIMUM_QUEUE_CAPACITY)
859 >            if (size < 0 || size > MAXIMUM_QUEUE_CAPACITY)
860                  throw new RejectedExecutionException("Queue capacity exceeded");
861              int oldMask, t, b;
862              ForkJoinTask<?>[] a = array = new ForkJoinTask<?>[size];
# Line 863 | Line 865 | public class ForkJoinPool extends Abstra
865                  int mask = size - 1;
866                  do { // emulate poll from old array, push to new array
867                      ForkJoinTask<?> x;
868 <                    int oldj = ((b & oldMask) << ASHIFT) + ABASE;
869 <                    int j    = ((b &    mask) << ASHIFT) + ABASE;
868 >                    long oldj = ((b & oldMask) << ASHIFT) + ABASE;
869 >                    long j    = ((b &    mask) << ASHIFT) + ABASE;
870                      x = (ForkJoinTask<?>)U.getObjectVolatile(oldA, oldj);
871                      if (x != null &&
872                          U.compareAndSwapObject(oldA, oldj, x, null))
# Line 902 | Line 904 | public class ForkJoinPool extends Abstra
904          final ForkJoinTask<?> pollAt(int b) {
905              ForkJoinTask<?> t; ForkJoinTask<?>[] a;
906              if ((a = array) != null) {
907 <                int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
908 <                if ((t = (ForkJoinTask<?>)U.getObjectVolatile(a, j)) != null &&
907 >                int m = a.length - 1;
908 >                long j = ((m & b) << ASHIFT) + ABASE;
909 >                if (m >= 0 &&
910 >                    (t = (ForkJoinTask<?>)U.getObjectVolatile(a, j)) != null &&
911                      base == b && U.compareAndSwapObject(a, j, t, null)) {
912                      base = b + 1;
913                      return t;
# Line 918 | Line 922 | public class ForkJoinPool extends Abstra
922          final ForkJoinTask<?> poll() {
923              ForkJoinTask<?>[] a; int b; ForkJoinTask<?> t;
924              while ((b = base) - top < 0 && (a = array) != null) {
925 <                int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
925 >                int m = a.length - 1;
926 >                long j = ((m & b) << ASHIFT) + ABASE;
927 >                if (m < 0)
928 >                    break;
929                  t = (ForkJoinTask<?>)U.getObjectVolatile(a, j);
930                  if (base == b) {
931                      if (t != null) {
# Line 949 | Line 956 | public class ForkJoinPool extends Abstra
956              if (a == null || (m = a.length - 1) < 0)
957                  return null;
958              int i = (config & FIFO_QUEUE) == 0 ? top - 1 : base;
959 <            int j = ((i & m) << ASHIFT) + ABASE;
959 >            long j = ((i & m) << ASHIFT) + ABASE;
960              return (ForkJoinTask<?>)U.getObjectVolatile(a, j);
961          }
962  
# Line 958 | Line 965 | public class ForkJoinPool extends Abstra
965           * (A shared version is available only via FJP.tryExternalUnpush)
966          */
967          final boolean tryUnpush(ForkJoinTask<?> t) {
968 <            ForkJoinTask<?>[] a; int s;
969 <            if ((a = array) != null && (s = top) != base &&
970 <                U.compareAndSwapObject
971 <                (a, (((a.length - 1) & --s) << ASHIFT) + ABASE, t, null)) {
972 <                U.putOrderedInt(this, QTOP, s);
973 <                return true;
968 >            ForkJoinTask<?>[] a;
969 >            if ((a = array) != null) {
970 >                int b = base, m = a.length - 1, s = top;
971 >                long j = ((m & (s - 1)) << ASHIFT) + ABASE;
972 >                if (s != b && m >= 0 &&
973 >                    U.compareAndSwapObject(a, j, t, null)) {
974 >                    U.putOrderedInt(this, QTOP, s - 1);
975 >                    return true;
976 >                }
977              }
978              return false;
979          }
# Line 1007 | Line 1017 | public class ForkJoinPool extends Abstra
1017                  (m = a.length - 1) >= 0) {
1018                  if ((config & FIFO_QUEUE) == 0) {
1019                      for (ForkJoinTask<?> t;;) {
1020 +                        long j = ((m & s) << ASHIFT) + ABASE;
1021                          if ((t = (ForkJoinTask<?>)U.getAndSetObject
1022 <                             (a, ((m & s) << ASHIFT) + ABASE, null)) == null)
1022 >                             (a, j, null)) == null)
1023                              break;
1024                          U.putOrderedInt(this, QTOP, s);
1025                          t.doExec();
# Line 1103 | Line 1114 | public class ForkJoinPool extends Abstra
1114          final CountedCompleter<?> popCC(CountedCompleter<?> task, int mode) {
1115              int s; ForkJoinTask<?>[] a; Object o;
1116              if (base - (s = top) < 0 && (a = array) != null) {
1117 <                long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
1118 <                if ((o = U.getObjectVolatile(a, j)) != null &&
1117 >                int m = a.length - 1;
1118 >                long j = ((m & (s - 1)) << ASHIFT) + ABASE;
1119 >                if (m >= 0 && (o = U.getObjectVolatile(a, j)) != null &&
1120                      (o instanceof CountedCompleter)) {
1121                      CountedCompleter<?> t = (CountedCompleter<?>)o;
1122                      for (CountedCompleter<?> r = t;;) {
# Line 1149 | Line 1161 | public class ForkJoinPool extends Abstra
1161              if ((b = base) - top >= 0 || (a = array) == null)
1162                  h = b | Integer.MIN_VALUE;  // to sense movement on re-poll
1163              else {
1164 <                long j = (((a.length - 1) & b) << ASHIFT) + ABASE;
1165 <                if ((o = U.getObjectVolatile(a, j)) == null)
1164 >                int m = a.length - 1;
1165 >                long j = ((m & b) << ASHIFT) + ABASE;
1166 >                if (m < 0 || (o = U.getObjectVolatile(a, j)) == null)
1167                      h = 2;                  // retryable
1168                  else if (!(o instanceof CountedCompleter))
1169                      h = -1;                 // unmatchable
# Line 1691 | Line 1704 | public class ForkJoinPool extends Abstra
1704              int ss = w.scanState;                     // initially non-negative
1705              for (int origin = r & m, k = origin, oldSum = 0, checkSum = 0;;) {
1706                  WorkQueue q; ForkJoinTask<?>[] a; ForkJoinTask<?> t;
1707 <                int b, n; long c;
1707 >                int b, am, n; long c;
1708                  if ((q = ws[k]) != null) {
1709 <                    if ((n = (b = q.base) - q.top) < 0 &&
1710 <                        (a = q.array) != null) {      // non-empty
1711 <                        long i = (((a.length - 1) & b) << ASHIFT) + ABASE;
1712 <                        if ((t = ((ForkJoinTask<?>)
1709 >                    if ((n = (b = q.base) - q.top) < 0 &&  // non-empty
1710 >                        (a = q.array) != null) {
1711 >                        long i = (((am = a.length - 1) & b) << ASHIFT) + ABASE;
1712 >                        if (am >= 0 &&
1713 >                            (t = ((ForkJoinTask<?>)
1714                                    U.getObjectVolatile(a, i))) != null &&
1715                              q.base == b) {
1716                              if (ss >= 0) {
# Line 1904 | Line 1918 | public class ForkJoinPool extends Abstra
1918                          }
1919                      }
1920                      for (;;) {                         // help v or descend
1921 <                        ForkJoinTask<?>[] a; int b;
1921 >                        ForkJoinTask<?>[] a; int b, am;
1922                          checkSum += (b = v.base);
1923                          ForkJoinTask<?> next = v.currentJoin;
1924                          if (subtask.status < 0 || j.currentJoin != subtask ||
1925                              v.currentSteal != subtask) // stale
1926                              break descent;
1927 <                        if (b - v.top >= 0 || (a = v.array) == null) {
1927 >                        if (b - v.top >= 0 || (a = v.array) == null ||
1928 >                            (am = a.length - 1) < 0) {
1929                              if ((subtask = next) == null)
1930                                  break descent;
1931                              j = v;
1932                              break;
1933                          }
1934 <                        int i = (((a.length - 1) & b) << ASHIFT) + ABASE;
1934 >                        long i = ((am & b) << ASHIFT) + ABASE;
1935                          ForkJoinTask<?> t = ((ForkJoinTask<?>)
1936                                               U.getObjectVolatile(a, i));
1937                          if (v.base == b) {
# Line 2323 | Line 2338 | public class ForkJoinPool extends Abstra
2338              else if ((q = ws[k = r & m & SQMASK]) != null) {
2339                  if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) {
2340                      ForkJoinTask<?>[] a = q.array;
2341 <                    int s = q.top;
2341 >                    int s = q.top, am;
2342                      boolean submitted = false; // initial submission or resizing
2343                      try {                      // locked version of push
2344 <                        if ((a != null && a.length > s + 1 - q.base) ||
2345 <                            (a = q.growArray()) != null) {
2346 <                            int j = (((a.length - 1) & s) << ASHIFT) + ABASE;
2344 >                        if (((a != null && a.length > s + 1 - q.base) ||
2345 >                             (a = q.growArray()) != null) &&
2346 >                            (am = a.length - 1) >= 0) {
2347 >                            long j = ((am & s) << ASHIFT) + ABASE;
2348                              U.putOrderedObject(a, j, task);
2349                              U.putOrderedInt(q, QTOP, s + 1);
2350                              submitted = true;
# Line 2376 | Line 2392 | public class ForkJoinPool extends Abstra
2392          if ((ws = workQueues) != null && (m = (ws.length - 1)) >= 0 &&
2393              (q = ws[m & r & SQMASK]) != null && r != 0 && rs > 0 &&
2394              U.compareAndSwapInt(q, QLOCK, 0, 1)) {
2395 <            ForkJoinTask<?>[] a; int am, n, s;
2396 <            if ((a = q.array) != null &&
2397 <                (am = a.length - 1) > (n = (s = q.top) - q.base)) {
2398 <                int j = ((am & s) << ASHIFT) + ABASE;
2399 <                U.putOrderedObject(a, j, task);
2400 <                U.putOrderedInt(q, QTOP, s + 1);
2401 <                U.putOrderedInt(q, QLOCK, 0);
2402 <                if (n <= 1)
2403 <                    signalWork(ws, q);
2404 <                return;
2395 >            ForkJoinTask<?>[] a;
2396 >            if ((a = q.array) != null) {
2397 >                int b = q.base, am = a.length - 1, s, n;
2398 >                long j = ((am & (s = q.top)) << ASHIFT) + ABASE;
2399 >                if (am > (n = s - b) && am >= 0) {
2400 >                    U.putOrderedObject(a, j, task);
2401 >                    U.putOrderedInt(q, QTOP, s + 1);
2402 >                    U.putOrderedInt(q, QLOCK, 0);
2403 >                    if (n <= 1)
2404 >                        signalWork(ws, q);
2405 >                    return;
2406 >                }
2407              }
2408              U.compareAndSwapInt(q, QLOCK, 1, 0);
2409          }
# Line 2410 | Line 2428 | public class ForkJoinPool extends Abstra
2428       * adjusts top. Each check can fail but rarely does.
2429       */
2430      final boolean tryExternalUnpush(ForkJoinTask<?> task) {
2431 <        WorkQueue[] ws; WorkQueue w; ForkJoinTask<?>[] a; int m, s;
2431 >        WorkQueue[] ws; WorkQueue w; ForkJoinTask<?>[] a; int m;
2432          int r = ThreadLocalRandom.getProbe();
2433          if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
2434              (w = ws[m & r & SQMASK]) != null &&
2435 <            (a = w.array) != null && (s = w.top) != w.base) {
2436 <            long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
2437 <            if (U.compareAndSwapInt(w, QLOCK, 0, 1)) {
2435 >            (a = w.array) != null) {
2436 >            int b = w.base, am = a.length - 1, s = w.top;
2437 >            long j = ((am & (s - 1)) << ASHIFT) + ABASE;
2438 >            if (s != b && am >= 0 && U.compareAndSwapInt(w, QLOCK, 0, 1)) {
2439                  if (w.top == s && w.array == a &&
2440                      U.getObject(a, j) == task &&
2441                      U.compareAndSwapObject(a, j, task, null)) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines