summary |
shortlog |
log |
commit | commitdiff |
review |
tree
raw |
patch |
inline | side by side (from parent 1:
558e8c8)
This field is only ever read from other classes, hence we can
hide it behind READ_PREV(). The updater is also not accessed
from anywhere else, hence make it private.
Change-Id: I13e2e5a85ef502e7ad12f27d0309cd7a9ec6803a
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
final class FailedNode<K, V> extends MainNode<K, V> {
private final MainNode<K, V> p;
final class FailedNode<K, V> extends MainNode<K, V> {
private final MainNode<K, V> p;
- FailedNode (final MainNode<K, V> p) {
+ FailedNode(final MainNode<K, V> p) {
MainNode<K, V> GCAS_READ(final TrieMap<K, V> ct) {
MainNode<K, V> m = /* READ */mainnode;
MainNode<K, V> GCAS_READ(final TrieMap<K, V> ct) {
MainNode<K, V> m = /* READ */mainnode;
- MainNode<K, V> prevval = /* READ */m.prev;
+ MainNode<K, V> prevval = /* READ */ m.READ_PREV();
if (prevval == null) {
return m;
} else {
if (prevval == null) {
return m;
} else {
return null;
} else {
// complete the GCAS
return null;
} else {
// complete the GCAS
- MainNode<K, V> prev = /* READ */m.prev;
+ MainNode<K, V> prev = /* READ */ m.READ_PREV();
INode<K, V> ctr = ct.readRoot(true);
if (prev == null) {
INode<K, V> ctr = ct.readRoot(true);
if (prev == null) {
if (prev instanceof FailedNode) {
// try to commit to previous value
FailedNode<K, V> fn = (FailedNode<K, V>) prev;
if (prev instanceof FailedNode) {
// try to commit to previous value
FailedNode<K, V> fn = (FailedNode<K, V>) prev;
- if (CAS(m, fn.prev)) {
- return fn.prev;
+ if (CAS(m, fn.READ_PREV())) {
+ return fn.READ_PREV();
} else {
// Tailrec
// return GCAS_Complete (/* READ */mainnode, ct);
} else {
// Tailrec
// return GCAS_Complete (/* READ */mainnode, ct);
n.WRITE_PREV (old);
if (CAS (old, n)) {
GCAS_Complete (n, ct);
n.WRITE_PREV (old);
if (CAS (old, n)) {
GCAS_Complete (n, ct);
- return /* READ */n.prev == null;
+ return /* READ */ n.READ_PREV() == null;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
abstract class MainNode<K, V> extends BasicNode {
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
abstract class MainNode<K, V> extends BasicNode {
+ @SuppressWarnings("rawtypes")
+ private static final AtomicReferenceFieldUpdater<MainNode, MainNode> PREV_UPDATER =
+ AtomicReferenceFieldUpdater.newUpdater(MainNode.class, MainNode.class, "prev");
- public static final AtomicReferenceFieldUpdater<MainNode, MainNode> updater = AtomicReferenceFieldUpdater.newUpdater (MainNode.class, MainNode.class, "prev");
-
- public volatile MainNode<K, V> prev = null;
+ private volatile MainNode<K, V> prev = null;
abstract int cachedSize(TrieMap<K, V> ct);
abstract int cachedSize(TrieMap<K, V> ct);
- public boolean CAS_PREV (final MainNode<K, V> oldval, final MainNode<K, V> nval) {
- return updater.compareAndSet (this, oldval, nval);
+ final boolean CAS_PREV(final MainNode<K, V> oldval, final MainNode<K, V> nval) {
+ return PREV_UPDATER.compareAndSet(this, oldval, nval);
- public void WRITE_PREV (final MainNode<K, V> nval) {
- updater.set (this, nval);
+ final void WRITE_PREV(final MainNode<K, V> nval) {
+ prev = nval;
- // do we need this? unclear in the javadocs...
- // apparently not - volatile reads are supposed to be safe
- // regardless of whether there are concurrent ARFU updates
- public MainNode<K, V> READ_PREV () {
- return updater.get (this);
+ final MainNode<K, V> READ_PREV() {
+ return prev;