[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 = >m_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