private static long getState( long address ) { return UnsafeUtil.getLongVolatile( address ); }
private long getCurrentFileSize() { return UnsafeUtil.getLongVolatile( this, fileSizeOffset ); }
private long getHeaderState() { return UnsafeUtil.getLongVolatile( this, headerStateOffset ); }
long getHighestEvictedTransactionId() { return UnsafeUtil.getLongVolatile( this, evictedTransactionIdOffset ); }
private byte getUsageCounter( long pageRef ) { return (byte) (UnsafeUtil.getLongVolatile( offPageBinding( pageRef ) ) & MASK_USAGE_COUNT); }
long getLastModifiedTxId( long pageRef ) { return UnsafeUtil.getLongVolatile( offLastModifiedTransactionId( pageRef ) ); }
/** * Atomically set field or array element to a maximum between current value and provided <code>newValue</code> */ public static void compareAndSetMaxLong( Object object, long fieldOffset, long newValue ) { long currentValue; do { currentValue = UnsafeUtil.getLongVolatile( object, fieldOffset ); if ( currentValue >= newValue ) { return; } } while ( !UnsafeUtil.compareAndSwapLong( object, fieldOffset, currentValue, newValue ) ); }
/** * Decrement the usage stamp. Returns true if it reaches 0. **/ boolean decrementUsage( long pageRef ) { // This is intentionally left benignly racy for performance. long address = offPageBinding( pageRef ); long value = UnsafeUtil.getLongVolatile( address ); long usage = value & MASK_USAGE_COUNT; if ( usage > 0 ) { long update = value - 1; // See `incrementUsage` about why we use `compareAndSwapLong`. UnsafeUtil.compareAndSwapLong( null, address, value, update ); } return usage <= 1; }
/** * Increment the usage stamp to at most 4. **/ void incrementUsage( long pageRef ) { // This is intentionally left benignly racy for performance. long address = offPageBinding( pageRef ); long value = UnsafeUtil.getLongVolatile( address ); long usage = value & MASK_USAGE_COUNT; if ( usage < MAX_USAGE_COUNT ) // avoid cache sloshing by not doing a write if counter is already maxed out { long update = value + 1; // Use compareAndSwapLong to only actually store the updated count if nothing else changed // in this word-line. The word-line is shared with the file page id, and the swapper id. // Those fields are updated under guard of the exclusive lock, but we *might* race with // that here, and in that case we would never want a usage counter update to clobber a page // binding update. UnsafeUtil.compareAndSwapLong( null, address, value, update ); } }
putLongVolatile( obj, aLongOffset, 2 ); assertThat( obj.aLong, is( 2L ) ); assertThat( getLongVolatile( obj, aLongOffset ), is( 2L ) ); obj.aLong = 0; assertThat( obj, is( new Obj() ) );
assertThat( getLongVolatile( address ), is( 1L ) ); setMemory( address, sizeInBytes, (byte) 0 ); assertThat( getLongVolatile( address ), is( 0L ) );
private long getHeaderState() { return UnsafeUtil.getLongVolatile( this, headerStateOffset ); }
private long getCurrentFileSize() { return UnsafeUtil.getLongVolatile( this, fileSizeOffset ); }
long getHighestEvictedTransactionId() { return UnsafeUtil.getLongVolatile( this, evictedTransactionIdOffset ); }
private static long getState( long address ) { return UnsafeUtil.getLongVolatile( address ); }
long getLastModifiedTxId( long pageRef ) { return UnsafeUtil.getLongVolatile( offLastModifiedTransactionId( pageRef ) ); }
private byte getUsageCounter( long pageRef ) { return (byte) (UnsafeUtil.getLongVolatile( offPageBinding( pageRef ) ) & MASK_USAGE_COUNT); }
/** * Atomically set field or array element to a maximum between current value and provided <code>newValue</code> */ public static void compareAndSetMaxLong( Object object, long fieldOffset, long newValue ) { long currentValue; do { currentValue = UnsafeUtil.getLongVolatile( object, fieldOffset ); if ( currentValue >= newValue ) { return; } } while ( !UnsafeUtil.compareAndSwapLong( object, fieldOffset, currentValue, newValue ) ); }
/** * Decrement the usage stamp. Returns true if it reaches 0. **/ boolean decrementUsage( long pageRef ) { // This is intentionally left benignly racy for performance. long address = offPageBinding( pageRef ); long value = UnsafeUtil.getLongVolatile( address ); long usage = value & MASK_USAGE_COUNT; if ( usage > 0 ) { long update = value - 1; // See `incrementUsage` about why we use `compareAndSwapLong`. UnsafeUtil.compareAndSwapLong( null, address, value, update ); } return usage <= 1; }
/** * Increment the usage stamp to at most 4. **/ void incrementUsage( long pageRef ) { // This is intentionally left benignly racy for performance. long address = offPageBinding( pageRef ); long value = UnsafeUtil.getLongVolatile( address ); long usage = value & MASK_USAGE_COUNT; if ( usage < MAX_USAGE_COUNT ) // avoid cache sloshing by not doing a write if counter is already maxed out { long update = value + 1; // Use compareAndSwapLong to only actually store the updated count if nothing else changed // in this word-line. The word-line is shared with the file page id, and the swapper id. // Those fields are updated under guard of the exclusive lock, but we *might* race with // that here, and in that case we would never want a usage counter update to clobber a page // binding update. UnsafeUtil.compareAndSwapLong( null, address, value, update ); } }