src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java

Print this page
rev 12972 : 8140606: Update library code to use internal Unsafe
Reviewed-by: duke


 116     /**
 117      * Padded variant of AtomicLong supporting only raw accesses plus CAS.
 118      *
 119      * JVM intrinsics note: It would be possible to use a release-only
 120      * form of CAS here, if it were provided.
 121      */
 122     @sun.misc.Contended static final class Cell {
 123         volatile long value;
 124         Cell(long x) { value = x; }
 125         final boolean cas(long cmp, long val) {
 126             return U.compareAndSwapLong(this, VALUE, cmp, val);
 127         }
 128         final void reset() {
 129             U.putLongVolatile(this, VALUE, 0L);
 130         }
 131         final void reset(long identity) {
 132             U.putLongVolatile(this, VALUE, identity);
 133         }
 134 
 135         // Unsafe mechanics
 136         private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
 137         private static final long VALUE;
 138         static {
 139             try {
 140                 VALUE = U.objectFieldOffset
 141                     (Cell.class.getDeclaredField("value"));
 142             } catch (ReflectiveOperationException e) {
 143                 throw new Error(e);
 144             }
 145         }
 146     }
 147 
 148     /** Number of CPUS, to place bound on table size */
 149     static final int NCPU = Runtime.getRuntime().availableProcessors();
 150 
 151     /**
 152      * Table of cells. When non-null, size is a power of 2.
 153      */
 154     transient volatile Cell[] cells;
 155 
 156     /**


 355             }
 356             else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
 357                 try {                           // Initialize table
 358                     if (cells == as) {
 359                         Cell[] rs = new Cell[2];
 360                         rs[h & 1] = new Cell(Double.doubleToRawLongBits(x));
 361                         cells = rs;
 362                         break done;
 363                     }
 364                 } finally {
 365                     cellsBusy = 0;
 366                 }
 367             }
 368             // Fall back on using base
 369             else if (casBase(v = base, apply(fn, v, x)))
 370                 break done;
 371         }
 372     }
 373 
 374     // Unsafe mechanics
 375     private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
 376     private static final long BASE;
 377     private static final long CELLSBUSY;
 378     private static final long PROBE;
 379     static {
 380         try {
 381             BASE = U.objectFieldOffset
 382                 (Striped64.class.getDeclaredField("base"));
 383             CELLSBUSY = U.objectFieldOffset
 384                 (Striped64.class.getDeclaredField("cellsBusy"));
 385 
 386             PROBE = U.objectFieldOffset
 387                 (Thread.class.getDeclaredField("threadLocalRandomProbe"));
 388         } catch (ReflectiveOperationException e) {
 389             throw new Error(e);
 390         }
 391     }
 392 
 393 }


 116     /**
 117      * Padded variant of AtomicLong supporting only raw accesses plus CAS.
 118      *
 119      * JVM intrinsics note: It would be possible to use a release-only
 120      * form of CAS here, if it were provided.
 121      */
 122     @sun.misc.Contended static final class Cell {
 123         volatile long value;
 124         Cell(long x) { value = x; }
 125         final boolean cas(long cmp, long val) {
 126             return U.compareAndSwapLong(this, VALUE, cmp, val);
 127         }
 128         final void reset() {
 129             U.putLongVolatile(this, VALUE, 0L);
 130         }
 131         final void reset(long identity) {
 132             U.putLongVolatile(this, VALUE, identity);
 133         }
 134 
 135         // Unsafe mechanics
 136         private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
 137         private static final long VALUE;
 138         static {
 139             try {
 140                 VALUE = U.objectFieldOffset
 141                     (Cell.class.getDeclaredField("value"));
 142             } catch (ReflectiveOperationException e) {
 143                 throw new Error(e);
 144             }
 145         }
 146     }
 147 
 148     /** Number of CPUS, to place bound on table size */
 149     static final int NCPU = Runtime.getRuntime().availableProcessors();
 150 
 151     /**
 152      * Table of cells. When non-null, size is a power of 2.
 153      */
 154     transient volatile Cell[] cells;
 155 
 156     /**


 355             }
 356             else if (cellsBusy == 0 && cells == as && casCellsBusy()) {
 357                 try {                           // Initialize table
 358                     if (cells == as) {
 359                         Cell[] rs = new Cell[2];
 360                         rs[h & 1] = new Cell(Double.doubleToRawLongBits(x));
 361                         cells = rs;
 362                         break done;
 363                     }
 364                 } finally {
 365                     cellsBusy = 0;
 366                 }
 367             }
 368             // Fall back on using base
 369             else if (casBase(v = base, apply(fn, v, x)))
 370                 break done;
 371         }
 372     }
 373 
 374     // Unsafe mechanics
 375     private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
 376     private static final long BASE;
 377     private static final long CELLSBUSY;
 378     private static final long PROBE;
 379     static {
 380         try {
 381             BASE = U.objectFieldOffset
 382                 (Striped64.class.getDeclaredField("base"));
 383             CELLSBUSY = U.objectFieldOffset
 384                 (Striped64.class.getDeclaredField("cellsBusy"));
 385 
 386             PROBE = U.objectFieldOffset
 387                 (Thread.class.getDeclaredField("threadLocalRandomProbe"));
 388         } catch (ReflectiveOperationException e) {
 389             throw new Error(e);
 390         }
 391     }
 392 
 393 }