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.313 by jsr166, Tue May 3 20:58:33 2016 UTC vs.
Revision 1.314 by dl, Thu Jun 2 13:16:27 2016 UTC

# Line 7 | Line 7
7   package java.util.concurrent;
8  
9   import java.lang.Thread.UncaughtExceptionHandler;
10 + import java.lang.invoke.MethodHandles;
11 + import java.lang.invoke.VarHandle;
12   import java.security.AccessControlContext;
13   import java.security.Permissions;
14   import java.security.ProtectionDomain;
# Line 260 | Line 262 | public class ForkJoinPool extends Abstra
262       * different position to use or create other queues -- they block
263       * only when creating and registering new queues. Because it is
264       * used only as a spinlock, unlocking requires only a "releasing"
265 <     * store (using putIntRelease).
265 >     * store (using setRelease).
266       *
267       * Management
268       * ==========
# Line 540 | Line 542 | public class ForkJoinPool extends Abstra
542       * Style notes
543       * ===========
544       *
545 <     * Memory ordering relies mainly on Unsafe intrinsics that carry
546 <     * the further responsibility of explicitly performing null- and
547 <     * bounds- checks otherwise carried out implicitly by JVMs.  This
548 <     * can be awkward and ugly, but also reflects the need to control
549 <     * outcomes across the unusual cases that arise in very racy code
550 <     * with very few invariants. So these explicit checks would exist
551 <     * in some form anyway.  All fields are read into locals before
552 <     * use, and null-checked if they are references.  This is usually
553 <     * done in a "C"-like style of listing declarations at the heads
554 <     * of methods or blocks, and using inline assignments on first
555 <     * encounter.  Array bounds-checks are usually performed by
554 <     * masking with array.length-1, which relies on the invariant that
555 <     * these arrays are created with positive lengths, which is itself
556 <     * paranoically checked. Nearly all explicit checks lead to
557 <     * bypass/return, not exception throws, because they may
558 <     * legitimately arise due to cancellation/revocation during
559 <     * shutdown.
545 >     * Memory ordering relies mainly on VarHandles This can be awkward
546 >     * and ugly, but also reflects the need to control outcomes across
547 >     * the unusual cases that arise in very racy code with very few
548 >     * invariants. So these explicit checks would exist in some form
549 >     * anyway.  All fields are read into locals before use, and
550 >     * null-checked if they are references.  This is usually done in a
551 >     * "C"-like style of listing declarations at the heads of methods
552 >     * or blocks, and using inline assignments on first encounter.
553 >     * Nearly all explicit checks lead to bypass/return, not exception
554 >     * throws, because they may legitimately arise due to
555 >     * cancellation/revocation during shutdown.
556       *
557       * There is a lot of representation-level coupling among classes
558       * ForkJoinPool, ForkJoinWorkerThread, and ForkJoinTask.  The
# Line 752 | Line 748 | public class ForkJoinPool extends Abstra
748              int s = top; ForkJoinTask<?>[] a; int al, d;
749              if ((a = array) != null && (al = a.length) > 0) {
750                  int index = (al - 1) & s;
755                long offset = ((long)index << ASHIFT) + ABASE;
751                  ForkJoinPool p = pool;
752                  top = s + 1;
753 <                U.putObjectRelease(a, offset, task);
753 >                QA.setRelease(a, index, task);
754                  if ((d = base - s) == 0 && p != null) {
755 <                    U.fullFence();
755 >                    VarHandle.fullFence();
756                      p.signalWork();
757                  }
758                  else if (d + al == 1)
# Line 783 | Line 778 | public class ForkJoinPool extends Abstra
778                  int mask = size - 1;
779                  do { // emulate poll from old array, push to new array
780                      int index = b & oldMask;
786                    long offset = ((long)index << ASHIFT) + ABASE;
781                      ForkJoinTask<?> x = (ForkJoinTask<?>)
782 <                        U.getObjectVolatile(oldA, offset);
782 >                        QA.getVolatile(oldA, index);
783                      if (x != null &&
784 <                        U.compareAndSwapObject(oldA, offset, x, null))
784 >                        QA.compareAndSet(oldA, index, x, null))
785                          a[b & mask] = x;
786                  } while (++b != t);
787 <                U.storeFence();
787 >                VarHandle.releaseFence();
788              }
789              return a;
790          }
# Line 803 | Line 797 | public class ForkJoinPool extends Abstra
797              int b = base, s = top, al, i; ForkJoinTask<?>[] a;
798              if ((a = array) != null && b != s && (al = a.length) > 0) {
799                  int index = (al - 1) & --s;
806                long offset = ((long)index << ASHIFT) + ABASE;
800                  ForkJoinTask<?> t = (ForkJoinTask<?>)
801 <                    U.getObject(a, offset);
801 >                    QA.get(a, index);
802                  if (t != null &&
803 <                    U.compareAndSwapObject(a, offset, t, null)) {
803 >                    QA.compareAndSet(a, index, t, null)) {
804                      top = s;
805 <                    U.storeFence();
805 >                    VarHandle.releaseFence();
806                      return t;
807                  }
808              }
# Line 825 | Line 818 | public class ForkJoinPool extends Abstra
818                  if ((a = array) != null && (d = b - s) < 0 &&
819                      (al = a.length) > 0) {
820                      int index = (al - 1) & b;
828                    long offset = ((long)index << ASHIFT) + ABASE;
821                      ForkJoinTask<?> t = (ForkJoinTask<?>)
822 <                        U.getObjectVolatile(a, offset);
822 >                        QA.getVolatile(a, index);
823                      if (b++ == base) {
824                          if (t != null) {
825 <                            if (U.compareAndSwapObject(a, offset, t, null)) {
825 >                            if (QA.compareAndSet(a, index, t, null)) {
826                                  base = b;
827                                  return t;
828                              }
# Line 869 | Line 861 | public class ForkJoinPool extends Abstra
861              int b = base, s = top, al; ForkJoinTask<?>[] a;
862              if ((a = array) != null && b != s && (al = a.length) > 0) {
863                  int index = (al - 1) & --s;
864 <                long offset = ((long)index << ASHIFT) + ABASE;
873 <                if (U.compareAndSwapObject(a, offset, task, null)) {
864 >                if (QA.compareAndSet(a, index, task, null)) {
865                      top = s;
866 <                    U.storeFence();
866 >                    VarHandle.releaseFence();
867                      return true;
868                  }
869              }
# Line 899 | Line 890 | public class ForkJoinPool extends Abstra
890                  int b = base, s = top, al; ForkJoinTask<?>[] a;
891                  if ((a = array) != null && b != s && (al = a.length) > 0) {
892                      int index = (al - 1) & --s;
902                    long offset = ((long)index << ASHIFT) + ABASE;
893                      ForkJoinTask<?> t = (ForkJoinTask<?>)
894 <                        U.getAndSetObject(a, offset, null);
894 >                        QA.getAndSet(a, index, null);
895                      if (t != null) {
896                          top = s;
897 <                        U.storeFence();
897 >                        VarHandle.releaseFence();
898                          t.doExec();
899                          if (limit != 0 && --limit == 0)
900                              break;
# Line 928 | Line 918 | public class ForkJoinPool extends Abstra
918                  if ((a = array) != null && (d = b - s) < 0 &&
919                      (al = a.length) > 0) {
920                      int index = (al - 1) & b++;
931                    long offset = ((long)index << ASHIFT) + ABASE;
921                      ForkJoinTask<?> t = (ForkJoinTask<?>)
922 <                        U.getAndSetObject(a, offset, null);
922 >                        QA.getAndSet(a, index, null);
923                      if (t != null) {
924                          base = b;
925                          t.doExec();
# Line 956 | Line 945 | public class ForkJoinPool extends Abstra
945                  (wa = array) != null && (wal = wa.length) > 0) {
946                  for (int m = wal - 1, ns = s - 1, i = ns; ; --i) {
947                      int index = i & m;
959                    long offset = (index << ASHIFT) + ABASE;
948                      ForkJoinTask<?> t = (ForkJoinTask<?>)
949 <                        U.getObject(wa, offset);
949 >                        QA.get(wa, index);
950                      if (t == null)
951                          break;
952                      else if (t == task) {
953 <                        if (U.compareAndSwapObject(wa, offset, t, null)) {
953 >                        if (QA.compareAndSet(wa, index, t, null)) {
954                              top = ns;   // safely shift down
955                              for (int j = i; j != ns; ++j) {
956                                  ForkJoinTask<?> f;
957                                  int pindex = (j + 1) & m;
958 <                                long pOffset = (pindex << ASHIFT) + ABASE;
959 <                                f = (ForkJoinTask<?>)U.getObject(wa, pOffset);
972 <                                U.putObjectVolatile(wa, pOffset, null);
973 <
958 >                                f = (ForkJoinTask<?>)QA.get(wa, pindex);
959 >                                QA.setVolatile(wa, pindex, null);
960                                  int jindex = j & m;
961 <                                long jOffset = (jindex << ASHIFT) + ABASE;
976 <                                U.putObjectRelease(wa, jOffset, f);
961 >                                QA.setRelease(wa, jindex, f);
962                              }
963 <                            U.storeFence();
963 >                            VarHandle.releaseFence();
964                              t.doExec();
965                          }
966                          break;
# Line 1000 | Line 985 | public class ForkJoinPool extends Abstra
985                      int b = base, s = top, al; ForkJoinTask<?>[] a;
986                      if ((a = array) != null && b != s && (al = a.length) > 0) {
987                          int index = (al - 1) & (s - 1);
1003                        long offset = ((long)index << ASHIFT) + ABASE;
988                          ForkJoinTask<?> o = (ForkJoinTask<?>)
989 <                            U.getObject(a, offset);
989 >                            QA.get(a, index);
990                          if (o instanceof CountedCompleter) {
991                              CountedCompleter<?> t = (CountedCompleter<?>)o;
992                              for (CountedCompleter<?> f = t;;) {
# Line 1011 | Line 995 | public class ForkJoinPool extends Abstra
995                                          break;
996                                  }
997                                  else {
998 <                                    if (U.compareAndSwapObject(a, offset,
1015 <                                                               t, null)) {
998 >                                    if (QA.compareAndSet(a, index, t, null)) {
999                                          top = s - 1;
1000 <                                        U.storeFence();
1000 >                                        VarHandle.releaseFence();
1001                                          t.doExec();
1002                                          help = true;
1003                                      }
# Line 1037 | Line 1020 | public class ForkJoinPool extends Abstra
1020           * Tries to lock shared queue by CASing phase field.
1021           */
1022          final boolean tryLockSharedQueue() {
1023 <            return U.compareAndSwapInt(this, PHASE, 0, QLOCK);
1023 >            return PHASE.compareAndSet(this, 0, QLOCK);
1024          }
1025  
1026          /**
# Line 1048 | Line 1031 | public class ForkJoinPool extends Abstra
1031              int s = top - 1, al; ForkJoinTask<?>[] a;
1032              if ((a = array) != null && (al = a.length) > 0) {
1033                  int index = (al - 1) & s;
1034 <                long offset = ((long)index << ASHIFT) + ABASE;
1052 <                ForkJoinTask<?> t = (ForkJoinTask<?>) U.getObject(a, offset);
1034 >                ForkJoinTask<?> t = (ForkJoinTask<?>) QA.get(a, index);
1035                  if (t == task &&
1036 <                    U.compareAndSwapInt(this, PHASE, 0, QLOCK)) {
1036 >                    PHASE.compareAndSet(this, 0, QLOCK)) {
1037                      if (top == s + 1 && array == a &&
1038 <                        U.compareAndSwapObject(a, offset, task, null)) {
1038 >                        QA.compareAndSet(a, index, task, null)) {
1039                          popped = true;
1040                          top = s;
1041                      }
1042 <                    U.putIntRelease(this, PHASE, 0);
1042 >                    PHASE.setRelease(this, 0);
1043                  }
1044              }
1045              return popped;
# Line 1074 | Line 1056 | public class ForkJoinPool extends Abstra
1056                      int b = base, s = top, al; ForkJoinTask<?>[] a;
1057                      if ((a = array) != null && b != s && (al = a.length) > 0) {
1058                          int index = (al - 1) & (s - 1);
1077                        long offset = ((long)index << ASHIFT) + ABASE;
1059                          ForkJoinTask<?> o = (ForkJoinTask<?>)
1060 <                            U.getObject(a, offset);
1060 >                            QA.get(a, index);
1061                          if (o instanceof CountedCompleter) {
1062                              CountedCompleter<?> t = (CountedCompleter<?>)o;
1063                              for (CountedCompleter<?> f = t;;) {
# Line 1085 | Line 1066 | public class ForkJoinPool extends Abstra
1066                                          break;
1067                                  }
1068                                  else {
1069 <                                    if (U.compareAndSwapInt(this, PHASE,
1089 <                                                            0, QLOCK)) {
1069 >                                    if (PHASE.compareAndSet(this, 0, QLOCK)) {
1070                                          if (top == s && array == a &&
1071 <                                            U.compareAndSwapObject(a, offset,
1092 <                                                                   t, null)) {
1071 >                                            QA.compareAndSet(a, index, t, null)) {
1072                                              help = true;
1073                                              top = s - 1;
1074                                          }
1075 <                                        U.putIntRelease(this, PHASE, 0);
1075 >                                        PHASE.setRelease(this, 0);
1076                                          if (help)
1077                                              t.doExec();
1078                                      }
# Line 1121 | Line 1100 | public class ForkJoinPool extends Abstra
1100                      s != Thread.State.TIMED_WAITING);
1101          }
1102  
1103 <        // Unsafe mechanics. Note that some are (and must be) the same as in FJP
1104 <        private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
1126 <        private static final long PHASE;
1127 <        private static final int ABASE;
1128 <        private static final int ASHIFT;
1103 >        // VarHandle mechanics.
1104 >        private static final VarHandle PHASE;
1105          static {
1106              try {
1107 <                PHASE = U.objectFieldOffset
1108 <                    (WorkQueue.class.getDeclaredField("phase"));
1133 <                ABASE = U.arrayBaseOffset(ForkJoinTask[].class);
1134 <                int scale = U.arrayIndexScale(ForkJoinTask[].class);
1135 <                if ((scale & (scale - 1)) != 0)
1136 <                    throw new Error("array index scale not a power of two");
1137 <                ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
1107 >                MethodHandles.Lookup l = MethodHandles.lookup();
1108 >                PHASE = l.findVarHandle(WorkQueue.class, "phase", int.class);
1109              } catch (ReflectiveOperationException e) {
1110                  throw new Error(e);
1111              }
# Line 1314 | Line 1285 | public class ForkJoinPool extends Abstra
1285          do {
1286              long nc = ((RC_MASK & (c + RC_UNIT)) |
1287                         (TC_MASK & (c + TC_UNIT)));
1288 <            if (ctl == c && U.compareAndSwapLong(this, CTL, c, nc)) {
1288 >            if (ctl == c && CTL.compareAndSet(this, c, nc)) {
1289                  createWorker();
1290                  break;
1291              }
# Line 1413 | Line 1384 | public class ForkJoinPool extends Abstra
1384          }
1385          if (phase != QUIET) {                         // else pre-adjusted
1386              long c;                                   // decrement counts
1387 <            do {} while (!U.compareAndSwapLong
1388 <                         (this, CTL, c = ctl, ((RC_MASK & (c - RC_UNIT)) |
1389 <                                               (TC_MASK & (c - TC_UNIT)) |
1390 <                                               (SP_MASK & c))));
1387 >            do {} while (!CTL.compareAndSet
1388 >                         (this, c = ctl, ((RC_MASK & (c - RC_UNIT)) |
1389 >                                          (TC_MASK & (c - TC_UNIT)) |
1390 >                                          (SP_MASK & c))));
1391          }
1392          if (w != null)
1393              w.cancelAll();                            // cancel remaining tasks
# Line 1455 | Line 1426 | public class ForkJoinPool extends Abstra
1426                  int vp = v.phase;
1427                  long nc = (v.stackPred & SP_MASK) | (UC_MASK & (c + RC_UNIT));
1428                  Thread vt = v.owner;
1429 <                if (sp == vp && U.compareAndSwapLong(this, CTL, c, nc)) {
1429 >                if (sp == vp && CTL.compareAndSet(this, c, nc)) {
1430                      v.phase = np;
1431                      if (v.source < 0)
1432                          LockSupport.unpark(vt);
# Line 1496 | Line 1467 | public class ForkJoinPool extends Abstra
1467                      int vp = v.phase;
1468                      Thread vt = v.owner;
1469                      long nc = ((long)v.stackPred & SP_MASK) | uc;
1470 <                    if (vp == sp && U.compareAndSwapLong(this, CTL, c, nc)) {
1470 >                    if (vp == sp && CTL.compareAndSet(this, c, nc)) {
1471                          v.phase = np;
1472                          if (v.source < 0)
1473                              LockSupport.unpark(vt);
# Line 1508 | Line 1479 | public class ForkJoinPool extends Abstra
1479              else if ((int)(c >> RC_SHIFT) -      // reduce parallelism
1480                       (short)(bounds & SMASK) > 0) {
1481                  long nc = ((RC_MASK & (c - RC_UNIT)) | (~RC_MASK & c));
1482 <                return U.compareAndSwapLong(this, CTL, c, nc) ? 1 : 0;
1482 >                return CTL.compareAndSet(this, c, nc) ? 1 : 0;
1483              }
1484              else {                               // validate
1485                  int md = mode, pc = md & SMASK, tc = pc + t, bc = 0;
# Line 1547 | Line 1518 | public class ForkJoinPool extends Abstra
1518          }
1519  
1520          long nc = ((c + TC_UNIT) & TC_MASK) | (c & ~TC_MASK); // expand pool
1521 <        return U.compareAndSwapLong(this, CTL, c, nc) && createWorker() ? 1 : 0;
1521 >        return CTL.compareAndSet(this, c, nc) && createWorker() ? 1 : 0;
1522      }
1523  
1524      /**
# Line 1570 | Line 1541 | public class ForkJoinPool extends Abstra
1541                      (a = q.array) != null && (al = a.length) > 0) {
1542                      int qid = q.id;                     // (never zero)
1543                      int index = (al - 1) & b;
1573                    long offset = ((long)index << ASHIFT) + ABASE;
1544                      ForkJoinTask<?> t = (ForkJoinTask<?>)
1545 <                        U.getObjectVolatile(a, offset);
1545 >                        QA.getVolatile(a, index);
1546                      if (t != null && b++ == q.base &&
1547 <                        U.compareAndSwapObject(a, offset, t, null)) {
1547 >                        QA.compareAndSet(a, index, t, null)) {
1548                          if ((q.base = b) - q.top < 0 && qid != lastSignalId)
1549                              signalWork();               // propagate signal
1550                          w.source = lastSignalId = qid;
# Line 1609 | Line 1579 | public class ForkJoinPool extends Abstra
1579                      do {
1580                          w.stackPred = (int)(c = ctl);
1581                          nc = ((c - RC_UNIT) & UC_MASK) | (SP_MASK & np);
1582 <                    } while (!U.compareAndSwapLong(this, CTL, c, nc));
1582 >                    } while (!CTL.compareAndSet(this, c, nc));
1583                  }
1584                  else {                                  // already queued
1585                      int pred = w.stackPred;
# Line 1636 | Line 1606 | public class ForkJoinPool extends Abstra
1606                                  d - System.currentTimeMillis() <= TIMEOUT_SLOP) {
1607                                  long nc = ((UC_MASK & (c - TC_UNIT)) |
1608                                             (SP_MASK & pred));
1609 <                                if (U.compareAndSwapLong(this, CTL, c, nc)) {
1609 >                                if (CTL.compareAndSet(this, c, nc)) {
1610                                      w.phase = QUIET;
1611                                      return;             // drop on timeout
1612                                  }
# Line 1682 | Line 1652 | public class ForkJoinPool extends Abstra
1652                              (a = q.array) != null && (al = a.length) > 0) {
1653                              int qid = q.id;
1654                              int index = (al - 1) & b;
1685                            long offset = ((long)index << ASHIFT) + ABASE;
1655                              ForkJoinTask<?> t = (ForkJoinTask<?>)
1656 <                                U.getObjectVolatile(a, offset);
1656 >                                QA.getVolatile(a, index);
1657                              if (t != null && b++ == q.base && id == q.source &&
1658 <                                U.compareAndSwapObject(a, offset, t, null)) {
1658 >                                QA.compareAndSet(a, index, t, null)) {
1659                                  q.base = b;
1660                                  w.source = qid;
1661                                  t.doExec();
# Line 1709 | Line 1678 | public class ForkJoinPool extends Abstra
1678                          ms = 1L;                       // avoid 0 for timed wait
1679                      if ((block = tryCompensate(w)) != 0) {
1680                          task.internalWait(ms);
1681 <                        U.getAndAddLong(this, CTL, (block > 0) ? RC_UNIT : 0L);
1681 >                        CTL.getAndAdd(this, (block > 0) ? RC_UNIT : 0L);
1682                      }
1683                      s = task.status;
1684                  }
# Line 1744 | Line 1713 | public class ForkJoinPool extends Abstra
1713                              int qid = q.id;
1714                              if (released == 0) {    // increment
1715                                  released = 1;
1716 <                                U.getAndAddLong(this, CTL, RC_UNIT);
1716 >                                CTL.getAndAdd(this, RC_UNIT);
1717                              }
1718                              int index = (al - 1) & b;
1750                            long offset = ((long)index << ASHIFT) + ABASE;
1719                              ForkJoinTask<?> t = (ForkJoinTask<?>)
1720 <                                U.getObjectVolatile(a, offset);
1720 >                                QA.getVolatile(a, index);
1721                              if (t != null && b++ == q.base &&
1722 <                                U.compareAndSwapObject(a, offset, t, null)) {
1722 >                                QA.compareAndSet(a, index, t, null)) {
1723                                  q.base = b;
1724                                  w.source = source = q.id;
1725                                  t.doExec();
# Line 1767 | Line 1735 | public class ForkJoinPool extends Abstra
1735              }
1736              if (quiet) {
1737                  if (released == 0)
1738 <                    U.getAndAddLong(this, CTL, RC_UNIT);
1738 >                    CTL.getAndAdd(this, RC_UNIT);
1739                  w.source = prevSrc;
1740                  break;
1741              }
# Line 1776 | Line 1744 | public class ForkJoinPool extends Abstra
1744                      w.source = source = QUIET;
1745                  if (released == 1) {                 // decrement
1746                      released = 0;
1747 <                    U.getAndAddLong(this, CTL, RC_MASK & -RC_UNIT);
1747 >                    CTL.getAndAdd(this, RC_MASK & -RC_UNIT);
1748                  }
1749              }
1750          }
# Line 1811 | Line 1779 | public class ForkJoinPool extends Abstra
1779                      if (b - q.top < 0 &&
1780                          (a = q.array) != null && (al = a.length) > 0) {
1781                          int index = (al - 1) & b;
1814                        long offset = ((long)index << ASHIFT) + ABASE;
1782                          ForkJoinTask<?> t = (ForkJoinTask<?>)
1783 <                            U.getObjectVolatile(a, offset);
1783 >                            QA.getVolatile(a, index);
1784                          if (t != null && b++ == q.base &&
1785 <                            U.compareAndSwapObject(a, offset, t, null)) {
1785 >                            QA.compareAndSet(a, index, t, null)) {
1786                              q.base = b;
1787                              return t;
1788                          }
# Line 2066 | Line 2033 | public class ForkJoinPool extends Abstra
2033              if (!enable || this == common)        // cannot shutdown
2034                  return false;
2035              else
2036 <                U.compareAndSwapInt(this, MODE, md, md | SHUTDOWN);
2036 >                MODE.compareAndSet(this, md, md | SHUTDOWN);
2037          }
2038  
2039          while (((md = mode) & STOP) == 0) {       // try to initiate termination
# Line 2099 | Line 2066 | public class ForkJoinPool extends Abstra
2066                  }
2067              }
2068              if ((md & STOP) == 0)
2069 <                U.compareAndSwapInt(this, MODE, md, md | STOP);
2069 >                MODE.compareAndSet(this, md, md | STOP);
2070          }
2071  
2072          while (((md = mode) & TERMINATED) == 0) { // help terminate others
# Line 2129 | Line 2096 | public class ForkJoinPool extends Abstra
2096                  break;
2097              else if ((md & SMASK) + (short)(ctl >>> TC_SHIFT) > 0)
2098                  break;
2099 <            else if (U.compareAndSwapInt(this, MODE, md, md | TERMINATED)) {
2099 >            else if (MODE.compareAndSet(this, md, md | TERMINATED)) {
2100                  synchronized (this) {
2101                      notifyAll();                  // for awaitTermination
2102                  }
# Line 3118 | Line 3085 | public class ForkJoinPool extends Abstra
3085                          do {} while (!blocker.isReleasable() &&
3086                                       !blocker.block());
3087                      } finally {
3088 <                        U.getAndAddLong(p, CTL, (block > 0) ? RC_UNIT : 0L);
3088 >                        CTL.getAndAdd(p, (block > 0) ? RC_UNIT : 0L);
3089                      }
3090                      break;
3091                  }
# Line 3154 | Line 3121 | public class ForkJoinPool extends Abstra
3121                      if ((a = w.array) != null && (d = b - s) < 0 &&
3122                          (al = a.length) > 0) {
3123                          int index = (al - 1) & b;
3157                        long offset = ((long)index << ASHIFT) + ABASE;
3124                          ForkJoinTask<?> t = (ForkJoinTask<?>)
3125 <                            U.getObjectVolatile(a, offset);
3125 >                            QA.getVolatile(a, index);
3126                          if (blocker.isReleasable())
3127                              break;
3128                          else if (b++ == w.base) {
# Line 3167 | Line 3133 | public class ForkJoinPool extends Abstra
3133                              else if (!(t instanceof CompletableFuture.
3134                                    AsynchronousCompletionTask))
3135                                  break;
3136 <                            else if (U.compareAndSwapObject(a, offset,
3171 <                                                            t, null)) {
3136 >                            else if (QA.compareAndSet(a, index, t, null)) {
3137                                  w.base = b;
3138                                  t.doExec();
3139                              }
# Line 3193 | Line 3158 | public class ForkJoinPool extends Abstra
3158          return new ForkJoinTask.AdaptedCallable<T>(callable);
3159      }
3160  
3161 <    // Unsafe mechanics
3162 <    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
3163 <    private static final long CTL;
3164 <    private static final long MODE;
3200 <    private static final int ABASE;
3201 <    private static final int ASHIFT;
3161 >    // VarHandle mechanics
3162 >    private static final VarHandle CTL;
3163 >    private static final VarHandle MODE;
3164 >    private static final VarHandle QA;
3165  
3166      static {
3167          try {
3168 <            CTL = U.objectFieldOffset
3169 <                (ForkJoinPool.class.getDeclaredField("ctl"));
3170 <            MODE = U.objectFieldOffset
3171 <                (ForkJoinPool.class.getDeclaredField("mode"));
3209 <            ABASE = U.arrayBaseOffset(ForkJoinTask[].class);
3210 <            int scale = U.arrayIndexScale(ForkJoinTask[].class);
3211 <            if ((scale & (scale - 1)) != 0)
3212 <                throw new Error("array index scale not a power of two");
3213 <            ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
3168 >            MethodHandles.Lookup l = MethodHandles.lookup();
3169 >            CTL = l.findVarHandle(ForkJoinPool.class, "ctl", long.class);
3170 >            MODE = l.findVarHandle(ForkJoinPool.class, "mode", int.class);
3171 >            QA = MethodHandles.arrayElementVarHandle(ForkJoinTask[].class);
3172          } catch (ReflectiveOperationException e) {
3173              throw new Error(e);
3174          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines