libitm: Improve method reinit and choice.
authorTorvald Riegel <triegel@redhat.com>
Tue, 14 Feb 2012 13:14:12 +0000 (13:14 +0000)
committerTorvald Riegel <torvald@gcc.gnu.org>
Tue, 14 Feb 2012 13:14:12 +0000 (13:14 +0000)
libitm/
* dispatch.h (GTM::abi_dispatch::supports): New.
(GTM::method_group::reinit): New.
* retry.cc (GTM::gtm_thread::decide_retry_strategy): Use reinit().
(GTM::gtm_thread::number_of_threads_changed): Check that the method
supports the current situation.

From-SVN: r184211

libitm/ChangeLog
libitm/dispatch.h
libitm/retry.cc

index 130c9efbd8500c12ed3c22767a401f3446310c3f..e44057d38d34efc327391d34ae2c900e244d5f26 100644 (file)
@@ -1,3 +1,11 @@
+2012-02-14  Torvald Riegel  <triegel@redhat.com>
+
+       * dispatch.h (GTM::abi_dispatch::supports): New.
+       (GTM::method_group::reinit): New.
+       * retry.cc (GTM::gtm_thread::decide_retry_strategy): Use reinit().
+       (GTM::gtm_thread::number_of_threads_changed): Check that the method
+       supports the current situation.
+
 2012-02-14  Torvald Riegel  <triegel@redhat.com>
 
        * util.cc (GTM::xcalloc): New.
index dbf05e4da37271674602e5a993b58b91cc949048..d059c493507df885461981581ce62e11aef83e81 100644 (file)
@@ -245,6 +245,12 @@ struct method_group
   // Stop using any method from this group for now. This can be used to
   // destruct meta data as soon as this method group is not used anymore.
   virtual void fini() = 0;
+  // This can be overriden to implement more light-weight re-initialization.
+  virtual void reinit()
+  {
+    fini();
+    init();
+  }
 };
 
 
@@ -290,6 +296,10 @@ public:
   // method on begin of a nested transaction without committing or restarting
   // the parent method.
   virtual abi_dispatch* closed_nesting_alternative() { return 0; }
+  // Returns true iff this method group supports the current situation.
+  // NUMBER_OF_THREADS is the current number of threads that might execute
+  // transactions.
+  virtual bool supports(unsigned number_of_threads) { return true; }
 
   bool read_only () const { return m_read_only; }
   bool write_through() const { return m_write_through; }
index decd7731b46282ede4e79805d34c5d2ef8c53601..761a066e834aa5f555c03e5eb1b76dd75010d8bc 100644 (file)
@@ -58,11 +58,8 @@ GTM::gtm_thread::decide_retry_strategy (gtm_restart_reason r)
          serial_lock.read_unlock(this);
          serial_lock.write_lock();
          if (disp->get_method_group() == default_dispatch->get_method_group())
-           {
-             // Still the same method group.
-             disp->get_method_group()->fini();
-             disp->get_method_group()->init();
-           }
+           // Still the same method group.
+           disp->get_method_group()->reinit();
          serial_lock.write_unlock();
          serial_lock.read_lock(this);
          if (disp->get_method_group() != default_dispatch->get_method_group())
@@ -72,11 +69,8 @@ GTM::gtm_thread::decide_retry_strategy (gtm_restart_reason r)
            }
        }
       else
-       {
-         // We are a serial transaction already, which makes things simple.
-         disp->get_method_group()->fini();
-         disp->get_method_group()->init();
-       }
+       // We are a serial transaction already, which makes things simple.
+       disp->get_method_group()->reinit();
     }
 
   bool retry_irr = (r == RESTART_SERIAL_IRR);
@@ -249,7 +243,7 @@ GTM::gtm_thread::number_of_threads_changed(unsigned previous, unsigned now)
       // Only one thread, so use a serializing method.
       // ??? If we don't have a fast serial mode implementation, it might be
       // better to use the global lock method set here.
-      if (default_dispatch_user)
+      if (default_dispatch_user && default_dispatch_user->supports(now))
        set_default_dispatch(default_dispatch_user);
       else
        set_default_dispatch(dispatch_serialirr());
@@ -257,9 +251,16 @@ GTM::gtm_thread::number_of_threads_changed(unsigned previous, unsigned now)
   else if (now > 1 && previous <= 1)
     {
       // More than one thread, use the default method.
-      if (default_dispatch_user)
+      if (default_dispatch_user && default_dispatch_user->supports(now))
        set_default_dispatch(default_dispatch_user);
       else
-       set_default_dispatch(dispatch_serialirr_onwrite());
+       {
+         abi_dispatch* a = dispatch_serialirr_onwrite();
+         if (a->supports(now))
+           set_default_dispatch(a);
+         else
+           // Serial-irrevocable mode always works.
+           set_default_dispatch(dispatch_serialirr());
+       }
     }
 }