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