package water.util;
import sun.misc.Unsafe;
import water.nbhm.UtilUnsafe;
public abstract class AtomicUtils {
// Atomically-updated float array
public abstract static class FloatArray {
private static final Unsafe _unsafe = UtilUnsafe.getUnsafe();
private static final int _Fbase = _unsafe.arrayBaseOffset(float[].class);
private static final int _Fscale = _unsafe.arrayIndexScale(float[].class);
private static long rawIndex(final float[] ary, final int idx) {
assert idx >= 0 && idx < ary.length;
return _Fbase + idx * _Fscale;
}
static public void setMin( float fs[], int i, float min ) {
float old = fs[i];
while( min < old && !_unsafe.compareAndSwapInt(fs,rawIndex(fs,i), Float.floatToRawIntBits(old), Float.floatToRawIntBits(min) ) )
old = fs[i];
}
static public void setMax( float fs[], int i, float max ) {
float old = fs[i];
while( max > old && !_unsafe.compareAndSwapInt(fs,rawIndex(fs,i), Float.floatToRawIntBits(old), Float.floatToRawIntBits(max) ) )
old = fs[i];
}
static public void add( float ds[], int i, float y ) {
long adr = rawIndex(ds,i);
float old = ds[i];
while( !_unsafe.compareAndSwapInt(ds,adr, Float.floatToRawIntBits(old), Float.floatToRawIntBits(old+y) ) )
old = ds[i];
}
static public String toString( float fs[] ) {
SB sb = new SB();
sb.p('[');
for( float f : fs )
sb.p(f==Float.MAX_VALUE ? "max": (f==-Float.MAX_VALUE ? "min": Float.toString(f))).p(',');
return sb.p(']').toString();
}
}
// Atomically-updated double array
public static class DoubleArray {
private static final Unsafe _unsafe = UtilUnsafe.getUnsafe();
private static final int _Dbase = _unsafe.arrayBaseOffset(double[].class);
private static final int _Dscale = _unsafe.arrayIndexScale(double[].class);
private static long rawIndex(final double[] ary, final int idx) {
assert idx >= 0 && idx < ary.length;
return _Dbase + idx * _Dscale;
}
static public boolean CAS( double[] ds, int i, double old, double newd ) {
return _unsafe.compareAndSwapLong(ds,rawIndex(ds,i), Double.doubleToRawLongBits(old), Double.doubleToRawLongBits(newd) );
}
static public void add( double ds[], int i, double y ) {
double old;
while( !CAS(ds,i,old=ds[i],old+y) ) ;
}
static public void min( double ds[], int i, double min ) {
double old;
while( !CAS(ds,i,old=ds[i],Math.min(old,min)) ) ;
}
static public void max( double ds[], int i, double max ) {
double old;
while( !CAS(ds,i,old=ds[i],Math.max(old,max)) ) ;
}
}
// Atomically-updated long array. Instead of using the similar JDK pieces,
// allows the bare array to be exposed for fast readers.
public static class LongArray {
private static final Unsafe _unsafe = UtilUnsafe.getUnsafe();
private static final int _Lbase = _unsafe.arrayBaseOffset(long[].class);
private static final int _Lscale = _unsafe.arrayIndexScale(long[].class);
private static long rawIndex(final long[] ary, final int idx) {
assert idx >= 0 && idx < ary.length;
return _Lbase + idx * _Lscale;
}
static public void incr( long ls[], int i ) { add(ls,i,1); }
static public void add( long ls[], int i, long x ) {
long adr = rawIndex(ls,i);
long old = ls[i];
while( !_unsafe.compareAndSwapLong(ls,adr, old, old+x) )
old = ls[i];
}
}
// Atomically-updated int array. Instead of using the similar JDK pieces,
// allows the bare array to be exposed for fast readers.
public static class IntArray {
private static final Unsafe _unsafe = UtilUnsafe.getUnsafe();
private static final int _Ibase = _unsafe.arrayBaseOffset(int[].class);
private static final int _Iscale = _unsafe.arrayIndexScale(int[].class);
private static long rawIndex(final int[] ary, final int idx) {
assert idx >= 0 && idx < ary.length;
return _Ibase + idx * _Iscale;
}
static public void incr( int is[], int i ) { add(is,i,1); }
static public void add( int is[], int i, int x ) {
long adr = rawIndex(is,i);
int old = is[i];
while( !_unsafe.compareAndSwapInt(is,adr, old, old+x) )
old = is[i];
}
}
}