< prev index next >
src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java
Print this page
8234131: Miscellaneous changes imported from jsr166 CVS 2020-12
Reviewed-by: martin
@@ -123,11 +123,11 @@
*/
@jdk.internal.vm.annotation.Contended static final class Cell {
volatile long value;
Cell(long x) { value = x; }
final boolean cas(long cmp, long val) {
- return VALUE.compareAndSet(this, cmp, val);
+ return VALUE.weakCompareAndSetRelease(this, cmp, val);
}
final void reset() {
VALUE.setVolatile(this, 0L);
}
final void reset(long identity) {
@@ -176,11 +176,11 @@
/**
* CASes the base field.
*/
final boolean casBase(long cmp, long val) {
- return BASE.compareAndSet(this, cmp, val);
+ return BASE.weakCompareAndSetRelease(this, cmp, val);
}
final long getAndSetBase(long val) {
return (long)BASE.getAndSet(this, val);
}
@@ -222,34 +222,33 @@
*
* @param x the value
* @param fn the update function, or null for add (this convention
* avoids the need for an extra field or function in LongAdder).
* @param wasUncontended false if CAS failed before call
+ * @param index thread index from getProbe
*/
final void longAccumulate(long x, LongBinaryOperator fn,
- boolean wasUncontended) {
- int h;
- if ((h = getProbe()) == 0) {
+ boolean wasUncontended, int index) {
+ if (index == 0) {
ThreadLocalRandom.current(); // force initialization
- h = getProbe();
+ index = getProbe();
wasUncontended = true;
}
- boolean collide = false; // True if last slot nonempty
- done: for (;;) {
+ for (boolean collide = false;;) { // True if last slot nonempty
Cell[] cs; Cell c; int n; long v;
if ((cs = cells) != null && (n = cs.length) > 0) {
- if ((c = cs[(n - 1) & h]) == null) {
+ if ((c = cs[(n - 1) & index]) == 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;
if ((rs = cells) != null &&
(m = rs.length) > 0 &&
- rs[j = (m - 1) & h] == null) {
+ rs[j = (m - 1) & index] == null) {
rs[j] = r;
- break done;
+ break;
}
} finally {
cellsBusy = 0;
}
continue; // Slot is now non-empty
@@ -274,28 +273,28 @@
cellsBusy = 0;
}
collide = false;
continue; // Retry with expanded table
}
- h = advanceProbe(h);
+ index = advanceProbe(index);
}
else if (cellsBusy == 0 && cells == cs && casCellsBusy()) {
try { // Initialize table
if (cells == cs) {
Cell[] rs = new Cell[2];
- rs[h & 1] = new Cell(x);
+ rs[index & 1] = new Cell(x);
cells = rs;
- break done;
+ break;
}
} finally {
cellsBusy = 0;
}
}
// Fall back on using base
else if (casBase(v = base,
(fn == null) ? v + x : fn.applyAsLong(v, x)))
- break done;
+ break;
}
}
private static long apply(DoubleBinaryOperator fn, long v, double x) {
double d = Double.longBitsToDouble(v);
@@ -308,32 +307,30 @@
* in too many places to sensibly merge with long version, given
* the low-overhead requirements of this class. So must instead be
* maintained by copy/paste/adapt.
*/
final void doubleAccumulate(double x, DoubleBinaryOperator fn,
- boolean wasUncontended) {
- int h;
- if ((h = getProbe()) == 0) {
+ boolean wasUncontended, int index) {
+ if (index == 0) {
ThreadLocalRandom.current(); // force initialization
- h = getProbe();
+ index = getProbe();
wasUncontended = true;
}
- boolean collide = false; // True if last slot nonempty
- done: for (;;) {
+ for (boolean collide = false;;) { // True if last slot nonempty
Cell[] cs; Cell c; int n; long v;
if ((cs = cells) != null && (n = cs.length) > 0) {
- if ((c = cs[(n - 1) & h]) == null) {
+ if ((c = cs[(n - 1) & index]) == 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;
if ((rs = cells) != null &&
(m = rs.length) > 0 &&
- rs[j = (m - 1) & h] == null) {
+ rs[j = (m - 1) & index] == null) {
rs[j] = r;
- break done;
+ break;
}
} finally {
cellsBusy = 0;
}
continue; // Slot is now non-empty
@@ -357,27 +354,27 @@
cellsBusy = 0;
}
collide = false;
continue; // Retry with expanded table
}
- h = advanceProbe(h);
+ index = advanceProbe(index);
}
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));
+ rs[index & 1] = new Cell(Double.doubleToRawLongBits(x));
cells = rs;
- break done;
+ break;
}
} finally {
cellsBusy = 0;
}
}
// Fall back on using base
else if (casBase(v = base, apply(fn, v, x)))
- break done;
+ break;
}
}
// VarHandle mechanics
private static final VarHandle BASE;
< prev index next >