package org.multiverse.stms.gamma.transactionalobjects.refs;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.multiverse.api.LockMode;
import org.multiverse.stms.gamma.GammaConstants;
import org.multiverse.stms.gamma.GammaStm;
import org.multiverse.stms.gamma.transactionalobjects.GammaTxnLong;
import org.multiverse.stms.gamma.transactionalobjects.Tranlocal;
import org.multiverse.stms.gamma.transactions.GammaTxn;
import static org.junit.Assert.*;
import static org.multiverse.stms.gamma.GammaTestUtils.*;
public class TryLockAndCheckConflictTest implements GammaConstants {
private GammaStm stm;
@Before
public void setUp() {
stm = new GammaStm();
}
//conflicts
@Test
public void writeBiased_whenOtherHasLocked() {
writeBiased_whenOtherHasLocked(LockMode.Read, LockMode.None, true);
writeBiased_whenOtherHasLocked(LockMode.Read, LockMode.Read, true);
writeBiased_whenOtherHasLocked(LockMode.Read, LockMode.Write, false);
writeBiased_whenOtherHasLocked(LockMode.Read, LockMode.Exclusive, false);
writeBiased_whenOtherHasLocked(LockMode.Write, LockMode.None, true);
writeBiased_whenOtherHasLocked(LockMode.Write, LockMode.Read, false);
writeBiased_whenOtherHasLocked(LockMode.Write, LockMode.Write, false);
writeBiased_whenOtherHasLocked(LockMode.Write, LockMode.Exclusive, false);
//write_whenOtherHasLocked(LockMode.Exclusive, LockMode.None, false);
writeBiased_whenOtherHasLocked(LockMode.Exclusive, LockMode.Read, false);
writeBiased_whenOtherHasLocked(LockMode.Exclusive, LockMode.Write, false);
writeBiased_whenOtherHasLocked(LockMode.Exclusive, LockMode.Exclusive, false);
}
public void writeBiased_whenOtherHasLocked(LockMode otherLockMode, LockMode thisLockMode, boolean success) {
GammaTxnLong ref = new GammaTxnLong(stm);
//tx.arriveEnabled = arriveNeeded;
Tranlocal tranlocal = ref.openForRead(stm.newDefaultTxn(), LOCKMODE_NONE);
ref.openForRead(stm.newDefaultTxn(), otherLockMode.asInt());
//todo: null transaction
boolean result = ref.tryLockAndCheckConflict(null, tranlocal, 1, thisLockMode.asInt());
assertEquals(success, result);
//assertEquals(expectedLockMode.asInt(), tranlocal.getLockMode());
//assertLockMode(ref, expectedLockMode);
//assertSurplus(ref, expectedSurplus);
}
@Test
public void writeBiased_whenLockFreeAndArriveNeeded() {
writeBiased(true, LockMode.None, LockMode.None, LockMode.None, 1);
writeBiased(true, LockMode.None, LockMode.Read, LockMode.Read, 1);
writeBiased(true, LockMode.None, LockMode.Write, LockMode.Write, 1);
writeBiased(true, LockMode.None, LockMode.Exclusive, LockMode.Exclusive, 1);
writeBiased(true, LockMode.Read, LockMode.None, LockMode.Read, 1);
writeBiased(true, LockMode.Read, LockMode.Read, LockMode.Read, 1);
writeBiased(true, LockMode.Read, LockMode.Write, LockMode.Write, 1);
writeBiased(true, LockMode.Read, LockMode.Exclusive, LockMode.Exclusive, 1);
writeBiased(true, LockMode.Write, LockMode.None, LockMode.Write, 1);
writeBiased(true, LockMode.Write, LockMode.Read, LockMode.Write, 1);
writeBiased(true, LockMode.Write, LockMode.Write, LockMode.Write, 1);
writeBiased(true, LockMode.Write, LockMode.Exclusive, LockMode.Exclusive, 1);
writeBiased(true, LockMode.Exclusive, LockMode.None, LockMode.Exclusive, 1);
writeBiased(true, LockMode.Exclusive, LockMode.Read, LockMode.Exclusive, 1);
writeBiased(true, LockMode.Exclusive, LockMode.Write, LockMode.Exclusive, 1);
writeBiased(true, LockMode.Exclusive, LockMode.Exclusive, LockMode.Exclusive, 1);
}
@Test
public void writeBiased_whenLockFreeAndNoArriveNeeded() {
writeBiased(false, LockMode.None, LockMode.None, LockMode.None, 0);
writeBiased(false, LockMode.None, LockMode.Read, LockMode.Read, 1);
writeBiased(false, LockMode.None, LockMode.Write, LockMode.Write, 1);
writeBiased(false, LockMode.None, LockMode.Exclusive, LockMode.Exclusive, 1);
writeBiased(false, LockMode.Read, LockMode.None, LockMode.Read, 1);
writeBiased(false, LockMode.Read, LockMode.Read, LockMode.Read, 1);
writeBiased(false, LockMode.Read, LockMode.Write, LockMode.Write, 1);
writeBiased(false, LockMode.Read, LockMode.Exclusive, LockMode.Exclusive, 1);
writeBiased(false, LockMode.Write, LockMode.None, LockMode.Write, 1);
writeBiased(false, LockMode.Write, LockMode.Read, LockMode.Write, 1);
writeBiased(false, LockMode.Write, LockMode.Write, LockMode.Write, 1);
writeBiased(false, LockMode.Write, LockMode.Exclusive, LockMode.Exclusive, 1);
writeBiased(false, LockMode.Exclusive, LockMode.None, LockMode.Exclusive, 1);
writeBiased(false, LockMode.Exclusive, LockMode.Read, LockMode.Exclusive, 1);
writeBiased(false, LockMode.Exclusive, LockMode.Write, LockMode.Exclusive, 1);
writeBiased(false, LockMode.Exclusive, LockMode.Exclusive, LockMode.Exclusive, 1);
}
public void writeBiased(boolean arriveNeeded, LockMode firstLockMode, LockMode secondLockMode,
LockMode expectedLockMode, int expectedSurplus) {
GammaTxnLong ref = new GammaTxnLong(stm);
GammaTxn tx = stm.newDefaultTxn();
tx.richmansMansConflictScan = arriveNeeded;
Tranlocal tranlocal = ref.openForRead(tx, firstLockMode.asInt());
boolean result = ref.tryLockAndCheckConflict(tx, tranlocal, 1, secondLockMode.asInt());
assertTrue(result);
assertEquals(expectedLockMode.asInt(), tranlocal.getLockMode());
assertLockMode(ref, expectedLockMode);
assertSurplus(ref, expectedSurplus);
}
@Test
public void readBiased_whenLockFree() {
readBiased(LockMode.None, LockMode.None, LockMode.None);
readBiased(LockMode.None, LockMode.Read, LockMode.Read);
readBiased(LockMode.None, LockMode.Write, LockMode.Write);
readBiased(LockMode.None, LockMode.Exclusive, LockMode.Exclusive);
readBiased(LockMode.Read, LockMode.None, LockMode.Read);
readBiased(LockMode.Read, LockMode.Read, LockMode.Read);
readBiased(LockMode.Read, LockMode.Write, LockMode.Write);
readBiased(LockMode.Read, LockMode.Exclusive, LockMode.Exclusive);
readBiased(LockMode.Write, LockMode.None, LockMode.Write);
readBiased(LockMode.Write, LockMode.Read, LockMode.Write);
readBiased(LockMode.Write, LockMode.Write, LockMode.Write);
readBiased(LockMode.Write, LockMode.Exclusive, LockMode.Exclusive);
readBiased(LockMode.Exclusive, LockMode.None, LockMode.Exclusive);
readBiased(LockMode.Exclusive, LockMode.Read, LockMode.Exclusive);
readBiased(LockMode.Exclusive, LockMode.Write, LockMode.Exclusive);
readBiased(LockMode.Exclusive, LockMode.Exclusive, LockMode.Exclusive);
}
public void readBiased(LockMode firstLockMode, LockMode secondLockMode, LockMode expectedLockMode) {
GammaTxnLong ref = makeReadBiased(new GammaTxnLong(stm));
GammaTxn tx = stm.newDefaultTxn();
tx.richmansMansConflictScan = true;
Tranlocal tranlocal = ref.openForRead(tx, firstLockMode.asInt());
boolean result = ref.tryLockAndCheckConflict(tx, tranlocal, 1, secondLockMode.asInt());
assertTrue(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(expectedLockMode.asInt(), tranlocal.getLockMode());
assertLockMode(ref, expectedLockMode);
assertSurplus(ref, 1);
}
@Test
@Ignore
public void lockNotFree() {
}
// ===================== lock free ==================================
@Test
public void lockFree_tryNoneLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_NONE);
assertTrue(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasNoLocks(ref);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 0);
}
@Test
public void lockFree_tryReadLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_READ);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_READ, tranlocal.getLockMode());
assertRefHasReadLock(ref, tx);
assertReadLockCount(ref, 1);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockFree_tryWriteLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_WRITE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_WRITE, tranlocal.getLockMode());
assertRefHasWriteLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockFree_tryExclusiveLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_EXCLUSIVE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_EXCLUSIVE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
// ==================== lock upgrade ========================
@Test
public void lockUpgrade_readLockAcquired_tryNoLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_READ);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_NONE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_READ, tranlocal.getLockMode());
assertRefHasReadLock(ref, tx);
assertReadLockCount(ref, 1);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockUpgrade_readLockAcquired_tryReadLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_READ);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_READ);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_READ, tranlocal.getLockMode());
assertRefHasReadLock(ref, tx);
assertReadLockCount(ref, 1);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockUpgrade_readLockAcquired_otherTransactionAlreadyAcquiredReadLock_tryReadLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_READ);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Read);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_READ);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_READ, tranlocal.getLockMode());
assertRefHasReadLock(ref, tx);
assertReadLockCount(ref, 2);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 2);
}
@Test
public void lockUpgrade_readLockAcquired_tryWriteLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_READ);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_WRITE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_WRITE, tranlocal.getLockMode());
assertRefHasWriteLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockUpgrade_readLockAcquired_otherTransactionAlsoAcquiredReadLock_tryWriteLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_READ);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Read);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_WRITE);
assertFalse(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_READ, tranlocal.getLockMode());
assertRefHasReadLock(ref, tx);
assertReadLockCount(ref, 2);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 2);
}
@Test
public void lockUpgrade_readLockAcquired_tryExclusiveLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_READ);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_EXCLUSIVE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_EXCLUSIVE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockUpgrade_readLockAcquired_otherTransactionAlsoAcquiredReadLock_tryExclusiveLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_READ);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Read);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_EXCLUSIVE);
assertFalse(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_READ, tranlocal.getLockMode());
assertRefHasReadLock(ref, tx);
assertReadLockCount(ref, 2);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 2);
}
@Test
public void lockUpgrade_writeLockAcquired_tryNoLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_WRITE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_NONE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_WRITE, tranlocal.getLockMode());
assertRefHasWriteLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockUpgrade_writeLockAcquired_tryReadLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_WRITE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_READ);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_WRITE, tranlocal.getLockMode());
assertRefHasWriteLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockAcquired_writeLockAcquired_tryWriteLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_WRITE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_WRITE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_WRITE, tranlocal.getLockMode());
assertRefHasWriteLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockAcquired_writeLockAcquired_tryExclusiveLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_WRITE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_EXCLUSIVE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_EXCLUSIVE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockUpgrade_exclusiveLockAcquired_tryNoLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_EXCLUSIVE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_NONE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_EXCLUSIVE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockUpgrade_exclusiveLockAcquired_tryReadLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_EXCLUSIVE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_READ);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_EXCLUSIVE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockAcquired_exclusiveLockAcquired_tryWriteLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_EXCLUSIVE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_WRITE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_EXCLUSIVE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockAcquired_exclusiveLockAcquired_tryExclusiveLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_EXCLUSIVE);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_EXCLUSIVE);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_EXCLUSIVE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, tx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
// ===================== lock free ==================================
@Test
public void lockFreeButConflictingUpdate_tryNoneLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
ref.atomicIncrementAndGet(1);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_NONE);
assertTrue(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasNoLocks(ref);
assertVersionAndValue(ref, initialVersion + 1, initialValue + 1);
assertSurplus(ref, 0);
}
@Test
public void lockFreeButConflictingUpdate__tryReadLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
ref.atomicIncrementAndGet(1);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_READ);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasNoLocks(ref);
assertVersionAndValue(ref, initialVersion + 1, initialValue + 1);
assertSurplus(ref, 0);
}
@Test
public void lockFreeButConflictingUpdate__tryWriteLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
ref.atomicIncrementAndGet(1);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_WRITE);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasNoLocks(ref);
assertVersionAndValue(ref, initialVersion + 1, initialValue + 1);
assertSurplus(ref, 0);
}
@Test
public void lockFreeButConflictingUpdate__tryExclusiveLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
ref.atomicIncrementAndGet(1);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_EXCLUSIVE);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasNoLocks(ref);
assertVersionAndValue(ref, initialVersion + 1, initialValue + 1);
assertSurplus(ref, 0);
}
// ===================== lock not free ==================================
@Test
public void lockNotFree_readLockAcquired_acquireNone() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Read);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_NONE);
assertTrue(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasReadLock(ref, otherTx);
assertReadLockCount(ref, 1);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockNotFree_readLockAcquired_acquireReadLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Read);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_READ);
assertTrue(result);
assertTrue(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_READ, tranlocal.getLockMode());
assertRefHasReadLock(ref, tx);
assertReadLockCount(ref, 2);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 2);
}
@Test
public void lockNotFree_readLockAcquired_acquireWriteLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Read);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_WRITE);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasReadLock(ref, otherTx);
assertReadLockCount(ref, 1);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockNotFree_readLockAcquired_acquireExclusiveLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Read);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_EXCLUSIVE);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasReadLock(ref, otherTx);
assertReadLockCount(ref, 1);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockNotFree_writeLockAcquired_acquireNoLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Write);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_NONE);
assertTrue(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasWriteLock(ref, otherTx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockNotFree_writeLockAcquired_acquireReadLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Write);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_READ);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasWriteLock(ref, otherTx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockNotFree_writeLockAcquired_acquireWriteLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Write);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_WRITE);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasWriteLock(ref, otherTx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockNotFree_writeLockAcquired_acquireExclusiveLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Write);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_EXCLUSIVE);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasWriteLock(ref, otherTx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockNotFree_exclusiveLockAcquired_acquireNoLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Exclusive);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_NONE);
assertTrue(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, otherTx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockNotFree_exclusiveLockAcquired_acquireReadLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Exclusive);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_READ);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, otherTx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockNotFree_exclusiveLockAcquired_acquireWriteLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Exclusive);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_WRITE);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, otherTx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
@Test
public void lockNotFree_exclusiveLockAcquired_acquireExclusiveLock() {
long initialValue = 10;
GammaTxnLong ref = new GammaTxnLong(stm, initialValue);
long initialVersion = ref.getVersion();
GammaTxn tx = stm.newDefaultTxn();
Tranlocal tranlocal = ref.openForRead(tx, LOCKMODE_NONE);
GammaTxn otherTx = stm.newDefaultTxn();
ref.getLock().acquire(otherTx, LockMode.Exclusive);
boolean result = ref.tryLockAndCheckConflict(tx,tranlocal, 1, LOCKMODE_EXCLUSIVE);
assertFalse(result);
assertFalse(tranlocal.hasDepartObligation());
assertEquals(LOCKMODE_NONE, tranlocal.getLockMode());
assertRefHasExclusiveLock(ref, otherTx);
assertVersionAndValue(ref, initialVersion, initialValue);
assertSurplus(ref, 1);
}
}