]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libitm/method-serial.cc
2013-06-27 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
[thirdparty/gcc.git] / libitm / method-serial.cc
index 09cfdd4a17520903f9562aec60336271a1fc5103..8dafce58fdb0478c3550c81bb6e3ee9214db5d7a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2013 Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@redhat.com>.
 
    This file is part of the GNU Transactional Memory Library (libitm).
@@ -212,11 +212,46 @@ class serialirr_onwrite_dispatch : public serialirr_dispatch
   }
 };
 
+// This group is pure HTM with serial mode as a fallback.  There is no
+// difference to serial_mg except that we need to enable or disable the HTM
+// fastpath.  See gtm_thread::begin_transaction.
+struct htm_mg : public method_group
+{
+  virtual void init()
+  {
+    // Enable the HTM fastpath if the HW is available.  The fastpath is
+    // initially disabled.
+#ifdef USE_HTM_FASTPATH
+    htm_fastpath = htm_init();
+#endif
+  }
+  virtual void fini()
+  {
+    // Disable the HTM fastpath.
+    htm_fastpath = 0;
+  }
+};
+
+static htm_mg o_htm_mg;
+
+// We just need the subclass to associate it with the HTM method group that
+// sets up the HTM fast path.  This will use serial_dispatch as fallback for
+// transactions that might get canceled; it has a different method group, but
+// this is harmless for serial dispatchs because they never abort.
+class htm_dispatch : public serialirr_dispatch
+{
+ public:
+  htm_dispatch() : serialirr_dispatch(false, true, false, false,
+      gtm_thread::STATE_SERIAL | gtm_thread::STATE_IRREVOCABLE, &o_htm_mg)
+  { }
+};
+
 } // anon namespace
 
 static const serialirr_dispatch o_serialirr_dispatch;
 static const serial_dispatch o_serial_dispatch;
 static const serialirr_onwrite_dispatch o_serialirr_onwrite_dispatch;
+static const htm_dispatch o_htm_dispatch;
 
 abi_dispatch *
 GTM::dispatch_serialirr ()
@@ -237,6 +272,12 @@ GTM::dispatch_serialirr_onwrite ()
       const_cast<serialirr_onwrite_dispatch *>(&o_serialirr_onwrite_dispatch);
 }
 
+abi_dispatch *
+GTM::dispatch_htm ()
+{
+  return const_cast<htm_dispatch *>(&o_htm_dispatch);
+}
+
 // Put the transaction into serial-irrevocable mode.
 
 void
@@ -244,6 +285,13 @@ GTM::gtm_thread::serialirr_mode ()
 {
   struct abi_dispatch *disp = abi_disp ();
 
+#if defined(USE_HTM_FASTPATH)
+  // HTM fastpath.  If we are executing a HW transaction, don't go serial but
+  // continue.  See gtm_thread::begin_transaction.
+  if (likely(htm_fastpath && !gtm_thread::serial_lock.is_write_locked()))
+    return;
+#endif
+
   if (this->state & STATE_SERIAL)
     {
       if (this->state & STATE_IRREVOCABLE)