Locked AbortReexecException

  • Thursday, September 17, 2009 9:41 PM
     
      Has Code

    Hi,

    I try to do my first steps with STM. I used the small program below to test retries. Funny thing is that I always get a System.TransactionalMemory.AbortReexecException thrown in the Debugger. From my - admittedly small - understanding of STM.NET i think it should automatically wait for a given condition (i.e. the conflicting transaction is finished) and then retry automatically. Why doesn't it?

    using System.Threading;
    using System.TransactionalMemory;
    
    class Program
    {
        static int _foo = 0;
    
        [AtomicNotSupported]
        static void Main(string[] args)
        {
            Thread t1 = new Thread(() => {
                while (true) {
                    Atomic.Do(() => {
                        _foo++;
                        Thread.Sleep(1);
                    });
                }
            });
            Thread t2 = new Thread(() => {
                while (true) {
                    Atomic.Do(() => {
                        _foo--;
                        Thread.Sleep(1);
                    });
                }
            });
            t1.Start();
            t2.Start();
        }
    }
    

All Replies

  • Friday, September 18, 2009 8:44 PM
     
     

    Hi there…

     

    Good question. Let’s first talk about the terminology that we use with STM.Net (unfortunately terminology around STM varies…). We use the following:

     

    Rollback – this is a mechanism that undoes whatever the transaction has done so far, and gets control flow to the beginning of it. It can employed for different reasons (that are listed next).

    Re-execute – the transaction re-executes when it discovers that it’s in an inconsistent state. It first rolls back and then starts again.

    Abort – means the user has thrown an exception that escapes the transaction. This is the only thing that can abort a transaction.

    Retry – means the user has called Atomic.Retry. The transaction will rollback and then, sometime later, will re-executes.

     

    You’ll note that re-executing due to inconsistency is a system triggered event, whereas re-execution due to abort or retry is something that the user initiates. However, the system uses AbortReexecException to implement re-execution due to inconsistency, too. This is why you see these exceptions in the debugger. You only see those when you have “break on first-exception” enabled, since the STM system also catches and handles these exception. They are basically used to unwind the stack such that you end up again at the code that started the transaction. Then you can re-execute.

     

    You can change the “while(true)” to a finite loop, disable the “break on first chance exception” and then you should be able to see the program running to completion successfully, and the value _foo should indeed be 0 when you finish.

     

    I hope this helps!

     

    --Yossi

     


    Yossi Levanoni, Principal Development Lead Parallel Computing Platform, Technical Computing Group, Microsoft
  • Sunday, September 20, 2009 3:32 PM
     
     

    Thanks for the explanation on the grammar.

    Can you please tell me where i can disable "break on first chance exception"? I could not find this setting in the debugger-related settings in VS08.

    However, i don't think i have ever seen exceptions coming up that are caught in the exception handler stack anyway. I now registered the AbortReexecException to not be reported on throw, but the "direct window" (using german version of VS, don't know correct name in english) keeps reporting that there is an unhandled exception in the user code. This smells like a bug to me and kills performance.

    Besides, i think both Re-Executes and Retries should be made available for the end-programmer as static method in Atomic. I realize that this will only throw AbortReexec or Retry exceptions, but has different semantics from the user (programmer) point of view. After all, Retry() is there anyway, so why not make Reexec available right there.
    It seems to me that a re-exec is a special case of a retry anyway (having nothing to wait for and thus immediately retrying).

    For the "while(true)" part - this is intended, the main thread would output the current values of _foo, indicating how fast the transaction would execute compared to a non-transacted execution (e.g. using interlocked or even allowing races).

  • Monday, September 21, 2009 5:59 AM
     
     Answered

    In VS2008, disable “break on first chance exception” by  Debug->Exceptions, uncheck “Thrown” and “User-handled” for “Common Language Runtime Exceptions”.

     

    Yes, you will still see the msg about AbortReexecException in the “Debug” view of the “Output” window.

     

    It is not a bug as explained in the previous post. “AbortReexecException” is used internally to trigger re-execution. It will be handled by system code. In your example, the two transactions you wrote (one does ++, the other does --) always conflict with each other. One of them has to be rolled-back and re-execute.  For such scenario, no matter what synchronization mechanism are used, you won’t be able to really get parallelism. So it kills performance as it is supposed to do.  STM helps the user to get scalability via automatic fine-grain locking. It works when the majority of transactions in the system does not conflict with others. If all transactions are accessing a centralized shared location (such as __foo in your code),  you cannot expect the scalability. Please refer to the User Guide to understand what STM helps.

     

    Why do you want to make Reexec available to the user?  Re-execution happens when a transaction finds itself in an inconsistent state, therefore it rolls back and start again. The check of inconsistency was done by the system automatically, which is not visible to the user. User can only see a transaction commits or aborts (via a user exception). In both cases, the shared states are kept consistent. If you want a transaction to re-execute when certain conditions are not satisfied, you use Retry.

     


    Yossi Levanoni, Principal Development Lead Parallel Computing Platform, Microsoft
    • Marked As Answer by Dana GroffOwner Wednesday, September 23, 2009 5:50 AM
    •