diff options
author | Stefan Liebler <stli@linux.vnet.ibm.com> | 2016-12-20 15:12:48 +0100 |
---|---|---|
committer | Stefan Liebler <stli@linux.vnet.ibm.com> | 2016-12-20 15:12:48 +0100 |
commit | 53c5c3d5ac238901c13f28a73ba05b0678094e80 (patch) | |
tree | c9419d79ec76ed267d8887cc2ea31c4ffada2610 /sysdeps/unix/sysv/linux/s390/elision-lock.c | |
parent | 8bfc4a2ab4bebdf86c151665aae8a266e2f18fb4 (diff) | |
download | glibc-53c5c3d5ac238901c13f28a73ba05b0678094e80.zip glibc-53c5c3d5ac238901c13f28a73ba05b0678094e80.tar.gz glibc-53c5c3d5ac238901c13f28a73ba05b0678094e80.tar.bz2 |
S390: Use new __libc_tbegin_retry macro in elision-lock.c.
This patch implements __libc_tbegin_retry macro which is equivalent to
gcc builtin __builtin_tbegin_retry, except the changes which were applied
to __libc_tbegin in the previous patch.
If tbegin aborts with _HTM_TBEGIN_TRANSIENT. Then this macros restores
the fpc, fprs and automatically retries up to retry_cnt tbegins.
Further saving of the state is omitted as it is already saved in the
first round. Before retrying a further transaction, the
transaction-abort-assist instruction is used to support the cpu.
This macro is now used in function __lll_lock_elision.
ChangeLog:
* sysdeps/unix/sysv/linux/s390/htm.h(__libc_tbegin_retry): New macro.
* sysdeps/unix/sysv/linux/s390/elision-lock.c (__lll_lock_elision):
Use __libc_tbegin_retry macro.
Diffstat (limited to 'sysdeps/unix/sysv/linux/s390/elision-lock.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/s390/elision-lock.c | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/sysdeps/unix/sysv/linux/s390/elision-lock.c b/sysdeps/unix/sysv/linux/s390/elision-lock.c index 48cc3db..3dd7fbc 100644 --- a/sysdeps/unix/sysv/linux/s390/elision-lock.c +++ b/sysdeps/unix/sysv/linux/s390/elision-lock.c @@ -60,17 +60,16 @@ __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private) goto use_lock; } - int try_tbegin; - for (try_tbegin = aconf.try_tbegin; - try_tbegin > 0; - try_tbegin--) + if (aconf.try_tbegin > 0) { - int status; - if (__builtin_expect - ((status = __libc_tbegin ((void *) 0)) == _HTM_TBEGIN_STARTED, 1)) + int status = __libc_tbegin_retry ((void *) 0, aconf.try_tbegin - 1); + if (__builtin_expect (status == _HTM_TBEGIN_STARTED, + _HTM_TBEGIN_STARTED)) { - if (*futex == 0) + if (__builtin_expect (*futex == 0, 1)) + /* Lock was free. Return to user code in a transaction. */ return 0; + /* Lock was busy. Fall back to normal locking. */ if (__builtin_expect (__libc_tx_nesting_depth (), 1)) { @@ -81,7 +80,6 @@ __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private) See above for why relaxed MO is sufficient. */ if (aconf.skip_lock_busy > 0) atomic_store_relaxed (adapt_count, aconf.skip_lock_busy); - goto use_lock; } else /* nesting depth is > 1 */ { @@ -99,28 +97,28 @@ __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private) __libc_tabort (_HTM_FIRST_USER_ABORT_CODE | 1); } } + else if (status != _HTM_TBEGIN_TRANSIENT) + { + /* A persistent abort (cc 1 or 3) indicates that a retry is + probably futile. Use the normal locking now and for the + next couple of calls. + Be careful to avoid writing to the lock. See above for why + relaxed MO is sufficient. */ + if (aconf.skip_lock_internal_abort > 0) + atomic_store_relaxed (adapt_count, + aconf.skip_lock_internal_abort); + } else { - if (status != _HTM_TBEGIN_TRANSIENT) - { - /* A persistent abort (cc 1 or 3) indicates that a retry is - probably futile. Use the normal locking now and for the - next couple of calls. - Be careful to avoid writing to the lock. See above for why - relaxed MO is sufficient. */ - if (aconf.skip_lock_internal_abort > 0) - atomic_store_relaxed (adapt_count, - aconf.skip_lock_internal_abort); - goto use_lock; - } + /* Same logic as above, but for for a number of temporary failures in + a row. */ + if (aconf.skip_lock_out_of_tbegin_retries > 0) + atomic_store_relaxed (adapt_count, + aconf.skip_lock_out_of_tbegin_retries); } } - /* Same logic as above, but for for a number of temporary failures in a - row. See above for why relaxed MO is sufficient. */ - if (aconf.skip_lock_out_of_tbegin_retries > 0 && aconf.try_tbegin > 0) - atomic_store_relaxed (adapt_count, aconf.skip_lock_out_of_tbegin_retries); - use_lock: + /* Use normal locking as fallback path if transaction does not succeed. */ return LLL_LOCK ((*futex), private); } |