@Override public void init(int blockId, String metainf) { readSet.clear(); writeSet.clear(); // Lock according to the transaction irrevocable state if (irrevocableState) irrevocableAccessLock.writeLock().lock(); else irrevocableAccessLock.readLock().lock(); endTime = clock.get(); startTime.set(endTime); status.set(((status.get() + (1 << STATUS_BITS)) & ~STATUS_MASK) | TX_ACTIVE); if (RO_HINT) { atomicBlockId = blockId; readWriteHint = readWriteMarkers.get(atomicBlockId); } attempts++; vr = (VR_THRESHOLD > 0 && VR_THRESHOLD <= attempts); }
private void onWriteAccess(Object obj, long field, Object value, Type type) { if (!readWriteHint) { // Change hint to read-write readWriteMarkers.insert(atomicBlockId, true); throw READ_ONLY_FAILURE_EXCEPTION; } int hash = LockTable.hash(obj, field); // Lock entry in write mode (might throw an exception) long timestamp = LockTable.lock(this, hash, id, true); 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 if (timestamp >= 0) { // Drop lock we just acquired (not in write set) LockTable.setAndReleaseLock(hash, timestamp); } // Abort throw KILLED_EXCEPTION; } if (timestamp < 0) { // We already own that lock writeSet.appendWrite(hash, obj, field, value, type); } else { // Add to write set if (timestamp > endTime) { // Handle write-after-read if (readSet.contains(obj, field)) { // Abort LockTable.setAndReleaseLock(hash, timestamp); throw WRITE_FAILURE_EXCEPTION; } // We delay validation until later (although we could already validate once here) } // Add to write set writeSet.addWrite(hash, obj, field, value, type, timestamp); } } }