< prev index next >
src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java
Print this page
8192943: Optimize atomic accumulators using VarHandle getAndSet
Reviewed-by: martin, psandoz, chegar
@@ -131,10 +131,13 @@
VALUE.setVolatile(this, 0L);
}
final void reset(long identity) {
VALUE.setVolatile(this, identity);
}
+ final long getAndSet(long val) {
+ return (long)VALUE.getAndSet(this, val);
+ }
// VarHandle mechanics
private static final VarHandle VALUE;
static {
try {
@@ -176,10 +179,14 @@
*/
final boolean casBase(long cmp, long val) {
return BASE.compareAndSet(this, cmp, val);
}
+ final long getAndSetBase(long val) {
+ return (long)BASE.getAndSet(this, val);
+ }
+
/**
* CASes the cellsBusy field from 0 to 1 to acquire lock.
*/
final boolean casCellsBusy() {
return CELLSBUSY.compareAndSet(this, 0, 1);
@@ -226,13 +233,13 @@
h = getProbe();
wasUncontended = true;
}
boolean collide = false; // True if last slot nonempty
done: for (;;) {
- Cell[] as; Cell a; int n; long v;
- if ((as = cells) != null && (n = as.length) > 0) {
- if ((a = as[(n - 1) & h]) == null) {
+ Cell[] cs; Cell c; int n; long v;
+ if ((cs = cells) != null && (n = cs.length) > 0) {
+ if ((c = cs[(n - 1) & h]) == 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;
@@ -250,32 +257,32 @@
}
collide = false;
}
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
- else if (a.cas(v = a.value,
+ else if (c.cas(v = c.value,
(fn == null) ? v + x : fn.applyAsLong(v, x)))
break;
- else if (n >= NCPU || cells != as)
+ else if (n >= NCPU || cells != cs)
collide = false; // At max size or stale
else if (!collide)
collide = true;
else if (cellsBusy == 0 && casCellsBusy()) {
try {
- if (cells == as) // Expand table unless stale
- cells = Arrays.copyOf(as, n << 1);
+ if (cells == cs) // Expand table unless stale
+ cells = Arrays.copyOf(cs, n << 1);
} finally {
cellsBusy = 0;
}
collide = false;
continue; // Retry with expanded table
}
h = advanceProbe(h);
}
- else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
+ else if (cellsBusy == 0 && cells == cs && casCellsBusy()) {
try { // Initialize table
- if (cells == as) {
+ if (cells == cs) {
Cell[] rs = new Cell[2];
rs[h & 1] = new Cell(x);
cells = rs;
break done;
}
@@ -310,13 +317,13 @@
h = getProbe();
wasUncontended = true;
}
boolean collide = false; // True if last slot nonempty
done: for (;;) {
- Cell[] as; Cell a; int n; long v;
- if ((as = cells) != null && (n = as.length) > 0) {
- if ((a = as[(n - 1) & h]) == null) {
+ Cell[] cs; Cell c; int n; long v;
+ if ((cs = cells) != null && (n = cs.length) > 0) {
+ if ((c = cs[(n - 1) & h]) == 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;
@@ -334,31 +341,31 @@
}
collide = false;
}
else if (!wasUncontended) // CAS already known to fail
wasUncontended = true; // Continue after rehash
- else if (a.cas(v = a.value, apply(fn, v, x)))
+ else if (c.cas(v = c.value, apply(fn, v, x)))
break;
- else if (n >= NCPU || cells != as)
+ else if (n >= NCPU || cells != cs)
collide = false; // At max size or stale
else if (!collide)
collide = true;
else if (cellsBusy == 0 && casCellsBusy()) {
try {
- if (cells == as) // Expand table unless stale
- cells = Arrays.copyOf(as, n << 1);
+ if (cells == cs) // Expand table unless stale
+ cells = Arrays.copyOf(cs, n << 1);
} finally {
cellsBusy = 0;
}
collide = false;
continue; // Retry with expanded table
}
h = advanceProbe(h);
}
- else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
+ else if (cellsBusy == 0 && cells == cs && casCellsBusy()) {
try { // Initialize table
- if (cells == as) {
+ if (cells == cs) {
Cell[] rs = new Cell[2];
rs[h & 1] = new Cell(Double.doubleToRawLongBits(x));
cells = rs;
break done;
}
< prev index next >