libitm: Fix handling of reentrancy in the HTM fastpath.
authorTorvald Riegel <triegel@redhat.com>
Thu, 20 Jun 2013 16:40:38 +0000 (16:40 +0000)
committerTorvald Riegel <torvald@gcc.gnu.org>
Thu, 20 Jun 2013 16:40:38 +0000 (16:40 +0000)
PR libitm/57643
* beginend.cc (gtm_thread::begin_transaction): Handle reentrancy in
the HTM fastpath.

From-SVN: r200250

libitm/ChangeLog
libitm/beginend.cc

index ed9114b91474a45fa4174ba700dff561e67788bb..26001b670bd5e89817a49ff27336c0b4aded8a8a 100644 (file)
@@ -1,3 +1,9 @@
+2013-06-20  Torvald Riegel  <triegel@redhat.com>
+
+       PR libitm/57643
+       * beginend.cc (gtm_thread::begin_transaction): Handle reentrancy in
+       the HTM fastpath.
+
 2013-03-31  Gerald Pfeifer  <gerald@pfeifer.com>
 
        PR bootstrap/56714
index 93e702efc9eb53c155608e4f75c96f7fa79259cb..a3bf5492153bac5532cdd99409fc0525f36d92dd 100644 (file)
@@ -197,6 +197,8 @@ GTM::gtm_thread::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb)
              // We are executing a transaction now.
              // Monitor the writer flag in the serial-mode lock, and abort
              // if there is an active or waiting serial-mode transaction.
+             // Note that this can also happen due to an enclosing
+             // serial-mode transaction; we handle this case below.
              if (unlikely(serial_lock.is_write_locked()))
                htm_abort();
              else
@@ -219,6 +221,14 @@ GTM::gtm_thread::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb)
                  tx = new gtm_thread();
                  set_gtm_thr(tx);
                }
+             // Check whether there is an enclosing serial-mode transaction;
+             // if so, we just continue as a nested transaction and don't
+             // try to use the HTM fastpath.  This case can happen when an
+             // outermost relaxed transaction calls unsafe code that starts
+             // a transaction.
+             if (tx->nesting > 0)
+               break;
+             // Another thread is running a serial-mode transaction.  Wait.
              serial_lock.read_lock(tx);
              serial_lock.read_unlock(tx);
              // TODO We should probably reset the retry count t here, unless