< 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 >