Comments
Patch
@@ -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
@@ -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)
{
@@ -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)
{
@@ -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 *));