diff options
Diffstat (limited to 'gcc-4.8/libitm')
-rw-r--r-- | gcc-4.8/libitm/ChangeLog | 64 | ||||
-rw-r--r-- | gcc-4.8/libitm/acinclude.m4 | 14 | ||||
-rw-r--r-- | gcc-4.8/libitm/beginend.cc | 10 | ||||
-rw-r--r-- | gcc-4.8/libitm/config/generic/asmcfi.h | 4 | ||||
-rw-r--r-- | gcc-4.8/libitm/config/linux/futex_bits.h | 6 | ||||
-rw-r--r-- | gcc-4.8/libitm/config/powerpc/sjlj.S | 24 | ||||
-rw-r--r-- | gcc-4.8/libitm/config/powerpc/target.h | 82 | ||||
-rw-r--r-- | gcc-4.8/libitm/config/x86/target.h | 7 | ||||
-rw-r--r-- | gcc-4.8/libitm/configure | 54 | ||||
-rw-r--r-- | gcc-4.8/libitm/configure.tgt | 5 | ||||
-rw-r--r-- | gcc-4.8/libitm/libitm.info | 128 | ||||
-rw-r--r-- | gcc-4.8/libitm/query.cc | 14 |
12 files changed, 336 insertions, 76 deletions
diff --git a/gcc-4.8/libitm/ChangeLog b/gcc-4.8/libitm/ChangeLog index b71c0f8f7..9b3ff926e 100644 --- a/gcc-4.8/libitm/ChangeLog +++ b/gcc-4.8/libitm/ChangeLog @@ -1,3 +1,66 @@ +2014-05-22 Release Manager + + * GCC 4.8.3 released. + +2014-04-14 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * acinclude.m4: Move s390* case from RTM to HTM check. + * configure: Regenerate. + +2014-04-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * config/generic/asmcfi.h: Also check for + __GCC_HAVE_DWARF2_CFI_ASM. + +2014-04-04 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Backport from mainline r204808: + + 2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/powerpc/sjlj.S [__powerpc64__ && _CALL_ELF == 2]: + (FUNC): Define ELFv2 variant. + (END): Likewise. + (HIDDEN): Likewise. + (CALL): Likewise. + (BASE): Likewise. + (LR_SAVE): Likewise. + +2014-04-04 Bill Schmidt <wschmidt@linux.vnet.ibm.com> + + Power8 HTM Support + Backport from mainline + * acinclude.m4 (LIBITM_CHECK_AS_HTM): New. + * configure: Rebuild. + * configure.tgt (target_cpu): Add -mhtm to XCFLAGS. + * config/powerpc/target.h: Include sys/auxv.h and htmintrin.h. + (USE_HTM_FASTPATH): Define. + (_TBEGIN_STARTED, _TBEGIN_INDETERMINATE, _TBEGIN_PERSISTENT) + (_HTM_RETRIES) New macros. + (htm_abort, htm_abort_should_retry, htm_available, htm_begin, htm_init) + (htm_begin_success, htm_commit, htm_transaction_active): New functions. + +2014-03-26 Jakub Jelinek <jakub@redhat.com> + + * config/linux/futex_bits.h: Include errno.h. + (sys_futex0): If syscall returns -1, return -errno rather than + -1. + +2014-03-03 Peter Bergner <bergner@vnet.ibm.com> + + Backport from mainline + 2013-06-20 Torvald Riegel <triegel@redhat.com> + + * query.cc (_ITM_inTransaction): Abort when using the HTM fastpath. + (_ITM_getTransactionId): Same. + * config/x86/target.h (htm_transaction_active): New. + + 2013-06-20 Torvald Riegel <triegel@redhat.com> + + PR libitm/57643 + * beginend.cc (gtm_thread::begin_transaction): Handle reentrancy in + the HTM fastpath. + 2013-10-16 Release Manager * GCC 4.8.2 released. @@ -9,7 +72,6 @@ * configure.tgt: Add -msoft-float to XCFLAGS. - 2013-08-14 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> * config/s390/sjlj.S: Add file missing from last commit. diff --git a/gcc-4.8/libitm/acinclude.m4 b/gcc-4.8/libitm/acinclude.m4 index de1c8f1ec..ca7e0a921 100644 --- a/gcc-4.8/libitm/acinclude.m4 +++ b/gcc-4.8/libitm/acinclude.m4 @@ -121,6 +121,20 @@ i[[34567]]86 | x86_64) AC_DEFINE(HAVE_AS_RTM, 1, [Define to 1 if the assembler supports RTM.]) fi ;; +esac]) + +dnl Check if as supports HTM instructions. +AC_DEFUN([LIBITM_CHECK_AS_HTM], [ +case "${target_cpu}" in +powerpc*) + AC_CACHE_CHECK([if the assembler supports HTM], libitm_cv_as_htm, [ + AC_TRY_COMPILE([], [asm("tbegin. 0; tend. 0");], + [libitm_cv_as_htm=yes], [libitm_cv_as_htm=no]) + ]) + if test x$libitm_cv_as_htm = xyes; then + AC_DEFINE(HAVE_AS_HTM, 1, [Define to 1 if the assembler supports HTM.]) + fi + ;; s390*) AC_CACHE_CHECK([if the assembler supports HTM], libitm_cv_as_htm, [ save_CFLAGS="$CFLAGS" diff --git a/gcc-4.8/libitm/beginend.cc b/gcc-4.8/libitm/beginend.cc index 93e702efc..a3bf54921 100644 --- a/gcc-4.8/libitm/beginend.cc +++ b/gcc-4.8/libitm/beginend.cc @@ -197,6 +197,8 @@ GTM::gtm_thread::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb) // We are executing a transaction now. // Monitor the writer flag in the serial-mode lock, and abort // if there is an active or waiting serial-mode transaction. + // Note that this can also happen due to an enclosing + // serial-mode transaction; we handle this case below. if (unlikely(serial_lock.is_write_locked())) htm_abort(); else @@ -219,6 +221,14 @@ GTM::gtm_thread::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb) tx = new gtm_thread(); set_gtm_thr(tx); } + // Check whether there is an enclosing serial-mode transaction; + // if so, we just continue as a nested transaction and don't + // try to use the HTM fastpath. This case can happen when an + // outermost relaxed transaction calls unsafe code that starts + // a transaction. + if (tx->nesting > 0) + break; + // Another thread is running a serial-mode transaction. Wait. serial_lock.read_lock(tx); serial_lock.read_unlock(tx); // TODO We should probably reset the retry count t here, unless diff --git a/gcc-4.8/libitm/config/generic/asmcfi.h b/gcc-4.8/libitm/config/generic/asmcfi.h index f34191763..59d73924b 100644 --- a/gcc-4.8/libitm/config/generic/asmcfi.h +++ b/gcc-4.8/libitm/config/generic/asmcfi.h @@ -24,7 +24,7 @@ #include "config.h" -#ifdef HAVE_AS_CFI_PSEUDO_OP +#if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__GCC_HAVE_DWARF2_CFI_ASM) #define cfi_startproc .cfi_startproc #define cfi_endproc .cfi_endproc @@ -50,4 +50,4 @@ #define cfi_restore(r) #define cfi_undefined(r) -#endif /* HAVE_AS_CFI_PSEUDO_OP */ +#endif /* HAVE_AS_CFI_PSEUDO_OP && __GCC_HAVE_DWARF2_CFI_ASM */ diff --git a/gcc-4.8/libitm/config/linux/futex_bits.h b/gcc-4.8/libitm/config/linux/futex_bits.h index 44f89aae2..fd79652e3 100644 --- a/gcc-4.8/libitm/config/linux/futex_bits.h +++ b/gcc-4.8/libitm/config/linux/futex_bits.h @@ -31,9 +31,13 @@ #include <unistd.h> #include <sys/syscall.h> +#include <errno.h> static inline long sys_futex0 (std::atomic<int> *addr, long op, long val) { - return syscall (SYS_futex, (int*) addr, op, val, 0); + long res = syscall (SYS_futex, (int*) addr, op, val, 0); + if (__builtin_expect (res == -1, 0)) + return -errno; + return res; } diff --git a/gcc-4.8/libitm/config/powerpc/sjlj.S b/gcc-4.8/libitm/config/powerpc/sjlj.S index 1f4a100f9..4a0b43dbb 100644 --- a/gcc-4.8/libitm/config/powerpc/sjlj.S +++ b/gcc-4.8/libitm/config/powerpc/sjlj.S @@ -26,7 +26,26 @@ #include "asmcfi.h" -#if defined(__powerpc64__) && defined(__ELF__) +#if defined(__powerpc64__) && _CALL_ELF == 2 +.macro FUNC name + .globl \name + .type \name, @function +\name: +0: addis 2,12,(.TOC.-0b)@ha + addi 2,2,(.TOC.-0b)@l + .localentry \name, . - \name +.endm +.macro END name + .size \name, . - \name +.endm +.macro HIDDEN name + .hidden \name +.endm +.macro CALL name + bl \name + nop +.endm +#elif defined(__powerpc64__) && defined(__ELF__) .macro FUNC name .globl \name, .\name .section ".opd","aw" @@ -117,6 +136,9 @@ _$0: #if defined(_CALL_AIXDESC) # define BASE 6*WS # define LR_SAVE 2*WS +#elif _CALL_ELF == 2 +# define BASE 6*WS +# define LR_SAVE 2*WS #elif defined(_CALL_SYSV) # define BASE 2*WS # define LR_SAVE 1*WS diff --git a/gcc-4.8/libitm/config/powerpc/target.h b/gcc-4.8/libitm/config/powerpc/target.h index 67c021884..cf01a5724 100644 --- a/gcc-4.8/libitm/config/powerpc/target.h +++ b/gcc-4.8/libitm/config/powerpc/target.h @@ -22,6 +22,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ +#ifdef HAVE_SYS_AUXV_H +#include <sys/auxv.h> +#endif + namespace GTM HIDDEN { typedef int v128 __attribute__((vector_size(16), may_alias, aligned(16))); @@ -55,4 +59,82 @@ cpu_relax (void) __asm volatile ("" : : : "memory"); } +// Use HTM if it is supported by the system. +// See gtm_thread::begin_transaction for how these functions are used. +#if defined (__linux__) \ + && defined (HAVE_AS_HTM) \ + && defined (HAVE_GETAUXVAL) \ + && defined (AT_HWCAP2) \ + && defined (PPC_FEATURE2_HAS_HTM) + +#include <htmintrin.h> + +#define USE_HTM_FASTPATH + +#define _TBEGIN_STARTED 0 +#define _TBEGIN_INDETERMINATE 1 +#define _TBEGIN_PERSISTENT 2 + +/* Number of retries for transient failures. */ +#define _HTM_RETRIES 10 + +static inline bool +htm_available (void) +{ + return (getauxval (AT_HWCAP2) & PPC_FEATURE2_HAS_HTM) ? true : false; +} + +static inline uint32_t +htm_init (void) +{ + // Maximum number of times we try to execute a transaction + // as a HW transaction. + return htm_available () ? _HTM_RETRIES : 0; +} + +static inline uint32_t +htm_begin (void) +{ + if (__builtin_expect (__builtin_tbegin (0), 1)) + return _TBEGIN_STARTED; + + if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ())) + return _TBEGIN_PERSISTENT; + + return _TBEGIN_INDETERMINATE; +} + +static inline bool +htm_begin_success (uint32_t begin_ret) +{ + return begin_ret == _TBEGIN_STARTED; +} + +static inline void +htm_commit (void) +{ + __builtin_tend (0); +} + +static inline void +htm_abort (void) +{ + __builtin_tabort (0); +} + +static inline bool +htm_abort_should_retry (uint32_t begin_ret) +{ + return begin_ret != _TBEGIN_PERSISTENT; +} + +/* Returns true iff a hardware transaction is currently being executed. */ +static inline bool +htm_transaction_active (void) +{ + return (_HTM_STATE (__builtin_ttest ()) == _HTM_TRANSACTIONAL); +} + +#endif + } // namespace GTM diff --git a/gcc-4.8/libitm/config/x86/target.h b/gcc-4.8/libitm/config/x86/target.h index 77b627f95..063c09ed9 100644 --- a/gcc-4.8/libitm/config/x86/target.h +++ b/gcc-4.8/libitm/config/x86/target.h @@ -125,6 +125,13 @@ htm_abort_should_retry (uint32_t begin_ret) { return begin_ret & _XABORT_RETRY; } + +/* Returns true iff a hardware transaction is currently being executed. */ +static inline bool +htm_transaction_active () +{ + return _xtest() != 0; +} #endif diff --git a/gcc-4.8/libitm/configure b/gcc-4.8/libitm/configure index 7635a4712..031c19ce3 100644 --- a/gcc-4.8/libitm/configure +++ b/gcc-4.8/libitm/configure @@ -7270,7 +7270,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -7295,7 +7295,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -7314,7 +7317,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -11779,7 +11785,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11782 "configure" +#line 11788 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11885,7 +11891,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11888 "configure" +#line 11894 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -17362,6 +17368,43 @@ $as_echo "#define HAVE_AS_RTM 1" >>confdefs.h fi ;; +esac + +case "${target_cpu}" in +powerpc*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler supports HTM" >&5 +$as_echo_n "checking if the assembler supports HTM... " >&6; } +if test "${libitm_cv_as_htm+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +asm("tbegin. 0; tend. 0"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + libitm_cv_as_htm=yes +else + libitm_cv_as_htm=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libitm_cv_as_htm" >&5 +$as_echo "$libitm_cv_as_htm" >&6; } + if test x$libitm_cv_as_htm = xyes; then + +$as_echo "#define HAVE_AS_HTM 1" >>confdefs.h + + fi + ;; s390*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler supports HTM" >&5 $as_echo_n "checking if the assembler supports HTM... " >&6; } @@ -17399,7 +17442,6 @@ $as_echo "#define HAVE_AS_HTM 1" >>confdefs.h fi ;; esac -LIBITM_CHECK_AS_HTM { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether weak refs work like ELF" >&5 diff --git a/gcc-4.8/libitm/configure.tgt b/gcc-4.8/libitm/configure.tgt index a20b410e0..507845597 100644 --- a/gcc-4.8/libitm/configure.tgt +++ b/gcc-4.8/libitm/configure.tgt @@ -47,7 +47,10 @@ fi # work out any special compilation flags as necessary. case "${target_cpu}" in alpha*) ARCH=alpha ;; - rs6000 | powerpc*) ARCH=powerpc ;; + rs6000 | powerpc*) + XCFLAGS="${XCFLAGS} -mhtm" + ARCH=powerpc + ;; arm*) ARCH=arm ;; diff --git a/gcc-4.8/libitm/libitm.info b/gcc-4.8/libitm/libitm.info index 9429feda4..0c8d5a941 100644 --- a/gcc-4.8/libitm/libitm.info +++ b/gcc-4.8/libitm/libitm.info @@ -1,5 +1,5 @@ -This is libitm.info, produced by makeinfo version 4.13 from -/d/gcc-4.8.1/gcc-4.8.1/libitm/libitm.texi. +This is libitm.info, produced by makeinfo version 4.12 from +/space/rguenther/gcc-4.8.3/gcc-4.8.3/libitm/libitm.texi. Copyright (C) 2011-2013 Free Software Foundation, Inc. @@ -33,7 +33,7 @@ Introduction ************ This manual documents the usage and internals of libitm, the GNU -Transactional Memory Library. It provides transaction support for +Transactional Memory Library. It provides transaction support for accesses to a process' memory, enabling easy-to-use synchronization of accesses to shared memory by several threads. @@ -56,7 +56,7 @@ File: libitm.info, Node: Enabling libitm, Next: C/C++ Language Constructs for ***************** To activate support for TM in C/C++, the compile-time flag `-fgnu-tm' -must be specified. This enables TM language-level constructs such as +must be specified. This enables TM language-level constructs such as transaction statements (e.g., `__transaction_atomic', *note C/C++ Language Constructs for TM:: for details). @@ -67,7 +67,7 @@ File: libitm.info, Node: C/C++ Language Constructs for TM, Next: The libitm AB ********************************** Transactions are supported in C++ and C in the form of transaction -statements, transaction expressions, and function transactions. In the +statements, transaction expressions, and function transactions. In the following example, both `a' and `b' will be read and the difference will be written to `c', all atomically and isolated from other transactions: @@ -87,10 +87,10 @@ Constructs for C++ (v1.1) of transactions. The precise semantics of transactions are defined in terms of the -C++11/C11 memory model (see the specification). Roughly, transactions +C++11/C11 memory model (see the specification). Roughly, transactions provide synchronization guarantees that are similar to what would be guaranteed when using a single global lock as a guard for all -transactions. Note that like other synchronization constructs in C/C++, +transactions. Note that like other synchronization constructs in C/C++, transactions rely on a data-race-free program (e.g., a nontransactional write that is concurrent with a transactional read to the same memory location is a data race). @@ -133,14 +133,14 @@ the structure of this specification. ---------------------------- The memory locations accessed with transactional loads and stores and -the memory locations whose values are logged must not overlap. This +the memory locations whose values are logged must not overlap. This required separation only extends to the scope of the execution of one transaction including all the executions of all nested transactions. The compiler must be consistent (within the scope of a single transaction) about which memory locations are shared and which are not shared with other threads (i.e., data must be accessed either -transactionally or nontransactionally). Otherwise, non-write-through TM +transactionally or nontransactionally). Otherwise, non-write-through TM algorithms would not work. For memory locations on the stack, this requirement extends to only @@ -220,7 +220,7 @@ machine. point register save/restore is not necessary for any target machine. `undoLogCode' is not supported and a fatal runtime error will be -raised if this bit is set. It is not properly defined in the ABI why +raised if this bit is set. It is not properly defined in the ABI why barriers other than undo logging are not present; Are they not necessary (e.g., a transaction operating purely on thread-local data) or have they been omitted by the compiler because it thinks that some @@ -258,7 +258,7 @@ used. `_ITM_rollbackTransaction' is not supported. `_ITM_abortTransaction' is supported but the abort reasons `exceptionBlockAbort', `TMConflict', and `userRetry' are not supported. There are no exception blocks in -general, so the related cases also do not have to be considered. To +general, so the related cases also do not have to be considered. To encode `__transaction_cancel [[outer]]', compilers must set the new `outerAbort' bit (`0x10') additionally to the `userAbort' bit in the abort reason. @@ -266,12 +266,12 @@ abort reason. 3.5.9 Committing a transaction ------------------------------ -The exception handling (EH) scheme is different. The Intel ABI requires +The exception handling (EH) scheme is different. The Intel ABI requires the `_ITM_tryCommitTransaction' function that will return even when the commit failed and will have to be matched with calls to either `_ITM_abortTransaction' or `_ITM_commitTransaction'. In contrast, gcc relies on transactional wrappers for the functions of the Exception -Handling ABI and on one additional commit function (shown below). This +Handling ABI and on one additional commit function (shown below). This allows the TM to keep track of EH internally and thus it does not have to embed the cleanup of EH state into the existing EH code in the program. `_ITM_tryCommitTransaction' is not supported. @@ -364,11 +364,11 @@ tuning output, but this output is not part of the ABI nor further defined by it. `_ITM_dropReferences' is not supported currently because its -semantics and the intention behind it is not entirely clear. The +semantics and the intention behind it is not entirely clear. The specification suggests that this function is necessary because of certain orderings of data transfer undos and the releasing of memory -regions (i.e., privatization). However, this ordering is never defined, -nor is the ordering of dropping references w.r.t. other events. +regions (i.e., privatization). However, this ordering is never defined, +nor is the ordering of dropping references w.r.t. other events. 3.5.18 [New] Transactional indirect calls ----------------------------------------- @@ -404,7 +404,7 @@ indirect calls in transactions: void *_ITM_getTMCloneSafe (void *function) ITM_REGPARM; If there is a registered clone for supplied function, both will -return a pointer to the clone. If not, the first runtime function will +return a pointer to the clone. If not, the first runtime function will attempt to switch to serial-irrevocable mode and return the original pointer, whereas the second will raise a fatal runtime error. @@ -427,7 +427,7 @@ calls to the original functions with calls to the wrapper functions. 3.7 Sample code =============== -The code examples might not be correct w.r.t. the current version of +The code examples might not be correct w.r.t. the current version of the ABI, especially everything related to exception handling. 3.8 [New] Memory model @@ -441,8 +441,8 @@ the programming language (e.g., by the C++ TM specification). For example, if a transactional load is ordered before another load/store, then the TM runtime must also ensure this ordering when -accessing shared state. If not, this might break the kind of -publication safety used in the C++ TM specification. Likewise, the TM +accessing shared state. If not, this might break the kind of +publication safety used in the C++ TM specification. Likewise, the TM runtime must ensure privatization safety. @@ -471,7 +471,7 @@ serial mode. -------------------------- The state of TM methods does not change after construction, but they do -alter the state of transactions that use this method. However, because +alter the state of transactions that use this method. However, because per-transaction data gets used by several methods, `gtm_thread' is responsible for setting an initial state that is useful for all methods. After that, methods are responsible for resetting/clearing this state @@ -498,9 +498,9 @@ might not be supported in the future. 4.2 Nesting: flat vs. closed ============================ -We support two different kinds of nesting of transactions. In the case +We support two different kinds of nesting of transactions. In the case of _flat nesting_, the nesting structure is flattened and all nested -transactions are subsumed by the enclosing transaction. In contrast, +transactions are subsumed by the enclosing transaction. In contrast, with _closed nesting_, nested transactions that have not yet committed can be rolled back separately from the enclosing transactions; when they commit, they are subsumed by the enclosing transaction, and their @@ -523,11 +523,11 @@ transaction encounters data conflicts during optimistic execution). ======================= This section documents the locking scheme and rules for all uses of -locking in libitm. We have to support serial(-irrevocable) mode, which +locking in libitm. We have to support serial(-irrevocable) mode, which is implemented using a global lock as explained next (called the _serial lock_). To simplify the overall design, we use the same lock as catch-all locking mechanism for other infrequent tasks such as -(de)registering clone tables or threads. Besides the serial lock, there +(de)registering clone tables or threads. Besides the serial lock, there are _per-method-group locks_ that are managed by specific method groups (i.e., groups of similar TM concurrency control algorithms), and lock-like constructs for quiescence-based operations such as ensuring @@ -538,13 +538,13 @@ are either _active transactions_ that do not run in serial mode, _serial transactions_ (which (are about to) run in serial mode), and management tasks that do not execute within a transaction but have acquired the serial mode like a serial transaction would do (e.g., to be able to -register threads with libitm). Transactions become active as soon as +register threads with libitm). Transactions become active as soon as they have successfully used the serial lock to announce this globally -(*note Serial lock implementation: serial-lock-impl.). Likewise, +(*note Serial lock implementation: serial-lock-impl.). Likewise, transactions become serial transactions as soon as they have acquired the exclusive rights provided by the serial lock (i.e., serial mode, which also means that there are no other concurrent active or serial -transactions). Note that active transactions can become serial +transactions). Note that active transactions can become serial transactions when they enter serial mode during the runtime of the transaction. @@ -555,13 +555,13 @@ Application data is protected by the serial lock if there is a serial transaction and no concurrently running active transaction (i.e., non-serial). Otherwise, application data is protected by the currently selected method group, which might use per-method-group locks or other -mechanisms. Also note that application data that is about to be +mechanisms. Also note that application data that is about to be privatized might not be allowed to be accessed by nontransactional code until privatization safety has been ensured; the details of this are handled by the current method group. libitm-internal state is either protected by the serial lock or -accessed through custom concurrent code. The latter applies to the +accessed through custom concurrent code. The latter applies to the public/shared part of a transaction object and most typical method-group-specific state. @@ -572,12 +572,12 @@ method-group-specific state. * The current selection of which method group to use. - * Some method-group-specific data, or invariants of this data. For + * Some method-group-specific data, or invariants of this data. For example, resetting a method group to its initial state is handled by switching to the same method group, so the serial lock protects such resetting as well. In general, such state is immutable whenever there exists an active -(non-serial) transaction. If there is no active transaction, a serial +(non-serial) transaction. If there is no active transaction, a serial transaction (or a thread that is not currently executing a transaction but has acquired the serial lock) is allowed to modify this state (but must of course be careful to not surprise the current method group's @@ -587,9 +587,9 @@ implementation with such modifications). ---------------------------- To prevent deadlocks, locks acquisition must happen in a globally -agreed-upon order. Note that this applies to other forms of blocking +agreed-upon order. Note that this applies to other forms of blocking too, but does not necessarily apply to lock acquisitions that do not -block (e.g., trylock() calls that do not get retried forever). Note +block (e.g., trylock() calls that do not get retried forever). Note that serial transactions are never return back to active transactions until the transaction has committed. Likewise, active transactions stay active until they have committed. Per-method-group locks are @@ -608,7 +608,7 @@ typically also not released before commit. transaction that is trying that (the latter is ensured by the serial lock implementation. - * Method groups must prevent deadlocks on their locks. In + * Method groups must prevent deadlocks on their locks. In particular, they must also be prepared for another active transaction that has acquired method-group-specific locks but is blocked during an attempt to upgrade to being a serial @@ -619,7 +619,7 @@ typically also not released before commit. There is no single rule for per-method-group blocking because this -depends on when a TM method might acquire locks. If no active +depends on when a TM method might acquire locks. If no active transaction can upgrade to being a serial transaction after it has acquired per-method-group locks (e.g., when those locks are only acquired during an attempt to commit), then the TM method does not need @@ -641,25 +641,25 @@ per-method-group locks, then TM methods need to avoid those deadlocks: per-method-group lock before doing the wake-up, and only blocking on this lock using a futex if this bit is not group). - *TODO*: Can reuse serial lock for gl-*? And if we can, does it make -sense to introduce further complexity in the serial lock? For gl-*, we + *TODO*: Can reuse serial lock for gl-*? And if we can, does it make +sense to introduce further complexity in the serial lock? For gl-*, we can really only avoid an abort if we do -wb and -vbv. 4.3.3 Serial lock implementation -------------------------------- The serial lock implementation is optimized towards assuming that serial -transactions are infrequent and not the common case. However, the +transactions are infrequent and not the common case. However, the performance of entering serial mode can matter because when only few transactions are run concurrently or if there are few threads, then it can be efficient to run transactions serially. The serial lock is similar to a multi-reader-single-writer lock in that there can be several active transactions but only one serial -transaction. However, we do want to avoid contention (in the lock +transaction. However, we do want to avoid contention (in the lock implementation) between active transactions, so we split up the reader side of the lock into per-transaction flags that are true iff the -transaction is active. The exclusive writer side remains a shared +transaction is active. The exclusive writer side remains a shared single flag, which is acquired using a CAS, for example. On the fast-path, the serial lock then works similar to Dekker's algorithm but with several reader flags that a serial transaction would have to check. @@ -670,7 +670,7 @@ lock can modify this list). We want starvation-freedom for the serial lock to allow for using it to ensure progress for potentially starved transactions (*note Progress -Guarantees: progress-guarantees. for details). However, this is +Guarantees: progress-guarantees. for details). However, this is currently not enforced by the implementation of the serial lock. Here is pseudo-code for the read/write fast paths of acquiring the @@ -714,12 +714,12 @@ libitm has to consider the following cases of reentrancy: * Transaction calls either a transactional wrapper or safe code, which in turn starts a new transaction: It is not yet defined in - the specification whether this is allowed. Thus, it is undefined + the specification whether this is allowed. Thus, it is undefined whether libitm supports this. * Code that starts new transactions might be called from within any part of libitm: This kind of reentrancy would likely be rather - complex and can probably be avoided. Therefore, it is not + complex and can probably be avoided. Therefore, it is not supported. @@ -736,15 +736,15 @@ quiescence does not contribute to deadlocks. In method groups that need to ensure publication safety explicitly, active transactions maintain a flag or timestamp in the public/shared -part of the transaction descriptor. Before blocking, privatizers need +part of the transaction descriptor. Before blocking, privatizers need to let the other transactions know that they should wake up the privatizer. - *TODO* Ho to implement the waiters? Should those flags be -per-transaction or at a central place? We want to avoid one wake/wait + *TODO* Ho to implement the waiters? Should those flags be +per-transaction or at a central place? We want to avoid one wake/wait call per active transactions, so we might want to use either a tree or combining to reduce the syscall overhead, or rather spin for a long -amount of time instead of doing blocking. Also, it would be good if +amount of time instead of doing blocking. Also, it would be good if only the last transaction that the privatizer waits for would do the wake-up. @@ -752,7 +752,7 @@ wake-up. ------------------------- Transactions that do not make progress when using the current TM method -will eventually try to execute in serial mode. Thus, the serial lock's +will eventually try to execute in serial mode. Thus, the serial lock's progress guarantees determine the progress guarantees of the whole TM. Obviously, we at least need deadlock-freedom for the serial lock, but it would also be good to provide starvation-freedom (informally, all @@ -762,7 +762,7 @@ enough cycles). However, the scheduling of transactions (e.g., thread scheduling by the OS) also affects the handling of progress guarantees by the TM. First, the TM can only guarantee deadlock-freedom if threads do not get -stopped. Likewise, low-priority threads can starve if they do not get +stopped. Likewise, low-priority threads can starve if they do not get scheduled when other high-priority threads get those cycles instead. If all threads get scheduled eventually, correct lock @@ -779,7 +779,7 @@ efficient). higher runtime overhead, we focus on deadlock-freedom right now and assume that the threads will get scheduled eventually by the OS (but don't consider threads with different priorities). We should support -starvation-freedom for serial transactions in the future. Everything +starvation-freedom for serial transactions in the future. Everything beyond that is highly related to proper contention management across all of the TM (including with TM method to choose), and is future work. @@ -1194,7 +1194,7 @@ GNU Free Documentation License not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it. - 10. FUTURE REVISIONS OF THIS LICENSE + 10. FUTURE REVISIONS OF THIS LICENSE The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new @@ -1215,7 +1215,7 @@ GNU Free Documentation License proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Document. - 11. RELICENSING + 11. RELICENSING "Massive Multiauthor Collaboration Site" (or "MMC Site") means any World Wide Web server that publishes copyrightable works and also @@ -1262,7 +1262,7 @@ notices just after the title page: Free Documentation License''. If you have Invariant Sections, Front-Cover Texts and Back-Cover -Texts, replace the "with...Texts." line with this: +Texts, replace the "with...Texts." line with this: with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts @@ -1293,15 +1293,15 @@ Index Tag Table: -Node: Top1173 -Node: Enabling libitm2076 -Node: C/C++ Language Constructs for TM2470 -Node: The libitm ABI3950 -Ref: txn-code-properties7743 -Node: Internals18018 -Ref: serial-lock-impl28043 -Ref: progress-guarantees32793 -Node: GNU Free Documentation License35067 -Node: Index60208 +Node: Top1187 +Node: Enabling libitm2090 +Node: C/C++ Language Constructs for TM2484 +Node: The libitm ABI3964 +Ref: txn-code-properties7757 +Node: Internals18032 +Ref: serial-lock-impl28057 +Ref: progress-guarantees32807 +Node: GNU Free Documentation License35081 +Node: Index60222 End Tag Table diff --git a/gcc-4.8/libitm/query.cc b/gcc-4.8/libitm/query.cc index 5707321f6..39a35b3e3 100644 --- a/gcc-4.8/libitm/query.cc +++ b/gcc-4.8/libitm/query.cc @@ -43,6 +43,15 @@ _ITM_libraryVersion (void) _ITM_howExecuting ITM_REGPARM _ITM_inTransaction (void) { +#if defined(USE_HTM_FASTPATH) + // If we use the HTM fastpath, we cannot reliably detect whether we are + // in a transaction because this function can be called outside of + // a transaction and thus we can't deduce this by looking at just the serial + // lock. This function isn't used in practice currently, so the easiest + // way to handle it is to just abort. + if (htm_fastpath && htm_transaction_active()) + htm_abort(); +#endif struct gtm_thread *tx = gtm_thr(); if (tx && (tx->nesting > 0)) { @@ -58,6 +67,11 @@ _ITM_inTransaction (void) _ITM_transactionId_t ITM_REGPARM _ITM_getTransactionId (void) { +#if defined(USE_HTM_FASTPATH) + // See ITM_inTransaction. + if (htm_fastpath && htm_transaction_active()) + htm_abort(); +#endif struct gtm_thread *tx = gtm_thr(); return (tx && (tx->nesting > 0)) ? tx->id : _ITM_noTransactionId; } |