< prev index next >

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

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

*** 103,126 **** * Updates with the given value. * * @param x the value */ public void accumulate(double x) { ! Cell[] as; long b, v, r; int m; Cell a; ! if ((as = cells) != null || ((r = doubleToRawLongBits (function.applyAsDouble(longBitsToDouble(b = base), x))) != b && !casBase(b, r))) { boolean uncontended = true; ! if (as == null ! || (m = as.length - 1) < 0 ! || (a = as[getProbe() & m]) == null || !(uncontended = ((r = doubleToRawLongBits (function.applyAsDouble ! (longBitsToDouble(v = a.value), x))) == v) ! || a.cas(v, r))) doubleAccumulate(x, function, uncontended); } } /** --- 103,126 ---- * Updates with the given value. * * @param x the value */ public void accumulate(double x) { ! Cell[] cs; long b, v, r; int m; Cell c; ! if ((cs = cells) != null || ((r = doubleToRawLongBits (function.applyAsDouble(longBitsToDouble(b = base), x))) != b && !casBase(b, r))) { boolean uncontended = true; ! if (cs == null ! || (m = cs.length - 1) < 0 ! || (c = cs[getProbe() & m]) == null || !(uncontended = ((r = doubleToRawLongBits (function.applyAsDouble ! (longBitsToDouble(v = c.value), x))) == v) ! || c.cas(v, r))) doubleAccumulate(x, function, uncontended); } } /**
*** 131,147 **** * incorporated. * * @return the current value */ public double get() { ! Cell[] as = cells; double result = longBitsToDouble(base); ! if (as != null) { ! for (Cell a : as) ! if (a != null) result = function.applyAsDouble ! (result, longBitsToDouble(a.value)); } return result; } /** --- 131,147 ---- * incorporated. * * @return the current value */ public double get() { ! Cell[] cs = cells; double result = longBitsToDouble(base); ! if (cs != null) { ! for (Cell c : cs) ! if (c != null) result = function.applyAsDouble ! (result, longBitsToDouble(c.value)); } return result; } /**
*** 151,166 **** * updates. Because this method is intrinsically racy, it should * only be used when it is known that no threads are concurrently * updating. */ public void reset() { ! Cell[] as = cells; base = identity; ! if (as != null) { ! for (Cell a : as) ! if (a != null) ! a.reset(identity); } } /** * Equivalent in effect to {@link #get} followed by {@link --- 151,166 ---- * updates. Because this method is intrinsically racy, it should * only be used when it is known that no threads are concurrently * updating. */ public void reset() { ! Cell[] cs = cells; base = identity; ! if (cs != null) { ! for (Cell c : cs) ! if (c != null) ! c.reset(identity); } } /** * Equivalent in effect to {@link #get} followed by {@link
*** 171,188 **** * the reset. * * @return the value before reset */ public double getThenReset() { ! Cell[] as = cells; ! double result = longBitsToDouble(base); ! base = identity; ! if (as != null) { ! for (Cell a : as) { ! if (a != null) { ! double v = longBitsToDouble(a.value); ! a.reset(identity); result = function.applyAsDouble(result, v); } } } return result; --- 171,186 ---- * the reset. * * @return the value before reset */ public double getThenReset() { ! Cell[] cs = cells; ! double result = longBitsToDouble(getAndSetBase(identity)); ! if (cs != null) { ! for (Cell c : cs) { ! if (c != null) { ! double v = longBitsToDouble(c.getAndSet(identity)); result = function.applyAsDouble(result, v); } } } return result;
< prev index next >