summaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/s390/elision-unlock.c
diff options
context:
space:
mode:
authorStefan Liebler <stli@linux.vnet.ibm.com>2017-01-20 09:53:04 +0100
committerStefan Liebler <stli@linux.vnet.ibm.com>2017-01-20 09:53:04 +0100
commit03b007771beb4dba3b16d6097a53bfa328a78efb (patch)
tree0c3a5e1b2fe7012e55534cbc997426d2aff1d8f6 /sysdeps/unix/sysv/linux/s390/elision-unlock.c
parent56009aa33c735d66f19d8382b6ef7c6addc24ec0 (diff)
downloadglibc-03b007771beb4dba3b16d6097a53bfa328a78efb.tar
glibc-03b007771beb4dba3b16d6097a53bfa328a78efb.tar.gz
glibc-03b007771beb4dba3b16d6097a53bfa328a78efb.tar.bz2
glibc-03b007771beb4dba3b16d6097a53bfa328a78efb.zip
S390: Adjust lock elision code after review.
This patch adjusts s390 specific lock elision code after review of the following patches: -S390: Use own tbegin macro instead of __builtin_tbegin. (8bfc4a2ab4bebdf86c151665aae8a266e2f18fb4) -S390: Use new __libc_tbegin_retry macro in elision-lock.c. (53c5c3d5ac238901c13f28a73ba05b0678094e80) -S390: Optimize lock-elision by decrementing adapt_count at unlock. (dd037fb3df286b7c2d0b0c6f8d02a2dd8a8e8a08) The futex value is not tested before starting a transaction, __glibc_likely is used instead of __builtin_expect and comments are adjusted. ChangeLog: * sysdeps/unix/sysv/linux/s390/htm.h: Adjust comments. * sysdeps/unix/sysv/linux/s390/elision-unlock.c: Likewise. * sysdeps/unix/sysv/linux/s390/elision-lock.c: Adjust comments. (__lll_lock_elision): Do not test futex before starting a transaction. Use __glibc_likely instead of __builtin_expect. * sysdeps/unix/sysv/linux/s390/elision-trylock.c: Adjust comments. (__lll_trylock_elision): Do not test futex before starting a transaction. Use __glibc_likely instead of __builtin_expect.
Diffstat (limited to 'sysdeps/unix/sysv/linux/s390/elision-unlock.c')
-rw-r--r--sysdeps/unix/sysv/linux/s390/elision-unlock.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/sysdeps/unix/sysv/linux/s390/elision-unlock.c b/sysdeps/unix/sysv/linux/s390/elision-unlock.c
index d9205faf52..c062d71b77 100644
--- a/sysdeps/unix/sysv/linux/s390/elision-unlock.c
+++ b/sysdeps/unix/sysv/linux/s390/elision-unlock.c
@@ -26,8 +26,12 @@ __lll_unlock_elision(int *futex, short *adapt_count, int private)
/* If the lock is free, we elided the lock earlier. This does not
necessarily mean that we are in a transaction, because the user code may
have closed the transaction, but that is impossible to detect reliably.
- Relaxed MO access to futex is sufficient as we only need a hint, if we
- started a transaction or acquired the futex in e.g. elision-lock.c. */
+ Relaxed MO access to futex is sufficient because a correct program
+ will only release a lock it has acquired; therefore, it must either
+ changed the futex word's value to something !=0 or it must have used
+ elision; these are actions by the same thread, so these actions are
+ sequenced-before the relaxed load (and thus also happens-before the
+ relaxed load). Therefore, relaxed MO is sufficient. */
if (atomic_load_relaxed (futex) == 0)
{
__libc_tend ();
@@ -36,17 +40,17 @@ __lll_unlock_elision(int *futex, short *adapt_count, int private)
{
/* Update the adapt_count while unlocking before completing the critical
section. adapt_count is accessed concurrently outside of a
- transaction or an aquired lock e.g. in elision-lock.c so we need to use
- atomic accesses. However, the value of adapt_count is just a hint, so
- relaxed MO accesses are sufficient.
+ transaction or a critical section (e.g. in elision-lock.c). So we need
+ to use atomic accesses. However, the value of adapt_count is just a
+ hint, so relaxed MO accesses are sufficient.
If adapt_count would be decremented while locking, multiple
- CPUs trying to lock the locked mutex will decrement adapt_count to
+ CPUs, trying to lock the acquired mutex, will decrement adapt_count to
zero and another CPU will try to start a transaction, which will be
immediately aborted as the mutex is locked.
- If adapt_count would be decremented while unlocking after completing
- the critical section, possible waiters will be waked up before
- decrementing the adapt_count. Those waked up waiters could have
- destroyed and freed this mutex! */
+ The update of adapt_count is done before releasing the lock as POSIX'
+ mutex destruction requirements disallow accesses to the mutex after it
+ has been released and thus could have been acquired or destroyed by
+ another thread. */
short adapt_count_val = atomic_load_relaxed (adapt_count);
if (adapt_count_val > 0)
atomic_store_relaxed (adapt_count, adapt_count_val - 1);