public void Merge(ReadMap other) { foreach (var kvpair in other) { PutIfAbsent(kvpair.Key,kvpair.Value); } }
private static void WaitOnReadset(JVTransaction transaction, ReadMap readMap) { #if DEBUG Console.WriteLine("ENTERED WAIT ON RETRY: " + transaction.Number); #endif if (readMap.Count == 0) { throw new STMInvalidRetryException(); } var expectedEra = transaction.RetryLatch.Era; foreach (var kvpair in readMap) { kvpair.Key.RegisterRetryLatch(transaction.RetryLatch, kvpair.Value, expectedEra); } if (!transaction.ReadMap.Validate()) { transaction.Abort(); return; } #if DEBUG Console.WriteLine("WAIT ON RETRY: " + transaction.Number); #endif transaction.Await(expectedEra); transaction.RetryLatch.Reset(); #if DEBUG Console.WriteLine("AWOKEN: " + transaction.Number); #endif transaction.Abort(); }
private static T AtomicInternal <T>(IList <Func <JVTransaction, T> > stmActions) { Debug.Assert(stmActions.Count > 0); var result = default(T); var index = 0; var nrAttempts = 0; var overAllReadSet = new ReadMap(); while (true) { var stmAction = stmActions[index]; var localTransaction = JVTransaction.LocalTransaction; var transaction = localTransaction.Status == TransactionStatus.Active ? JVTransaction.StartNested(localTransaction) : JVTransaction.Start(); JVTransaction.LocalTransaction = transaction; try { //Execute transaction body result = stmAction(transaction); if (transaction.Commit()) { return(result); } transaction.Abort(); } catch (STMRetryException) { index = HandleRetry(stmActions, transaction, index, overAllReadSet); }/* * catch (Exception ex) //Catch non stm related exceptions which occurs in transactions * { * //Throw exception of transaction can commit * //Else abort and rerun transaction * if (transaction.Commit()) * { * throw; * } * }*/ nrAttempts++; //transaction.Abort(); if (transaction.IsNested) { JVTransaction.LocalTransaction = transaction.Parent; } if (nrAttempts == MAX_ATTEMPTS) { throw new STMMaxAttemptException("Fatal error: max attempts reached"); } } }
private JVTransaction(TransactionStatus status, int id, JVTransaction parent, ReadMap readMap, WriteMap writeMap) { Number = id; Parent = parent; ReadMap = readMap; WriteMap = writeMap; Status = status; //Commutes = new List<BaseCommute>(); }
private JVTransaction(TransactionStatus status, ActiveTxnRecord txnRecord, JVTransaction parent, ReadMap readMap, WriteMap writeMap) { Number = txnRecord.TxNumber; Parent = parent; ReadMap = readMap; WriteMap = writeMap; Status = status; _txnRecord = txnRecord; //Commutes = new List<BaseCommute>(); }
public bool Validate(ReadMap readMap) { foreach (var writePair in this) { if (readMap.ContainsKey(writePair.Key)) { return(false); } } return(true); }
private static int HandleRetry <T>(IList <Func <JVTransaction, T> > stmActions, JVTransaction transaction, int index, ReadMap overAllReadSet) { if (stmActions.Count == 1) //Optimized for when there are no orelse blocks { WaitOnReadset(transaction, transaction.ReadMap); } else if (stmActions.Count == index + 1) //Final orelse block { overAllReadSet.Merge(transaction.ReadMap); WaitOnReadset(transaction, overAllReadSet); index = 0; } else //Non final atomic or orelse blocks { #if DEBUG Console.WriteLine("Transaction: " + transaction.Number + " ORELSE jump"); #endif overAllReadSet.Merge(transaction.ReadMap); index++; } return(index); }
public bool Commit() { return(CommitLockFree()); if (WriteMap.Count == 0) { Status = TransactionStatus.Committed; //_txnRecord.FinishTransaction(); return(true); } bool result; ActiveTxnRecord commitRecord = null; lock (CommitLock) { var newNumber = ActiveTxnRecord.LastCommitted.TxNumber + 1; var valid = ReadMap.Validate(); if (!valid) { result = false; } else { if (IsNested) { Parent.ReadMap.Merge(ReadMap); Parent.WriteMap.Merge(WriteMap); } else { //var bodies = new BaseVBoxBody[WriteMap.Count]; var i = 0; foreach (var kvpair in WriteMap) { //bodies[i] = kvpair.Key.Install(kvpair.Value, newNumber); kvpair.Key.Install(kvpair.Value, newNumber); i++; } //commitRecord = new ActiveTxnRecord(newNumber, bodies); commitRecord = new ActiveTxnRecord(newNumber); ActiveTxnRecord.InsertNewRecord(commitRecord); } Status = TransactionStatus.Committed; result = true; } } /* * if (result && !IsNested) * { * _txnRecord.FinishTransaction(); * * if (commitRecord != null) * { * Interlocked.Decrement(ref commitRecord.Running); * } * }*/ return(result);; }