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 <trie...@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 <r...@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 <r...@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 *));