Skip to content

Commit

Permalink
Use exact maths in the CommunityLockManager
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvest committed Mar 8, 2016
1 parent f6784c4 commit 26a88d2
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 22 deletions.
13 changes: 13 additions & 0 deletions community/kernel/src/main/java/org/neo4j/helpers/MathUtil.java
Expand Up @@ -89,5 +89,18 @@ public static int compareLongAgainstDouble( long lhs, double rhs )
{ {
return - compareDoubleAgainstLong( rhs, lhs ); return - compareDoubleAgainstLong( rhs, lhs );
} }

/**
* Return an integer one less than the given integer, or throw {@link ArithmeticException} if the given integer is
* zero.
*/
public static int decrementExactNotPastZero( int value )
{
if ( value == 0 )
{
throw new ArithmeticException( "integer underflow past zero" );
}
return value - 1;
}
} }


Expand Up @@ -81,7 +81,7 @@ public boolean incrementActiveClients()
return false; return false;
} }
} }
while ( !clientState.compareAndSet( currentState, statusWithUpdatedClients( currentState, 1 ) ) ); while ( !clientState.compareAndSet( currentState, incrementActiveClients( currentState ) ) );
return true; return true;
} }


Expand All @@ -95,7 +95,7 @@ public void decrementActiveClients()
{ {
currentState = clientState.get(); currentState = clientState.get();
} }
while ( !clientState.compareAndSet( currentState, statusWithUpdatedClients( currentState, -1 ) ) ); while ( !clientState.compareAndSet( currentState, decrementActiveClients( currentState ) ) );
} }


/** /**
Expand Down Expand Up @@ -136,8 +136,13 @@ private int stateWithNewStatus( int clientState, int newStatus )
return newStatus | getActiveClients( clientState ); return newStatus | getActiveClients( clientState );
} }


private int statusWithUpdatedClients( int clientState, int delta ) private int incrementActiveClients( int clientState )
{ {
return getStatus( clientState ) | Math.addExact( getActiveClients( clientState ), delta ); return getStatus( clientState ) | Math.incrementExact( getActiveClients( clientState ) );
}

private int decrementActiveClients( int clientState )
{
return getStatus( clientState ) | Math.decrementExact( getActiveClients( clientState ) );
} }
} }
Expand Up @@ -19,6 +19,7 @@
*/ */
package org.neo4j.kernel.impl.locking.community; package org.neo4j.kernel.impl.locking.community;


import org.neo4j.helpers.MathUtil;
import org.neo4j.storageengine.api.lock.ResourceType; import org.neo4j.storageengine.api.lock.ResourceType;


public class LockResource public class LockResource
Expand Down Expand Up @@ -77,12 +78,12 @@ public String toString()


public void acquireReference() public void acquireReference()
{ {
refCount++; refCount = Math.incrementExact( refCount );
} }


public int releaseReference() public int releaseReference()
{ {
return --refCount; return refCount = MathUtil.decrementExactNotPastZero( refCount );
} }


public long resourceId() public long resourceId()
Expand Down
Expand Up @@ -23,6 +23,7 @@
import java.util.LinkedList; import java.util.LinkedList;
import java.util.ListIterator; import java.util.ListIterator;


import org.neo4j.helpers.MathUtil;
import org.neo4j.kernel.DeadlockDetectedException; import org.neo4j.kernel.DeadlockDetectedException;
import org.neo4j.kernel.impl.locking.LockType; import org.neo4j.kernel.impl.locking.LockType;
import org.neo4j.kernel.impl.util.ArrayMap; import org.neo4j.kernel.impl.util.ArrayMap;
Expand Down Expand Up @@ -99,12 +100,12 @@ private static class TxLockElement


void incrementRequests() void incrementRequests()
{ {
requests++; requests = Math.incrementExact( requests );
} }


void decrementRequests() void decrementRequests()
{ {
requests--; requests = MathUtil.decrementExactNotPastZero( requests );
} }


boolean hasNoRequests() boolean hasNoRequests()
Expand Down Expand Up @@ -151,7 +152,13 @@ public Object resource()


synchronized void mark() synchronized void mark()
{ {
this.marked++; marked = Math.incrementExact( marked );
}

/** synchronized by all caller methods */
private void unmark()
{
marked = MathUtil.decrementExactNotPastZero( marked );
} }


