summaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc/elision-lock.c')
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/elision-lock.c43
1 files changed, 9 insertions, 34 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-lock.c b/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
index 7f9bcc2bf1..dd1e4c3b17 100644
--- a/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
+++ b/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
@@ -1,5 +1,5 @@
/* elision-lock.c: Elided pthread mutex lock.
- Copyright (C) 2015 Free Software Foundation, Inc.
+ Copyright (C) 2015-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -23,27 +23,6 @@
#include <elision-conf.h>
#include "htm.h"
-/* PowerISA 2.0.7 Section B.5.5 defines isync to be insufficient as a
- barrier in acquire mechanism for HTM operations, a strong 'sync' is
- required. */
-#undef __arch_compare_and_exchange_val_32_acq
-#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
- ({ \
- __typeof (*(mem)) __tmp; \
- __typeof (mem) __memp = (mem); \
- __asm __volatile ( \
- "1: lwarx %0,0,%1" MUTEX_HINT_ACQ "\n" \
- " cmpw %0,%2\n" \
- " bne 2f\n" \
- " stwcx. %3,0,%1\n" \
- " bne- 1b\n" \
- "2: sync" \
- : "=&r" (__tmp) \
- : "b" (__memp), "r" (oldval), "r" (newval) \
- : "cr0", "memory"); \
- __tmp; \
- })
-
#if !defined(LLL_LOCK) && !defined(EXTRAARG)
/* Make sure the configuration code is always linked in for static
libraries. */
@@ -68,40 +47,36 @@ __lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared)
{
if (*adapt_count > 0)
{
- (*adapt_count)--;
goto use_lock;
}
- int try_begin = aconf.try_tbegin;
- while (1)
+ for (int i = aconf.try_tbegin; i > 0; i--)
{
- if (__builtin_tbegin (0))
+ if (__libc_tbegin (0))
{
if (*lock == 0)
return 0;
/* Lock was busy. Fall back to normal locking. */
- __builtin_tabort (_ABORT_LOCK_BUSY);
+ __libc_tabort (_ABORT_LOCK_BUSY);
}
else
{
/* A persistent failure indicates that a retry will probably
result in another failure. Use normal locking now and
for the next couple of calls. */
- if (try_begin-- <= 0
- || _TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
+ if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
{
if (aconf.skip_lock_internal_abort > 0)
*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. */
- else if (aconf.skip_lock_out_of_tbegin_retries > 0
- && aconf.try_tbegin > 0)
- *adapt_count = aconf.skip_lock_out_of_tbegin_retries;
}
}
+ /* Fall back to locks for a bit if retries have been exhausted */
+ if (aconf.try_tbegin > 0 && aconf.skip_lock_out_of_tbegin_retries > 0)
+ *adapt_count = aconf.skip_lock_out_of_tbegin_retries;
+
use_lock:
return LLL_LOCK ((*lock), pshared);
}