aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--NEWS2
-rw-r--r--sysdeps/powerpc/nptl/elide.h6
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/elision-lock.c15
4 files changed, 19 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index a392a75..0a70fee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2015-10-27 Paul E. Murphy <murphyp@linux.vnet.ibm.com>
+
+ [BZ #19174]
+ * sysdeps/powerpc/nptl/elide.h (__elide_lock): Fix usage of
+ .skip_lock_out_of_tbegin_retries.
+ * sysdeps/unix/sysv/linux/powerpc/elision-lock.c
+ (__lll_lock_elision): Likewise, and respect a value of
+ try_tbegin <= 0.
+
2015-10-27 Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
* elf/dl-support.c (_dl_aux_init): Added AT_PLATFORM to the case
diff --git a/NEWS b/NEWS
index 1122aff..5120ddc 100644
--- a/NEWS
+++ b/NEWS
@@ -21,7 +21,7 @@ Version 2.23
18970, 18977, 18980, 18981, 18982, 18985, 19003, 19007, 19012, 19016,
19018, 19032, 19046, 19049, 19050, 19059, 19071, 19074, 19076, 19077,
19078, 19079, 19085, 19086, 19088, 19094, 19095, 19124, 19125, 19129,
- 19134, 19137, 19156.
+ 19134, 19137, 19156, 19174.
* There is now a --disable-timezone-tools configure option for disabling the
building and installing of the timezone related utilities (zic, zdump, and
diff --git a/sysdeps/powerpc/nptl/elide.h b/sysdeps/powerpc/nptl/elide.h
index 12171f4..2e1e443 100644
--- a/sysdeps/powerpc/nptl/elide.h
+++ b/sysdeps/powerpc/nptl/elide.h
@@ -27,7 +27,7 @@
configurations. Returns true if the system should retry again or false
otherwise. */
static inline bool
-__get_new_count (uint8_t *adapt_count)
+__get_new_count (uint8_t *adapt_count, int attempt)
{
/* A persistent failure indicates that a retry will probably
result in another failure. Use normal locking now and
@@ -40,7 +40,7 @@ __get_new_count (uint8_t *adapt_count)
}
/* Same logic as above, but for a number of temporary failures in a
a row. */
- else if (__elision_aconf.skip_lock_out_of_tbegin_retries > 0
+ else if (attempt <= 1 && __elision_aconf.skip_lock_out_of_tbegin_retries > 0
&& __elision_aconf.try_tbegin > 0)
*adapt_count = __elision_aconf.skip_lock_out_of_tbegin_retries;
return true;
@@ -78,7 +78,7 @@ __get_new_count (uint8_t *adapt_count)
__builtin_tabort (_ABORT_LOCK_BUSY); \
} \
else \
- if (!__get_new_count(&adapt_count)) \
+ if (!__get_new_count (&adapt_count,i)) \
break; \
} \
ret; \
diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-lock.c b/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
index 3762732..4775fca 100644
--- a/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
+++ b/sysdeps/unix/sysv/linux/powerpc/elision-lock.c
@@ -50,8 +50,7 @@ __lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared)
goto use_lock;
}
- int try_begin = aconf.try_tbegin;
- while (1)
+ for (int i = aconf.try_tbegin; i > 0; i--)
{
if (__builtin_tbegin (0))
{
@@ -65,21 +64,19 @@ __lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared)
/* 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);
}