synchronized boolean isMarked() synchronized boolean isMarked()
Expand Down Expand Up @@ -233,7 +240,7 @@ synchronized boolean acquireReadLock( Object tx ) throws DeadlockDetectedExcepti
interrupted(); interrupted();
// if deadlocked, remove marking so lock is removed when empty // if deadlocked, remove marking so lock is removed when empty
tle.decrementRequests(); tle.decrementRequests();
marked--; unmark();
} }
} }


Expand All @@ -254,7 +261,7 @@ synchronized boolean tryAcquireReadLock( Object tx )
finally finally
{ {
// if deadlocked, remove marking so lock is removed when empty // if deadlocked, remove marking so lock is removed when empty
marked--; unmark();
} }
} }


Expand All @@ -276,8 +283,8 @@ synchronized void releaseReadLock( Object tx ) throws LockNotFoundException
throw new LockNotFoundException( "" + tx + " don't have readLock" ); throw new LockNotFoundException( "" + tx + " don't have readLock" );
} }


totalReadCount--; totalReadCount = MathUtil.decrementExactNotPastZero( totalReadCount );
tle.readCount--; tle.readCount = MathUtil.decrementExactNotPastZero( tle.readCount );
if ( tle.isFree() ) if ( tle.isFree() )
{ {
ragManager.lockReleased( this, tx ); ragManager.lockReleased( this, tx );
Expand Down Expand Up @@ -419,7 +426,7 @@ synchronized boolean acquireWriteLock( Object tx ) throws DeadlockDetectedExcept
interrupted(); interrupted();
// if deadlocked, remove marking so lock is removed when empty // if deadlocked, remove marking so lock is removed when empty
tle.decrementRequests(); tle.decrementRequests();
marked--; unmark();
} }
} }


Expand Down Expand Up @@ -451,7 +458,7 @@ synchronized boolean tryAcquireWriteLock( Object tx )
finally finally
{ {
// if deadlocked, remove marking so lock is removed when empty // if deadlocked, remove marking so lock is removed when empty
marked--; unmark();
} }
} }


Expand All @@ -473,8 +480,8 @@ synchronized void releaseWriteLock( Object tx ) throws LockNotFoundException
throw new LockNotFoundException( "" + tx + " don't have writeLock" ); throw new LockNotFoundException( "" + tx + " don't have writeLock" );
} }


totalWriteCount--; totalWriteCount = MathUtil.decrementExactNotPastZero( totalWriteCount );
tle.writeCount--; tle.writeCount = MathUtil.decrementExactNotPastZero( tle.writeCount );
if ( tle.isFree() ) if ( tle.isFree() )
{ {
ragManager.lockReleased( this, tx ); ragManager.lockReleased( this, tx );
Expand Down Expand Up @@ -587,7 +594,7 @@ public synchronized String describe()


public synchronized long maxWaitTime() public synchronized long maxWaitTime()
{ {
long max = 0l; long max = 0L;
for ( LockRequest thread : waitingThreadList ) for ( LockRequest thread : waitingThreadList )
{ {
if ( thread.since < max ) if ( thread.since < max )
Expand Down Expand Up @@ -624,15 +631,15 @@ public String toString()
private void registerReadLockAcquired( Object tx, TxLockElement tle ) private void registerReadLockAcquired( Object tx, TxLockElement tle )
{ {
registerLockAcquired( tx, tle ); registerLockAcquired( tx, tle );
totalReadCount++; totalReadCount = Math.incrementExact( totalReadCount );
tle.readCount++; tle.readCount = Math.incrementExact( tle.readCount );
} }


private void registerWriteLockAcquired( Object tx, TxLockElement tle ) private void registerWriteLockAcquired( Object tx, TxLockElement tle )
{ {
registerLockAcquired( tx, tle ); registerLockAcquired( tx, tle );
totalWriteCount++; totalWriteCount = Math.incrementExact( totalWriteCount );
tle.writeCount++; tle.writeCount = Math.incrementExact( tle.writeCount );
} }


private void registerLockAcquired( Object tx, TxLockElement tle ) private void registerLockAcquired( Object tx, TxLockElement tle )
Expand Down

0 comments on commit 26a88d2

Please sign in to comment.