package org.apache.cassandra.utils;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
public final class AtomicLongArrayUpdater {
private static final long offset;
private static final int shift;
static final Unsafe theUnsafe;
static {
theUnsafe = (Unsafe) AccessController.doPrivileged(
new PrivilegedAction<Object>()
{
@Override
public Object run()
{
try
{
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return f.get(null);
} catch (NoSuchFieldException e)
{
// It doesn't matter what we throw;
// it's swallowed in getBestComparer().
throw new Error();
} catch (IllegalAccessException e)
{
throw new Error();
}
}
});
Class<?> clazz = long[].class;
offset = theUnsafe.arrayBaseOffset(clazz);
shift = shift(theUnsafe.arrayIndexScale(clazz));
}
private static int shift(int scale)
{
if (Integer.bitCount(scale) != 1)
throw new IllegalStateException();
return Integer.bitCount(scale - 1);
}
public AtomicLongArrayUpdater() { }
public final boolean compareAndSet(Object trg, int i, long exp, long upd) {
return theUnsafe.compareAndSwapLong(trg, offset + (i << shift), exp, upd);
}
public final void putVolatile(Object trg, int i, long val) {
theUnsafe.putLongVolatile(trg, offset + (i << shift), val);
}
public final void putOrdered(Object trg, int i, long val) {
theUnsafe.putOrderedLong(trg, offset + (i << shift), val);
}
public final long get(Object trg, int i) {
return theUnsafe.getLong(trg, offset + (i << shift));
}
public final long getVolatile(Object trg, int i) {
return theUnsafe.getLongVolatile(trg, offset + (i << shift));
}
}