@Override public void beforeReadAccess(Object obj, long field) { if (vr) { readHash = LockTable.hash(obj, field); // Lock entry in read mode (might throw an exception) readLock = LockTable.lock(this, readHash, id, false); if (readLock >= 0) { synchronized (writeSet) { // Mutual exclusion on write set to allow other transaction to drop locks if ((status.get() & STATUS_MASK) != TX_ACTIVE) { // We have been killed: drop lock we just acquired (not in write set) LockTable.setAndReleaseLock(readHash, readLock); // Abort throw KILLED_EXCEPTION; } // Add to write set (for being able to drop lock later) writeSet.addRead(readHash, obj, field, readLock); } } } else { readHash = LockTable.hash(obj, field); // Check if the field is locked (may throw an exception) readLock = LockTable.checkLock(this, readHash, id); } }
@Override public void beforeReadAccess(Object obj, long field, int advice) { ReadFieldAccess next = readSet.getNext(); currentReadFieldAccess = next; next.init(obj, field, advice); // Check the read is still valid lastReadLock = LockTable.checkLock(next.hashCode(), localClock); }
private boolean onReadAccess(Object obj, long field, Type type) { if (vr) { // Visible read if (readLock == LockTable.LOCKED_WRITE) { // We already own that lock in write mode WriteFieldAccess w = writeSet.get(readHash, obj, field); if (w == null) return false; readValue = w.getValue(); return true; } else { // We already own that lock in read mode return false; } } else { // Invisible read if ((status.get() & STATUS_MASK) != TX_ACTIVE) { // We have been killed: abort throw KILLED_EXCEPTION; } if (readLock == LockTable.LOCKED_WRITE) { // We already own that lock in write mode WriteFieldAccess w = writeSet.get(readHash, obj, field); if (w == null) return false; readValue = w.getValue(); return true; } else if (readLock == LockTable.LOCKED_READ) { // We already own that lock in read mode return false; } boolean b = false; while (true) { while (readLock <= endTime) { // Re-read timestamp (check for race) long lock = LockTable.checkLock(this, readHash, id); if (lock != readLock) { readLock = lock; readValue = Field.getValue(obj, field, type); b = true; continue; } // We have read a valid value (in snapshot) if (readWriteHint) { // Save to read set readSet.add(obj, field, readHash, lock); } return b; } // Try to extend snapshot if (!(readWriteHint && extend())) { throw EXTEND_FAILURE_EXCEPTION; } } } }
private WriteFieldAccess onReadAccess0(Object obj, long field, int advice) { ReadFieldAccess current = currentReadFieldAccess; int hash = current.hashCode(); // Check the read is still valid LockTable.checkLock(hash, localClock, lastReadLock); // Check if it is already included in the write set return writeSet.contains(current); }