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