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

Torvald Riegel triegel@redhat.com
Tue Aug 9 12:28:00 GMT 2011


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.


-------------- next part --------------
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.

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 *));


More information about the Gcc-patches mailing list