Patchwork [trans-mem] New TM method: serial-irrevocable on first write

login
register
mail settings
Submitter Torvald Riegel
Date Aug. 3, 2011, 10:56 a.m.
Message ID <1312369013.3533.228.camel@triegel.csb>
Download mbox | patch
Permalink /patch/108114/
State New
Headers show

Comments

Torvald Riegel - Aug. 3, 2011, 10:56 a.m.
This adds a new TM method which lets transactions simply read through
without any protection until the first write in the transaction, upon
which the transaction switches to serial-irrevocable mode (thus
isolating all other transactions from uncommitted writes).

This can work well for read-mostly workloads but is too simplistic for
anything else. Nevertheless, it's useful to test the performance of the
upcoming changes to the serial lock implementation, and can be better
than always going to serial mode (which currently is the only
implemented TM method).

OK for branch?
commit a2eefe78d18203c40de0f4b81dc934ff575d8ee5
Author: Torvald Riegel <triegel@redhat.com>
Date:   Thu Jul 28 21:21:12 2011 +0200

    Add serialirr_onwrite_dispatch and use as new default method, for now.
    
    	* retry.cc (GTM::gtm_transaction::decide_begin_dispatch): Use
    	serialirr_onwrite_dispatch as new default for now.
    	* method-serial.cc (serialirr_onwrite_dispatch): New.
    	(GTM::dispatch_serialirr_onwrite): New.
    	* libitm_i.h: Same.
Richard Henderson - Aug. 4, 2011, 3:39 p.m.
On 08/03/2011 03:56 AM, Torvald Riegel wrote:
>     Add serialirr_onwrite_dispatch and use as new default method, for now.
>     
>     	* retry.cc (GTM::gtm_transaction::decide_begin_dispatch): Use
>     	serialirr_onwrite_dispatch as new default for now.
>     	* method-serial.cc (serialirr_onwrite_dispatch): New.
>     	(GTM::dispatch_serialirr_onwrite): New.
>     	* libitm_i.h: Same.

Ok.


r~

Patch

diff --git a/libitm/libitm_i.h b/libitm/libitm_i.h
index 093fc0e..97f535a 100644
--- a/libitm/libitm_i.h
+++ b/libitm/libitm_i.h
@@ -252,6 +252,7 @@  extern void GTM_fatal (const char *fmt, ...)
 
 extern abi_dispatch *dispatch_serial();
 extern abi_dispatch *dispatch_serialirr();
+extern abi_dispatch *dispatch_serialirr_onwrite();
 
 extern gtm_cacheline_mask gtm_mask_stack(gtm_cacheline *, gtm_cacheline_mask);
 
diff --git a/libitm/method-serial.cc b/libitm/method-serial.cc
index 5912791..430f004 100644
--- a/libitm/method-serial.cc
+++ b/libitm/method-serial.cc
@@ -1,4 +1,4 @@ 
-/* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@redhat.com>.
 
    This file is part of the GNU Transactional Memory Library (libitm).
@@ -41,6 +41,10 @@  class serialirr_dispatch : public abi_dispatch
   serialirr_dispatch() : abi_dispatch(false, true, true, false) { }
 
  protected:
+  serialirr_dispatch(bool ro, bool wt, bool uninstrumented,
+      bool closed_nesting) :
+    abi_dispatch(ro, wt, uninstrumented, closed_nesting) { }
+
   // Transactional loads and stores simply access memory directly.
   // These methods are static to avoid indirect calls, and will be used by the
   // virtual ABI dispatch methods or by static direct-access methods created
@@ -139,10 +143,65 @@  public:
   serial_dispatch() : abi_dispatch(false, true, false, true) { }
 };
 
+
+// Like serialirr_dispatch but does not requests serial-irrevocable mode until
+// the first write in the transaction. Can be useful for read-mostly workloads
+// and testing, but is likely too simple to be of general purpose.
+class serialirr_onwrite_dispatch : public serialirr_dispatch
+{
+ public:
+  serialirr_onwrite_dispatch() :
+    serialirr_dispatch(false, true, false, false) { }
+
+ protected:
+  static void pre_write()
+  {
+    gtm_transaction *tx = gtm_tx();
+    if (!(tx->state & (gtm_transaction::STATE_SERIAL
+        | gtm_transaction::STATE_IRREVOCABLE)))
+      tx->serialirr_mode();
+  }
+
+  // Transactional loads access memory directly.
+  // Transactional stores switch to serial mode first.
+  template <typename V> static void store(V* addr, const V value,
+      ls_modifier mod)
+  {
+    pre_write();
+    serialirr_dispatch::store(addr, value, mod);
+  }
+
+ public:
+  static void memtransfer_static(void *dst, const void* src, size_t size,
+      bool may_overlap, ls_modifier dst_mod, ls_modifier src_mod)
+  {
+    pre_write();
+    serialirr_dispatch::memtransfer_static(dst, src, size, may_overlap,
+        dst_mod, src_mod);
+  }
+
+  static void memset_static(void *dst, int c, size_t size, ls_modifier mod)
+  {
+    pre_write();
+    serialirr_dispatch::memset_static(dst, c, size, mod);
+  }
+
+  CREATE_DISPATCH_METHODS(virtual, )
+  CREATE_DISPATCH_METHODS_MEM()
+
+  virtual void rollback(gtm_transaction_cp *cp)
+  {
+    gtm_transaction *tx = gtm_tx();
+    if (tx->state & gtm_transaction::STATE_IRREVOCABLE)
+      abort();
+  }
+};
+
 } // 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;
 
 abi_dispatch *
 GTM::dispatch_serialirr ()
@@ -156,6 +215,13 @@  GTM::dispatch_serial ()
   return const_cast<serial_dispatch *>(&o_serial_dispatch);
 }
 
+abi_dispatch *
+GTM::dispatch_serialirr_onwrite ()
+{
+  return
+      const_cast<serialirr_onwrite_dispatch *>(&o_serialirr_onwrite_dispatch);
+}
+
 // Put the transaction into serial-irrevocable mode.
 
 void
diff --git a/libitm/retry.cc b/libitm/retry.cc
index 199201a..5b3bf90 100644
--- a/libitm/retry.cc
+++ b/libitm/retry.cc
@@ -1,4 +1,4 @@ 
-/* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@redhat.com>.
 
    This file is part of the GNU Transactional Memory Library (libitm).
@@ -87,6 +87,8 @@  GTM::gtm_transaction::decide_begin_dispatch (uint32_t prop)
 {
   // ??? Probably want some environment variable to choose the default
   // STM implementation once we have more than one implemented.
+  if (prop & pr_hasNoAbort)
+    return dispatch_serialirr_onwrite();
   state = STATE_SERIAL;
   if (prop & pr_hasNoAbort)
     state |= STATE_IRREVOCABLE;