Patchwork [trans-mem] Use per-transaction reader flags for the serial lock

login
register
mail settings
Submitter Torvald Riegel
Date Aug. 9, 2011, 12:01 p.m.
Message ID <1312891266.3533.368.camel@triegel.csb>
Download mbox | patch
Permalink /patch/109201/
State New
Headers show

Comments

Torvald Riegel - Aug. 9, 2011, 12:01 p.m.
On Fri, 2011-08-05 at 19:33 +0200, Torvald Riegel wrote:
> patch8:
> 
> The first patch merely keeps a list of all threads with transactions,
> registering and deregistering gtm_transaction objects during their
> construction and destruction. The aligment attribute for the start of
> the shared part of a gtm_transaction object relies on allocating those
> objects on separate cachelines (and thus aligned at cacheline
> granularity). This has not been implemented yet, but is requested by the
> xmalloc call for gtm_transaction.

Attached is a revised patch that puts HW_CACHELINE_SIZE into
config/*/target.h instead of libitm_i.h.
commit b76c73421c17ca9df7411129ca622f3143514f17
Author: Torvald Riegel <triegel@redhat.com>
Date:   Fri Jul 29 22:12:14 2011 +0200

    Maintain a list of all threads' transactions.
    
    	* libitm_i.h (next_tx): Add list of all threads' transaction.
    	* beginend.cc (GTM::gtm_transaction::begin_transaction): Register
    	transaction with list of transactions and ...
    	(thread_exit_handler): ... deregister here.
    	* config/alpha/target.h: Add HW_CACHELINE_SIZE setting.
    	* config/x86/target.h: Same.
Richard Henderson - Aug. 12, 2011, 5:27 p.m.
On 08/09/2011 05:01 AM, Torvald Riegel wrote:
>     Maintain a list of all threads' transactions.
>     
>     	* libitm_i.h (next_tx): Add list of all threads' transaction.
>     	* beginend.cc (GTM::gtm_transaction::begin_transaction): Register
>     	transaction with list of transactions and ...
>     	(thread_exit_handler): ... deregister here.
>     	* config/alpha/target.h: Add HW_CACHELINE_SIZE setting.
>     	* config/x86/target.h: Same.

Ok.


r~

Patch

diff --git a/libitm/beginend.cc b/libitm/beginend.cc
index 08592a3..fc7cb8d 100644
--- a/libitm/beginend.cc
+++ b/libitm/beginend.cc
@@ -29,6 +29,7 @@  using namespace GTM;
 
 __thread gtm_thread GTM::_gtm_thr;
 gtm_rwlock GTM::gtm_transaction::serial_lock;
+gtm_transaction *GTM::gtm_transaction::list_of_tx = 0;
 
 gtm_stmlock GTM::gtm_stmlock_array[LOCK_ARRAY_SIZE];
 gtm_version GTM::gtm_clock;
@@ -75,6 +76,20 @@  thread_exit_handler(void *dummy __attribute__((unused)))
     {
       if (tx->nesting > 0)
         GTM_fatal("Thread exit while a transaction is still active.");
+
+      // Deregister this transaction.
+      gtm_transaction::serial_lock.write_lock ();
+      gtm_transaction **prev = &gtm_transaction::list_of_tx;
+      for (; *prev; prev = &(*prev)->next_tx)
+        {
+          if (*prev == tx)
+            {
+              *prev = (*prev)->next_tx;
+              break;
+            }
+        }
+      gtm_transaction::serial_lock.write_unlock ();
+
       delete tx;
       set_gtm_tx(NULL);
     }
@@ -124,6 +139,12 @@  GTM::gtm_transaction::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb)
       tx = new gtm_transaction;
       set_gtm_tx(tx);
 
+      // Register this transaction with the list of all threads' transactions.
+      serial_lock.write_lock ();
+      tx->next_tx = list_of_tx;
+      list_of_tx = tx;
+      serial_lock.write_unlock ();
+
       if (pthread_once(&tx_release_once, thread_exit_init))
         GTM_fatal("Initializing tx release TLS key failed.");
       // Any non-null value is sufficient to trigger releasing of this
diff --git a/libitm/config/alpha/target.h b/libitm/config/alpha/target.h
index 94ac59b..121546f 100644
--- a/libitm/config/alpha/target.h
+++ b/libitm/config/alpha/target.h
@@ -1,4 +1,4 @@ 
-/* Copyright (C) 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2009, 2011 Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@redhat.com>.
 
    This file is part of the GNU Transactional Memory Library (libitm).
@@ -36,6 +36,9 @@  typedef struct gtm_jmpbuf
 #define PAGE_SIZE	8192
 #define FIXED_PAGE_SIZE	1
 
+/* The size of one line in hardware caches (in bytes). */
+#define HW_CACHELINE_SIZE 64
+
 static inline void
 cpu_relax (void)
 {
diff --git a/libitm/config/x86/target.h b/libitm/config/x86/target.h
index 758e773..197faeb 100644
--- a/libitm/config/x86/target.h
+++ b/libitm/config/x86/target.h
@@ -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).
@@ -56,6 +56,10 @@  typedef struct gtm_jmpbuf
 #define PAGE_SIZE       4096
 #define FIXED_PAGE_SIZE 1
 
+/* The size of one line in hardware caches (in bytes). */
+#define HW_CACHELINE_SIZE 64
+
+
 static inline void
 cpu_relax (void)
 {
diff --git a/libitm/libitm_i.h b/libitm/libitm_i.h
index 7d475be..f738ff7 100644
--- a/libitm/libitm_i.h
+++ b/libitm/libitm_i.h
@@ -187,11 +187,21 @@  struct gtm_transaction
   uint32_t restart_reason[NUM_RESTARTS];
   uint32_t restart_total;
 
+  // *** The shared part of gtm_transaction starts here. ***
+  // Shared state is on separate cachelines to avoid false sharing with
+  // thread-local parts of gtm_transaction.
+
+  // Points to the next transaction in the list of all threads' transactions.
+  gtm_transaction *next_tx __attribute__((__aligned__(HW_CACHELINE_SIZE)));
+
   // The lock that provides access to serial mode.  Non-serialized
   // transactions acquire read locks; a serialized transaction aquires
   // a write lock.
   static gtm_rwlock serial_lock;
 
+  // The head of the list of all threads' transactions.
+  static gtm_transaction *list_of_tx;
+
   // In alloc.cc
   void commit_allocations (bool, aa_tree<uintptr_t, gtm_alloc_action>*);
   void record_allocation (void *, void (*)(void *));