< prev index next >

src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java

Print this page
8192943: Optimize atomic accumulators using VarHandle getAndSet
Reviewed-by: martin, psandoz, chegar

*** 131,140 **** --- 131,143 ---- VALUE.setVolatile(this, 0L); } final void reset(long identity) { VALUE.setVolatile(this, identity); } + final long getAndSet(long val) { + return (long)VALUE.getAndSet(this, val); + } // VarHandle mechanics private static final VarHandle VALUE; static { try {
*** 176,185 **** --- 179,192 ---- */ final boolean casBase(long cmp, long val) { return BASE.compareAndSet(this, cmp, val); } + final long getAndSetBase(long val) { + return (long)BASE.getAndSet(this, val); + } + /** * CASes the cellsBusy field from 0 to 1 to acquire lock. */ final boolean casCellsBusy() { return CELLSBUSY.compareAndSet(this, 0, 1);
*** 226,238 **** h = getProbe(); wasUncontended = true; } boolean collide = false; // True if last slot nonempty done: for (;;) { ! Cell[] as; Cell a; int n; long v; ! if ((as = cells) != null && (n = as.length) > 0) { ! if ((a = as[(n - 1) & h]) == null) { if (cellsBusy == 0) { // Try to attach new Cell Cell r = new Cell(x); // Optimistically create if (cellsBusy == 0 && casCellsBusy()) { try { // Recheck under lock Cell[] rs; int m, j; --- 233,245 ---- h = getProbe(); wasUncontended = true; } boolean collide = false; // True if last slot nonempty done: for (;;) { ! Cell[] cs; Cell c; int n; long v; ! if ((cs = cells) != null && (n = cs.length) > 0) { ! if ((c = cs[(n - 1) & h]) == null) { if (cellsBusy == 0) { // Try to attach new Cell Cell r = new Cell(x); // Optimistically create if (cellsBusy == 0 && casCellsBusy()) { try { // Recheck under lock Cell[] rs; int m, j;
*** 250,281 **** } collide = false; } else if (!wasUncontended) // CAS already known to fail wasUncontended = true; // Continue after rehash ! else if (a.cas(v = a.value, (fn == null) ? v + x : fn.applyAsLong(v, x))) break; ! else if (n >= NCPU || cells != as) collide = false; // At max size or stale else if (!collide) collide = true; else if (cellsBusy == 0 && casCellsBusy()) { try { ! if (cells == as) // Expand table unless stale ! cells = Arrays.copyOf(as, n << 1); } finally { cellsBusy = 0; } collide = false; continue; // Retry with expanded table } h = advanceProbe(h); } ! else if (cellsBusy == 0 && cells == as && casCellsBusy()) { try { // Initialize table ! if (cells == as) { Cell[] rs = new Cell[2]; rs[h & 1] = new Cell(x); cells = rs; break done; } --- 257,288 ---- } collide = false; } else if (!wasUncontended) // CAS already known to fail wasUncontended = true; // Continue after rehash ! else if (c.cas(v = c.value, (fn == null) ? v + x : fn.applyAsLong(v, x))) break; ! else if (n >= NCPU || cells != cs) collide = false; // At max size or stale else if (!collide) collide = true; else if (cellsBusy == 0 && casCellsBusy()) { try { ! if (cells == cs) // Expand table unless stale ! cells = Arrays.copyOf(cs, n << 1); } finally { cellsBusy = 0; } collide = false; continue; // Retry with expanded table } h = advanceProbe(h); } ! else if (cellsBusy == 0 && cells == cs && casCellsBusy()) { try { // Initialize table ! if (cells == cs) { Cell[] rs = new Cell[2]; rs[h & 1] = new Cell(x); cells = rs; break done; }
*** 310,322 **** h = getProbe(); wasUncontended = true; } boolean collide = false; // True if last slot nonempty done: for (;;) { ! Cell[] as; Cell a; int n; long v; ! if ((as = cells) != null && (n = as.length) > 0) { ! if ((a = as[(n - 1) & h]) == null) { if (cellsBusy == 0) { // Try to attach new Cell Cell r = new Cell(Double.doubleToRawLongBits(x)); if (cellsBusy == 0 && casCellsBusy()) { try { // Recheck under lock Cell[] rs; int m, j; --- 317,329 ---- h = getProbe(); wasUncontended = true; } boolean collide = false; // True if last slot nonempty done: for (;;) { ! Cell[] cs; Cell c; int n; long v; ! if ((cs = cells) != null && (n = cs.length) > 0) { ! if ((c = cs[(n - 1) & h]) == null) { if (cellsBusy == 0) { // Try to attach new Cell Cell r = new Cell(Double.doubleToRawLongBits(x)); if (cellsBusy == 0 && casCellsBusy()) { try { // Recheck under lock Cell[] rs; int m, j;
*** 334,364 **** } collide = false; } else if (!wasUncontended) // CAS already known to fail wasUncontended = true; // Continue after rehash ! else if (a.cas(v = a.value, apply(fn, v, x))) break; ! else if (n >= NCPU || cells != as) collide = false; // At max size or stale else if (!collide) collide = true; else if (cellsBusy == 0 && casCellsBusy()) { try { ! if (cells == as) // Expand table unless stale ! cells = Arrays.copyOf(as, n << 1); } finally { cellsBusy = 0; } collide = false; continue; // Retry with expanded table } h = advanceProbe(h); } ! else if (cellsBusy == 0 && cells == as && casCellsBusy()) { try { // Initialize table ! if (cells == as) { Cell[] rs = new Cell[2]; rs[h & 1] = new Cell(Double.doubleToRawLongBits(x)); cells = rs; break done; } --- 341,371 ---- } collide = false; } else if (!wasUncontended) // CAS already known to fail wasUncontended = true; // Continue after rehash ! else if (c.cas(v = c.value, apply(fn, v, x))) break; ! else if (n >= NCPU || cells != cs) collide = false; // At max size or stale else if (!collide) collide = true; else if (cellsBusy == 0 && casCellsBusy()) { try { ! if (cells == cs) // Expand table unless stale ! cells = Arrays.copyOf(cs, n << 1); } finally { cellsBusy = 0; } collide = false; continue; // Retry with expanded table } h = advanceProbe(h); } ! else if (cellsBusy == 0 && cells == cs && casCellsBusy()) { try { // Initialize table ! if (cells == cs) { Cell[] rs = new Cell[2]; rs[h & 1] = new Cell(Double.doubleToRawLongBits(x)); cells = rs; break done; }
< prev index next >