From b679c81340ece3ceecbd74d46a1af6fe473813bc Mon Sep 17 00:00:00 2001
From: Torvald Riegel <triegel@redhat.com>
Date: Wed, 24 Oct 2012 19:52:02 +0000
Subject: [PATCH] Ask dispatch whether it requires serial mode.

	* retry.cc (gtm_thread::decide_begin_dispatch): Ask dispatch whether
	it requires serial mode instead of assuming that for certain
	dispatchs.
	* dispatch.h (abi_dispatch::requires_serial): New.
	(abi_dispatch::abi_dispatch): Adapt.
	* method-gl.cc (gl_wt_dispatch::gl_wt_dispatch): Adapt.
	* method-ml.cc (ml_wt_dispatch::ml_wt_dispatch): Same.
	* method-serial.cc (serialirr_dispatch::serialirr_dispatch,
	serial_dispatch::serial_dispatch,
	serialirr_onwrite_dispatch::serialirr_onwrite_dispatch): Same.

From-SVN: r192777
---
 libitm/ChangeLog        | 13 +++++++++++++
 libitm/dispatch.h       |  9 +++++++--
 libitm/method-gl.cc     |  2 +-
 libitm/method-ml.cc     |  2 +-
 libitm/method-serial.cc | 14 +++++++++-----
 libitm/retry.cc         |  7 ++-----
 6 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/libitm/ChangeLog b/libitm/ChangeLog
index d62247987ea9..af74e974df11 100644
--- a/libitm/ChangeLog
+++ b/libitm/ChangeLog
@@ -1,3 +1,16 @@
+2012-10-24  Torvald Riegel  <triegel@redhat.com>
+
+	* retry.cc (gtm_thread::decide_begin_dispatch): Ask dispatch whether
+	it requires serial mode instead of assuming that for certain
+	dispatchs.
+	* dispatch.h (abi_dispatch::requires_serial): New.
+	(abi_dispatch::abi_dispatch): Adapt.
+	* method-gl.cc (gl_wt_dispatch::gl_wt_dispatch): Adapt.
+	* method-ml.cc (ml_wt_dispatch::ml_wt_dispatch): Same.
+	* method-serial.cc (serialirr_dispatch::serialirr_dispatch,
+	serial_dispatch::serial_dispatch,
+	serialirr_onwrite_dispatch::serialirr_onwrite_dispatch): Same.
+
 2012-10-02  Uros Bizjak  <ubizjak@gmail.com>
 
 	* config/x86/target.h (struct gtm_jmpbuf): Merge x86_64
diff --git a/libitm/dispatch.h b/libitm/dispatch.h
index 6a9e62ef6c0d..200138bb4b89 100644
--- a/libitm/dispatch.h
+++ b/libitm/dispatch.h
@@ -311,6 +311,9 @@ public:
   }
   // Returns true iff this TM method supports closed nesting.
   bool closed_nesting() const { return m_closed_nesting; }
+  // Returns STATE_SERIAL or STATE_SERIAL | STATE_IRREVOCABLE iff the TM
+  // method only works for serial-mode transactions.
+  uint32_t requires_serial() const { return m_requires_serial; }
   method_group* get_method_group() const { return m_method_group; }
 
   static void *operator new(size_t s) { return xmalloc (s); }
@@ -332,12 +335,14 @@ protected:
   const bool m_write_through;
   const bool m_can_run_uninstrumented_code;
   const bool m_closed_nesting;
+  const uint32_t m_requires_serial;
   method_group* const m_method_group;
   abi_dispatch(bool ro, bool wt, bool uninstrumented, bool closed_nesting,
-      method_group* mg) :
+      uint32_t requires_serial, method_group* mg) :
     m_read_only(ro), m_write_through(wt),
     m_can_run_uninstrumented_code(uninstrumented),
-    m_closed_nesting(closed_nesting), m_method_group(mg)
+    m_closed_nesting(closed_nesting), m_requires_serial(requires_serial),
+    m_method_group(mg)
   { }
 };
 
diff --git a/libitm/method-gl.cc b/libitm/method-gl.cc
index 4b6769ba2c00..be8f36c011e2 100644
--- a/libitm/method-gl.cc
+++ b/libitm/method-gl.cc
@@ -341,7 +341,7 @@ public:
   CREATE_DISPATCH_METHODS(virtual, )
   CREATE_DISPATCH_METHODS_MEM()
 
