示例#1
0
        private static void WaitOnReadset(Transaction me, ReadSet readSet, int readstamp)
        {
#if DEBUG
            Console.WriteLine("ENTERED WAIT ON RETRY: " + me.ID);
#endif

            if (readSet.Count == 0)
            {
                throw new STMInvalidRetryException();
            }

            var waiton = new WaitHandle[readSet.Count()];

            var i = 0;
            foreach (var item in readSet)
            {
                waiton[i] = item.Key.RegisterWaitHandle();
                i++;
            }

            if (!readSet.Validate(me, readstamp))
            {
                return;
            }

#if DEBUG
            Console.WriteLine("WAIT ON RETRY: " + me.ID);
#endif
            WaitHandle.WaitAny(waiton);
#if DEBUG
            Console.WriteLine("WAIT ON RETRY: " + me.ID);
#endif
        }
示例#2
0
 public void Merge(ReadSet other)
 {
     foreach (var kvpair in other)
     {
         if (!_lockObjects.ContainsKey(kvpair.Key))
         {
             _lockObjects[kvpair.Key] = kvpair.Value;
         }
     }
 }
示例#3
0
        private static T AtomicInternal <T>(IList <Func <T> > stmActions)
        {
            Debug.Assert(stmActions.Count > 0);
            var result           = default(T);
            var index            = 0;
            var overAllReadSet   = new ReadSet();
            var ovarAllReadstamp = -1;
            var nrAttempts       = 0;

            while (true)
            {
                var stmAction = stmActions[index];

                //Start new or nested transaction
                var prevTransaction = Transaction.LocalTransaction;
                var me = prevTransaction.Status == TransactionStatus.Active ?
                         Transaction.StartNestedTransaction(prevTransaction) :
                         Transaction.StartTransaction();

                if (index == 0)
                {
                    ovarAllReadstamp = me.ReadStamp;
                }

                try
                {
                    //Execute transaction body
                    result = stmAction();

                    if (me.Commit())
                    {
                        return(result);
                    }
                }
                catch (STMAbortException)
                {
                    //Skips straight to abort a reexecute
                }
                catch (STMRetryException)
                {
                    index = HandleRetry(stmActions, me, index, overAllReadSet, ovarAllReadstamp);
                }
                catch (Exception) //Catch non stm related exceptions which occurs in transactions
                {
                    //Throw exception of transaction can commit
                    //Else abort and rerun transaction
                    if (me.Commit())
                    {
                        throw;
                    }
                }

                nrAttempts++;
                me.Abort();

                //If the transaction is nested restore the parent as current transaction before retrying
                if (me.IsNested)
                {
                    Transaction.LocalTransaction = me.Parent;
                }

                if (nrAttempts == MAX_ATTEMPTS)
                {
                    throw new STMMaxAttemptException("Fatal error: max attempts reached");
                }
            }
        }
示例#4
0
 private static void WaitOnReadset(Transaction me, ReadSet readSet)
 {
     WaitOnReadset(me, readSet, me.ReadStamp);
 }
示例#5
0
        private static int HandleRetry <T>(IList <Func <T> > stmActions, Transaction me, int index, ReadSet overAllReadSet, int originalReadstamp)
        {
            if (stmActions.Count == 1) //Optimized for when there are no orelse blocks
            {
                WaitOnReadset(me, me.ReadSet);
            }
            else if (stmActions.Count == index + 1) //Final orelse block
            {
                overAllReadSet.Merge(me.ReadSet);
                WaitOnReadset(me, overAllReadSet, originalReadstamp);
                index = 0;
            }
            else //Non final atomic or orelse blocks
            {
#if DEBUG
                Console.WriteLine("Transaction: " + me.ID + " ORELSE jump");
#endif
                overAllReadSet.Merge(me.ReadSet);
                index++;
            }

            return(index);
        }