Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 5 Feb 2017 00:32:12 +0000 (UTC)
From:      Ruslan Bukin <br@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r313254 - head/sys/riscv/include
Message-ID:  <201702050032.v150WC0j065036@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: br
Date: Sun Feb  5 00:32:12 2017
New Revision: 313254
URL: https://svnweb.freebsd.org/changeset/base/313254

Log:
  Implement atomic_fcmpset_*() for RISC-V.
  
  Requested by: mjg
  Sponsored by:	DARPA, AFRL
  Differential Revision:	https://reviews.freebsd.org/D9447

Modified:
  head/sys/riscv/include/atomic.h

Modified: head/sys/riscv/include/atomic.h
==============================================================================
--- head/sys/riscv/include/atomic.h	Sat Feb  4 20:57:09 2017	(r313253)
+++ head/sys/riscv/include/atomic.h	Sun Feb  5 00:32:12 2017	(r313254)
@@ -120,6 +120,31 @@ atomic_cmpset_32(volatile uint32_t *p, u
 	return (!res);
 }
 
+static __inline int
+atomic_fcmpset_32(volatile uint32_t *p, uint32_t *cmpval, uint32_t newval)
+{
+	uint32_t tmp;
+	int res;
+
+	res = 0;
+
+	__asm __volatile(
+		"0:"
+			"li   %1, 1\n"		/* Preset to fail */
+			"lr.w %0, %2\n"		/* Load old value */
+			"bne  %0, %z4, 1f\n"	/* Compare */
+			"sc.w %1, %z5, %2\n"	/* Try to store new value */
+			"j 2f\n"
+		"1:"
+			"sw   %0, %3\n"		/* Save old value */
+		"2:"
+			: "=&r" (tmp), "=&r" (res), "+A" (*p), "+A" (*cmpval)
+			: "rJ" (*cmpval), "rJ" (newval)
+			: "memory");
+
+	return (!res);
+}
+
 static __inline uint32_t
 atomic_fetchadd_32(volatile uint32_t *p, uint32_t val)
 {
@@ -152,6 +177,7 @@ atomic_readandclear_32(volatile uint32_t
 #define	atomic_add_int		atomic_add_32
 #define	atomic_clear_int	atomic_clear_32
 #define	atomic_cmpset_int	atomic_cmpset_32
+#define	atomic_fcmpset_int	atomic_fcmpset_32
 #define	atomic_fetchadd_int	atomic_fetchadd_32
 #define	atomic_readandclear_int	atomic_readandclear_32
 #define	atomic_set_int		atomic_set_32
@@ -183,6 +209,27 @@ atomic_cmpset_rel_32(volatile uint32_t *
 	return (atomic_cmpset_32(p, cmpval, newval));
 }
 
+static __inline int
+atomic_fcmpset_acq_32(volatile uint32_t *p, uint32_t *cmpval, uint32_t newval)
+{
+	int res;
+
+	res = atomic_fcmpset_32(p, cmpval, newval);
+
+	fence();
+
+	return (res);
+}
+
+static __inline int
+atomic_fcmpset_rel_32(volatile uint32_t *p, uint32_t *cmpval, uint32_t newval)
+{
+
+	fence();
+
+	return (atomic_fcmpset_32(p, cmpval, newval));
+}
+
 static __inline uint32_t
 atomic_load_acq_32(volatile uint32_t *p)
 {
@@ -207,6 +254,7 @@ atomic_store_rel_32(volatile uint32_t *p
 #define	atomic_add_acq_int	atomic_add_acq_32
 #define	atomic_clear_acq_int	atomic_clear_acq_32
 #define	atomic_cmpset_acq_int	atomic_cmpset_acq_32
+#define	atomic_fcmpset_acq_int	atomic_fcmpset_acq_32
 #define	atomic_load_acq_int	atomic_load_acq_32
 #define	atomic_set_acq_int	atomic_set_acq_32
 #define	atomic_subtract_acq_int	atomic_subtract_acq_32
@@ -214,6 +262,7 @@ atomic_store_rel_32(volatile uint32_t *p
 #define	atomic_add_rel_int	atomic_add_rel_32
 #define	atomic_clear_rel_int	atomic_add_rel_32
 #define	atomic_cmpset_rel_int	atomic_cmpset_rel_32
+#define	atomic_fcmpset_rel_int	atomic_fcmpset_rel_32
 #define	atomic_set_rel_int	atomic_set_rel_32
 #define	atomic_subtract_rel_int	atomic_subtract_rel_32
 #define	atomic_store_rel_int	atomic_store_rel_32
@@ -281,6 +330,31 @@ atomic_cmpset_64(volatile uint64_t *p, u
 	return (!res);
 }
 
+static __inline int
+atomic_fcmpset_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval)
+{
+	uint64_t tmp;
+	int res;
+
+	res = 0;
+
+	__asm __volatile(
+		"0:"
+			"li   %1, 1\n"		/* Preset to fail */
+			"lr.d %0, %2\n"		/* Load old value */
+			"bne  %0, %z4, 1f\n"	/* Compare */
+			"sc.d %1, %z5, %2\n"	/* Try to store new value */
+			"j 2f\n"
+		"1:"
+			"sd   %0, %3\n"		/* Save old value */
+		"2:"
+			: "=&r" (tmp), "=&r" (res), "+A" (*p), "+A" (*cmpval)
+			: "rJ" (*cmpval), "rJ" (newval)
+			: "memory");
+
+	return (!res);
+}
+
 static __inline uint64_t
 atomic_fetchadd_64(volatile uint64_t *p, uint64_t val)
 {
@@ -339,6 +413,7 @@ atomic_swap_64(volatile uint64_t *p, uin
 #define	atomic_add_long			atomic_add_64
 #define	atomic_clear_long		atomic_clear_64
 #define	atomic_cmpset_long		atomic_cmpset_64
+#define	atomic_fcmpset_long		atomic_fcmpset_64
 #define	atomic_fetchadd_long		atomic_fetchadd_64
 #define	atomic_readandclear_long	atomic_readandclear_64
 #define	atomic_set_long			atomic_set_64
@@ -347,6 +422,7 @@ atomic_swap_64(volatile uint64_t *p, uin
 #define	atomic_add_ptr			atomic_add_64
 #define	atomic_clear_ptr		atomic_clear_64
 #define	atomic_cmpset_ptr		atomic_cmpset_64
+#define	atomic_fcmpset_ptr		atomic_fcmpset_64
 #define	atomic_fetchadd_ptr		atomic_fetchadd_64
 #define	atomic_readandclear_ptr		atomic_readandclear_64
 #define	atomic_set_ptr			atomic_set_64
@@ -378,6 +454,27 @@ atomic_cmpset_rel_64(volatile uint64_t *
 	return (atomic_cmpset_64(p, cmpval, newval));
 }
 
+static __inline int
+atomic_fcmpset_acq_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval)
+{
+	int res;
+
+	res = atomic_fcmpset_64(p, cmpval, newval);
+
+	fence();
+
+	return (res);
+}
+
+static __inline int
+atomic_fcmpset_rel_64(volatile uint64_t *p, uint64_t *cmpval, uint64_t newval)
+{
+
+	fence();
+
+	return (atomic_fcmpset_64(p, cmpval, newval));
+}
+
 static __inline uint64_t
 atomic_load_acq_64(volatile uint64_t *p)
 {
@@ -402,6 +499,7 @@ atomic_store_rel_64(volatile uint64_t *p
 #define	atomic_add_acq_long		atomic_add_acq_64
 #define	atomic_clear_acq_long		atomic_add_acq_64
 #define	atomic_cmpset_acq_long		atomic_cmpset_acq_64
+#define	atomic_fcmpset_acq_long		atomic_fcmpset_acq_64
 #define	atomic_load_acq_long		atomic_load_acq_64
 #define	atomic_set_acq_long		atomic_set_acq_64
 #define	atomic_subtract_acq_long	atomic_subtract_acq_64
@@ -409,6 +507,7 @@ atomic_store_rel_64(volatile uint64_t *p
 #define	atomic_add_acq_ptr		atomic_add_acq_64
 #define	atomic_clear_acq_ptr		atomic_add_acq_64
 #define	atomic_cmpset_acq_ptr		atomic_cmpset_acq_64
+#define	atomic_fcmpset_acq_ptr		atomic_fcmpset_acq_64
 #define	atomic_load_acq_ptr		atomic_load_acq_64
 #define	atomic_set_acq_ptr		atomic_set_acq_64
 #define	atomic_subtract_acq_ptr		atomic_subtract_acq_64
@@ -447,6 +546,7 @@ atomic_thread_fence_seq_cst(void)
 #define	atomic_add_rel_long		atomic_add_rel_64
 #define	atomic_clear_rel_long		atomic_clear_rel_64
 #define	atomic_cmpset_rel_long		atomic_cmpset_rel_64
+#define	atomic_fcmpset_rel_long		atomic_fcmpset_rel_64
 #define	atomic_set_rel_long		atomic_set_rel_64
 #define	atomic_subtract_rel_long	atomic_subtract_rel_64
 #define	atomic_store_rel_long		atomic_store_rel_64
@@ -454,6 +554,7 @@ atomic_thread_fence_seq_cst(void)
 #define	atomic_add_rel_ptr		atomic_add_rel_64
 #define	atomic_clear_rel_ptr		atomic_clear_rel_64
 #define	atomic_cmpset_rel_ptr		atomic_cmpset_rel_64
+#define	atomic_fcmpset_rel_ptr		atomic_fcmpset_rel_64
 #define	atomic_set_rel_ptr		atomic_set_rel_64
 #define	atomic_subtract_rel_ptr		atomic_subtract_rel_64
 #define	atomic_store_rel_ptr		atomic_store_rel_64



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201702050032.v150WC0j065036>