-  gl_wt_dispatch() : abi_dispatch(false, true, false, false, &o_gl_mg)
+  gl_wt_dispatch() : abi_dispatch(false, true, false, false, 0, &o_gl_mg)
   { }
 };
 
diff --git a/libitm/method-ml.cc b/libitm/method-ml.cc
index 88455e8f85e0..80278f519aea 100644
--- a/libitm/method-ml.cc
+++ b/libitm/method-ml.cc
@@ -590,7 +590,7 @@ public:
   CREATE_DISPATCH_METHODS(virtual, )
   CREATE_DISPATCH_METHODS_MEM()
 
-  ml_wt_dispatch() : abi_dispatch(false, true, false, false, &o_ml_mg)
+  ml_wt_dispatch() : abi_dispatch(false, true, false, false, 0, &o_ml_mg)
   { }
 };
 
diff --git a/libitm/method-serial.cc b/libitm/method-serial.cc
index bdecd7b87b32..09cfdd4a1752 100644
--- a/libitm/method-serial.cc
+++ b/libitm/method-serial.cc
@@ -50,13 +50,15 @@ static serial_mg o_serial_mg;
 class serialirr_dispatch : public abi_dispatch
 {
  public:
-  serialirr_dispatch() : abi_dispatch(false, true, true, false, &o_serial_mg)
+  serialirr_dispatch() : abi_dispatch(false, true, true, false,
+      gtm_thread::STATE_SERIAL | gtm_thread::STATE_IRREVOCABLE, &o_serial_mg)
   { }
 
  protected:
   serialirr_dispatch(bool ro, bool wt, bool uninstrumented,
-      bool closed_nesting, method_group* mg) :
-    abi_dispatch(ro, wt, uninstrumented, closed_nesting, mg) { }
+      bool closed_nesting, uint32_t requires_serial, method_group* mg) :
+    abi_dispatch(ro, wt, uninstrumented, closed_nesting, requires_serial, mg)
+  { }
 
   // Transactional loads and stores simply access memory directly.
   // These methods are static to avoid indirect calls, and will be used by the
@@ -151,7 +153,9 @@ public:
   CREATE_DISPATCH_METHODS(virtual, )
   CREATE_DISPATCH_METHODS_MEM()
 
-  serial_dispatch() : abi_dispatch(false, true, false, true, &o_serial_mg) { }
+  serial_dispatch() : abi_dispatch(false, true, false, true,
+      gtm_thread::STATE_SERIAL, &o_serial_mg)
+  { }
 };
 
 
@@ -162,7 +166,7 @@ class serialirr_onwrite_dispatch : public serialirr_dispatch
 {
  public:
   serialirr_onwrite_dispatch() :
-    serialirr_dispatch(false, true, false, false, &o_serial_mg) { }
+    serialirr_dispatch(false, true, false, false, 0, &o_serial_mg) { }
 
  protected:
   static void pre_write()
diff --git a/libitm/retry.cc b/libitm/retry.cc
index 660bf5244e3c..172419bb8032 100644
--- a/libitm/retry.cc
+++ b/libitm/retry.cc
@@ -173,7 +173,7 @@ GTM::gtm_thread::decide_begin_dispatch (uint32_t prop)
 	  && dd->closed_nesting_alternative())
 	dd = dd->closed_nesting_alternative();
 
-      if (dd != dispatch_serial() && dd != dispatch_serialirr())
+      if (!(dd->requires_serial() & STATE_SERIAL))
 	{
 	  // The current dispatch is supposedly a non-serial one.  Become an
 	  // active transaction and verify this.  Relaxed memory order is fine
@@ -193,10 +193,7 @@ GTM::gtm_thread::decide_begin_dispatch (uint32_t prop)
 
   // We are some kind of serial transaction.
   serial_lock.write_lock();
-  if (dd == dispatch_serialirr())
-    state = STATE_SERIAL | STATE_IRREVOCABLE;
-  else
-    state = STATE_SERIAL;
+  state = dd->requires_serial();
   return dd;
 }
 
-- 
GitLab