svn commit: r353008 - head/sys/mips/include
Kyle Evans
kevans at FreeBSD.org
Wed Oct 2 15:13:41 UTC 2019
Author: kevans
Date: Wed Oct 2 15:13:40 2019
New Revision: 353008
URL: https://svnweb.freebsd.org/changeset/base/353008
Log:
mips: fcmpset: do not spin on sc failure
For ll/sc architectures, atomic(9) allows failure modes where *old == val
due to write failure and callers should compensate for this. Do not retry on
failure, just leave 0 in ret and fail the operation if we couldn't sc it.
This lets the caller determine if it should retry or not.
Reviewed by: kib
Looks ok: imp
Differential Revision: https://reviews.freebsd.org/D21836
Modified:
head/sys/mips/include/atomic.h
Modified: head/sys/mips/include/atomic.h
==============================================================================
--- head/sys/mips/include/atomic.h Wed Oct 2 13:46:40 2019 (r353007)
+++ head/sys/mips/include/atomic.h Wed Oct 2 15:13:40 2019 (r353008)
@@ -397,18 +397,25 @@ atomic_fcmpset_32(__volatile uint32_t *p, uint32_t *cm
{
int ret;
+ /*
+ * The following sequence (similar to that in atomic_fcmpset_64) will
+ * attempt to update the value of *p with newval if the comparison
+ * succeeds. Note that they'll exit regardless of whether the store
+ * actually succeeded, leaving *cmpval untouched. This is in line with
+ * the documentation of atomic_fcmpset_<type>() in atomic(9) for ll/sc
+ * architectures.
+ */
__asm __volatile (
- "1:\n\t"
"ll %0, %1\n\t" /* load old value */
- "bne %0, %4, 2f\n\t" /* compare */
+ "bne %0, %4, 1f\n\t" /* compare */
"move %0, %3\n\t" /* value to store */
"sc %0, %1\n\t" /* attempt to store */
- "beqz %0, 1b\n\t" /* if it failed, spin */
- "j 3f\n\t"
- "2:\n\t"
+ "j 2f\n\t" /* exit regardless of success */
+ "nop\n\t" /* avoid delay slot accident */
+ "1:\n\t"
"sw %0, %2\n\t" /* save old value */
"li %0, 0\n\t"
- "3:\n"
+ "2:\n"
: "=&r" (ret), "+m" (*p), "=m" (*cmpval)
: "r" (newval), "r" (*cmpval)
: "memory");
@@ -508,17 +515,16 @@ atomic_fcmpset_64(__volatile uint64_t *p, uint64_t *cm
int ret;
__asm __volatile (
- "1:\n\t"
"lld %0, %1\n\t" /* load old value */
- "bne %0, %4, 2f\n\t" /* compare */
+ "bne %0, %4, 1f\n\t" /* compare */
"move %0, %3\n\t" /* value to store */
"scd %0, %1\n\t" /* attempt to store */
- "beqz %0, 1b\n\t" /* if it failed, spin */
- "j 3f\n\t"
- "2:\n\t"
+ "j 2f\n\t" /* exit regardless of success */
+ "nop\n\t" /* avoid delay slot accident */
+ "1:\n\t"
"sd %0, %2\n\t" /* save old value */
"li %0, 0\n\t"
- "3:\n"
+ "2:\n"
: "=&r" (ret), "+m" (*p), "=m" (*cmpval)
: "r" (newval), "r" (*cmpval)
: "memory");
More information about the svn-src-all
mailing list