< prev index next >

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

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

*** 85,103 **** * Adds the given value. * * @param x the value to add */ public void add(double x) { ! Cell[] as; long b, v; int m; Cell a; ! if ((as = cells) != null || !casBase(b = base, Double.doubleToRawLongBits (Double.longBitsToDouble(b) + x))) { boolean uncontended = true; ! if (as == null || (m = as.length - 1) < 0 || ! (a = as[getProbe() & m]) == null || ! !(uncontended = a.cas(v = a.value, Double.doubleToRawLongBits (Double.longBitsToDouble(v) + x)))) doubleAccumulate(x, null, uncontended); } } --- 85,103 ---- * Adds the given value. * * @param x the value to add */ public void add(double x) { ! Cell[] cs; long b, v; int m; Cell c; ! if ((cs = cells) != null || !casBase(b = base, Double.doubleToRawLongBits (Double.longBitsToDouble(b) + x))) { boolean uncontended = true; ! if (cs == null || (m = cs.length - 1) < 0 || ! (c = cs[getProbe() & m]) == null || ! !(uncontended = c.cas(v = c.value, Double.doubleToRawLongBits (Double.longBitsToDouble(v) + x)))) doubleAccumulate(x, null, uncontended); } }
*** 113,128 **** * updates to a single variable. * * @return the sum */ public double sum() { ! Cell[] as = cells; double sum = Double.longBitsToDouble(base); ! if (as != null) { ! for (Cell a : as) ! if (a != null) ! sum += Double.longBitsToDouble(a.value); } return sum; } /** --- 113,128 ---- * updates to a single variable. * * @return the sum */ public double sum() { ! Cell[] cs = cells; double sum = Double.longBitsToDouble(base); ! if (cs != null) { ! for (Cell c : cs) ! if (c != null) ! sum += Double.longBitsToDouble(c.value); } return sum; } /**
*** 131,146 **** * effective if there are no concurrent 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 = 0L; // relies on fact that double 0 must have same rep as long ! if (as != null) { ! for (Cell a : as) ! if (a != null) ! a.reset(); } } /** * Equivalent in effect to {@link #sum} followed by {@link --- 131,146 ---- * effective if there are no concurrent 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 = 0L; // relies on fact that double 0 must have same rep as long ! if (cs != null) { ! for (Cell c : cs) ! if (c != null) ! c.reset(); } } /** * Equivalent in effect to {@link #sum} followed by {@link
*** 151,170 **** * the reset. * * @return the sum */ public double sumThenReset() { ! Cell[] as = cells; ! double sum = Double.longBitsToDouble(base); ! base = 0L; ! if (as != null) { ! for (Cell a : as) { ! if (a != null) { ! long v = a.value; ! a.reset(); ! sum += Double.longBitsToDouble(v); ! } } } return sum; } --- 151,166 ---- * the reset. * * @return the sum */ public double sumThenReset() { ! Cell[] cs = cells; ! double sum = Double.longBitsToDouble(getAndSetBase(0L)); ! if (cs != null) { ! for (Cell c : cs) { ! if (c != null) ! sum += Double.longBitsToDouble(c.getAndSet(0L)); } } return sum; }
< prev index next >