From bec9ec3fc1f24d55a37a6c90ac03dc60f87d4d72 Mon Sep 17 00:00:00 2001 From: Torvald Riegel Date: Fri, 30 Aug 2013 10:33:41 +0000 Subject: Add custom HTM fast path for RTM on x86_64. * libitm_i.h (gtm_thread): Assign an asm name to serial_lock. (htm_fastpath): Assign an asm name. * libitm.h (_ITM_codeProperties): Add non-ABI flags used by custom HTM fast paths. (_ITM_actions): Likewise. * config/x86/target.h (HTM_CUSTOM_FASTPATH): Enable custom fastpath on x86_64. * config/x86/sjlj.S (_ITM_beginTransaction): Add custom HTM fast path. * config/posix/rwlock.h (gtm_rwlock): Update comments. Move summary field to the start of the structure. * config/linux/rwlock.h (gtm_rwlock): Update comments. * beginend.cc (gtm_thread::begin_transaction): Add retry policy handling for custom HTM fast paths. From-SVN: r202101 --- libitm/beginend.cc | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'libitm/beginend.cc') diff --git a/libitm/beginend.cc b/libitm/beginend.cc index a3bf549..bd7b19e 100644 --- a/libitm/beginend.cc +++ b/libitm/beginend.cc @@ -165,7 +165,7 @@ GTM::gtm_thread::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb) if (unlikely(prop & pr_undoLogCode)) GTM_fatal("pr_undoLogCode not supported"); -#if defined(USE_HTM_FASTPATH) && !defined(HTM_CUSTOM_FASTPATH) +#ifdef USE_HTM_FASTPATH // HTM fastpath. Only chosen in the absence of transaction_cancel to allow // using an uninstrumented code path. // The fastpath is enabled only by dispatch_htm's method group, which uses @@ -187,6 +187,7 @@ GTM::gtm_thread::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb) // indeed in serial mode, and HW transactions should never need serial mode // for any internal changes (e.g., they never abort visibly to the STM code // and thus do not trigger the standard retry handling). +#ifndef HTM_CUSTOM_FASTPATH if (likely(htm_fastpath && (prop & pr_hasNoAbort))) { for (uint32_t t = htm_fastpath; t; t--) @@ -237,6 +238,49 @@ GTM::gtm_thread::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb) } } } +#else + // If we have a custom HTM fastpath in ITM_beginTransaction, we implement + // just the retry policy here. We communicate with the custom fastpath + // through additional property bits and return codes, and either transfer + // control back to the custom fastpath or run the fallback mechanism. The + // fastpath synchronization algorithm itself is the same. + // pr_HTMRetryableAbort states that a HW transaction started by the custom + // HTM fastpath aborted, and that we thus have to decide whether to retry + // the fastpath (returning a_tryHTMFastPath) or just proceed with the + // fallback method. + if (likely(htm_fastpath && (prop & pr_HTMRetryableAbort))) + { + tx = gtm_thr(); + if (unlikely(tx == NULL)) + { + // See below. + tx = new gtm_thread(); + set_gtm_thr(tx); + } + // If this is the first abort, reset the retry count. We abuse + // restart_total for the retry count, which is fine because our only + // other fallback will use serial transactions, which don't use + // restart_total but will reset it when committing. + if (!(prop & pr_HTMRetriedAfterAbort)) + tx->restart_total = htm_fastpath; + + if (--tx->restart_total > 0) + { + // Wait until any concurrent serial-mode transactions have finished. + // Essentially the same code as above. + if (serial_lock.is_write_locked()) + { + if (tx->nesting > 0) + goto stop_custom_htm_fastpath; + serial_lock.read_lock(tx); + serial_lock.read_unlock(tx); + } + // Let ITM_beginTransaction retry the custom HTM fastpath. + return a_tryHTMFastPath; + } + } + stop_custom_htm_fastpath: +#endif #endif tx = gtm_thr(); -- cgit v1.1