svn commit: r329383 - in stable/11: share/man/man9 sys/amd64/include sys/i386/include
Mark Johnston
markj at FreeBSD.org
Fri Feb 16 16:41:20 UTC 2018
Author: markj
Date: Fri Feb 16 16:41:19 2018
New Revision: 329383
URL: https://svnweb.freebsd.org/changeset/base/329383
Log:
MFC r315718, r316031:
Add support for 8- and 16-bit atomic_(f)cmpset to x86.
Modified:
stable/11/share/man/man9/atomic.9
stable/11/sys/amd64/include/atomic.h
stable/11/sys/i386/include/atomic.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/share/man/man9/atomic.9
==============================================================================
--- stable/11/share/man/man9/atomic.9 Fri Feb 16 16:22:54 2018 (r329382)
+++ stable/11/share/man/man9/atomic.9 Fri Feb 16 16:41:19 2018 (r329383)
@@ -328,9 +328,9 @@ if (*dst == old) {
.Ed
.El
.Pp
-The
+Some architectures do not implement the
.Fn atomic_cmpset
-functions are not implemented for the types
+functions for the types
.Dq Li char ,
.Dq Li short ,
.Dq Li 8 ,
@@ -367,9 +367,9 @@ function also returns
despite
.Dl *old == *dst .
.Pp
-The
+Some architectures do not implement the
.Fn atomic_fcmpset
-functions are not implemented for the types
+functions for the types
.Dq Li char ,
.Dq Li short ,
.Dq Li 8 ,
Modified: stable/11/sys/amd64/include/atomic.h
==============================================================================
--- stable/11/sys/amd64/include/atomic.h Fri Feb 16 16:22:54 2018 (r329382)
+++ stable/11/sys/amd64/include/atomic.h Fri Feb 16 16:41:19 2018 (r329383)
@@ -99,8 +99,13 @@
void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v); \
void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
+int atomic_cmpset_char(volatile u_char *dst, u_char expect, u_char src);
+int atomic_cmpset_short(volatile u_short *dst, u_short expect, u_short src);
int atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src);
int atomic_cmpset_long(volatile u_long *dst, u_long expect, u_long src);
+int atomic_fcmpset_char(volatile u_char *dst, u_char *expect, u_char src);
+int atomic_fcmpset_short(volatile u_short *dst, u_short *expect,
+ u_short src);
int atomic_fcmpset_int(volatile u_int *dst, u_int *expect, u_int src);
int atomic_fcmpset_long(volatile u_long *dst, u_long *expect, u_long src);
u_int atomic_fetchadd_int(volatile u_int *p, u_int v);
@@ -157,85 +162,62 @@ atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##
struct __hack
/*
- * Atomic compare and set, used by the mutex functions
+ * Atomic compare and set, used by the mutex functions.
*
- * if (*dst == expect) *dst = src (all 32 bit words)
+ * cmpset:
+ * if (*dst == expect)
+ * *dst = src
*
- * Returns 0 on failure, non-zero on success
+ * fcmpset:
+ * if (*dst == *expect)
+ * *dst = src
+ * else
+ * *expect = *dst
+ *
+ * Returns 0 on failure, non-zero on success.
*/
-
-static __inline int
-atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src)
-{
- u_char res;
-
- __asm __volatile(
- " " MPLOCKED " "
- " cmpxchgl %3,%1 ; "
- " sete %0 ; "
- "# atomic_cmpset_int"
- : "=q" (res), /* 0 */
- "+m" (*dst), /* 1 */
- "+a" (expect) /* 2 */
- : "r" (src) /* 3 */
- : "memory", "cc");
- return (res);
+#define ATOMIC_CMPSET(TYPE) \
+static __inline int \
+atomic_cmpset_##TYPE(volatile u_##TYPE *dst, u_##TYPE expect, u_##TYPE src) \
+{ \
+ u_char res; \
+ \
+ __asm __volatile( \
+ " " MPLOCKED " " \
+ " cmpxchg %3,%1 ; " \
+ " sete %0 ; " \
+ "# atomic_cmpset_" #TYPE " " \
+ : "=q" (res), /* 0 */ \
+ "+m" (*dst), /* 1 */ \
+ "+a" (expect) /* 2 */ \
+ : "r" (src) /* 3 */ \
+ : "memory", "cc"); \
+ return (res); \
+} \
+ \
+static __inline int \
+atomic_fcmpset_##TYPE(volatile u_##TYPE *dst, u_##TYPE *expect, u_##TYPE src) \
+{ \
+ u_char res; \
+ \
+ __asm __volatile( \
+ " " MPLOCKED " " \
+ " cmpxchg %3,%1 ; " \
+ " sete %0 ; " \
+ "# atomic_fcmpset_" #TYPE " " \
+ : "=q" (res), /* 0 */ \
+ "+m" (*dst), /* 1 */ \
+ "+a" (*expect) /* 2 */ \
+ : "r" (src) /* 3 */ \
+ : "memory", "cc"); \
+ return (res); \
}
-static __inline int
-atomic_cmpset_long(volatile u_long *dst, u_long expect, u_long src)
-{
- u_char res;
+ATOMIC_CMPSET(char);
+ATOMIC_CMPSET(short);
+ATOMIC_CMPSET(int);
+ATOMIC_CMPSET(long);
- __asm __volatile(
- " " MPLOCKED " "
- " cmpxchgq %3,%1 ; "
- " sete %0 ; "
- "# atomic_cmpset_long"
- : "=q" (res), /* 0 */
- "+m" (*dst), /* 1 */
- "+a" (expect) /* 2 */
- : "r" (src) /* 3 */
- : "memory", "cc");
- return (res);
-}
-
-static __inline int
-atomic_fcmpset_int(volatile u_int *dst, u_int *expect, u_int src)
-{
- u_char res;
-
- __asm __volatile(
- " " MPLOCKED " "
- " cmpxchgl %3,%1 ; "
- " sete %0 ; "
- "# atomic_fcmpset_int"
- : "=r" (res), /* 0 */
- "+m" (*dst), /* 1 */
- "+a" (*expect) /* 2 */
- : "r" (src) /* 3 */
- : "memory", "cc");
- return (res);
-}
-
-static __inline int
-atomic_fcmpset_long(volatile u_long *dst, u_long *expect, u_long src)
-{
- u_char res;
-
- __asm __volatile(
- " " MPLOCKED " "
- " cmpxchgq %3,%1 ; "
- " sete %0 ; "
- "# atomic_fcmpset_long"
- : "=r" (res), /* 0 */
- "+m" (*dst), /* 1 */
- "+a" (*expect) /* 2 */
- : "r" (src) /* 3 */
- : "memory", "cc");
- return (res);
-}
-
/*
* Atomically add the value of v to the integer pointed to by p and return
* the previous value of *p.
@@ -524,6 +506,10 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_add_rel_char atomic_add_barr_char
#define atomic_subtract_acq_char atomic_subtract_barr_char
#define atomic_subtract_rel_char atomic_subtract_barr_char
+#define atomic_cmpset_acq_char atomic_cmpset_char
+#define atomic_cmpset_rel_char atomic_cmpset_char
+#define atomic_fcmpset_acq_char atomic_fcmpset_char
+#define atomic_fcmpset_rel_char atomic_fcmpset_char
#define atomic_set_acq_short atomic_set_barr_short
#define atomic_set_rel_short atomic_set_barr_short
@@ -533,6 +519,10 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_add_rel_short atomic_add_barr_short
#define atomic_subtract_acq_short atomic_subtract_barr_short
#define atomic_subtract_rel_short atomic_subtract_barr_short
+#define atomic_cmpset_acq_short atomic_cmpset_short
+#define atomic_cmpset_rel_short atomic_cmpset_short
+#define atomic_fcmpset_acq_short atomic_fcmpset_short
+#define atomic_fcmpset_rel_short atomic_fcmpset_short
#define atomic_set_acq_int atomic_set_barr_int
#define atomic_set_rel_int atomic_set_barr_int
@@ -544,8 +534,8 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_subtract_rel_int atomic_subtract_barr_int
#define atomic_cmpset_acq_int atomic_cmpset_int
#define atomic_cmpset_rel_int atomic_cmpset_int
-#define atomic_fcmpset_acq_int atomic_fcmpset_int
-#define atomic_fcmpset_rel_int atomic_fcmpset_int
+#define atomic_fcmpset_acq_int atomic_fcmpset_int
+#define atomic_fcmpset_rel_int atomic_fcmpset_int
#define atomic_set_acq_long atomic_set_barr_long
#define atomic_set_rel_long atomic_set_barr_long
@@ -557,8 +547,8 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_subtract_rel_long atomic_subtract_barr_long
#define atomic_cmpset_acq_long atomic_cmpset_long
#define atomic_cmpset_rel_long atomic_cmpset_long
-#define atomic_fcmpset_acq_long atomic_fcmpset_long
-#define atomic_fcmpset_rel_long atomic_fcmpset_long
+#define atomic_fcmpset_acq_long atomic_fcmpset_long
+#define atomic_fcmpset_rel_long atomic_fcmpset_long
#define atomic_readandclear_int(p) atomic_swap_int(p, 0)
#define atomic_readandclear_long(p) atomic_swap_long(p, 0)
@@ -578,6 +568,12 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_subtract_rel_8 atomic_subtract_rel_char
#define atomic_load_acq_8 atomic_load_acq_char
#define atomic_store_rel_8 atomic_store_rel_char
+#define atomic_cmpset_8 atomic_cmpset_char
+#define atomic_cmpset_acq_8 atomic_cmpset_acq_char
+#define atomic_cmpset_rel_8 atomic_cmpset_rel_char
+#define atomic_fcmpset_8 atomic_fcmpset_char
+#define atomic_fcmpset_acq_8 atomic_fcmpset_acq_char
+#define atomic_fcmpset_rel_8 atomic_fcmpset_rel_char
/* Operations on 16-bit words. */
#define atomic_set_16 atomic_set_short
@@ -594,6 +590,12 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_subtract_rel_16 atomic_subtract_rel_short
#define atomic_load_acq_16 atomic_load_acq_short
#define atomic_store_rel_16 atomic_store_rel_short
+#define atomic_cmpset_16 atomic_cmpset_short
+#define atomic_cmpset_acq_16 atomic_cmpset_acq_short
+#define atomic_cmpset_rel_16 atomic_cmpset_rel_short
+#define atomic_fcmpset_16 atomic_fcmpset_short
+#define atomic_fcmpset_acq_16 atomic_fcmpset_acq_short
+#define atomic_fcmpset_rel_16 atomic_fcmpset_rel_short
/* Operations on 32-bit double words. */
#define atomic_set_32 atomic_set_int
Modified: stable/11/sys/i386/include/atomic.h
==============================================================================
--- stable/11/sys/i386/include/atomic.h Fri Feb 16 16:22:54 2018 (r329382)
+++ stable/11/sys/i386/include/atomic.h Fri Feb 16 16:41:19 2018 (r329383)
@@ -107,7 +107,12 @@ __mbu(void)
void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v); \
void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
+int atomic_cmpset_char(volatile u_char *dst, u_char expect, u_char src);
+int atomic_cmpset_short(volatile u_short *dst, u_short expect, u_short src);
int atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src);
+int atomic_fcmpset_char(volatile u_char *dst, u_char *expect, u_char src);
+int atomic_fcmpset_short(volatile u_short *dst, u_short *expect,
+ u_short src);
int atomic_fcmpset_int(volatile u_int *dst, u_int *expect, u_int src);
u_int atomic_fetchadd_int(volatile u_int *p, u_int v);
int atomic_testandset_int(volatile u_int *p, u_int v);
@@ -166,49 +171,61 @@ atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##
struct __hack
/*
- * Atomic compare and set, used by the mutex functions
+ * Atomic compare and set, used by the mutex functions.
*
- * if (*dst == expect) *dst = src (all 32 bit words)
+ * cmpset:
+ * if (*dst == expect)
+ * *dst = src
*
- * Returns 0 on failure, non-zero on success
+ * fcmpset:
+ * if (*dst == *expect)
+ * *dst = src
+ * else
+ * *expect = *dst
+ *
+ * Returns 0 on failure, non-zero on success.
*/
-
-static __inline int
-atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src)
-{
- u_char res;
-
- __asm __volatile(
- " " MPLOCKED " "
- " cmpxchgl %3,%1 ; "
- " sete %0 ; "
- "# atomic_cmpset_int"
- : "=q" (res), /* 0 */
- "+m" (*dst), /* 1 */
- "+a" (expect) /* 2 */
- : "r" (src) /* 3 */
- : "memory", "cc");
- return (res);
+#define ATOMIC_CMPSET(TYPE, CONS) \
+static __inline int \
+atomic_cmpset_##TYPE(volatile u_##TYPE *dst, u_##TYPE expect, u_##TYPE src) \
+{ \
+ u_char res; \
+ \
+ __asm __volatile( \
+ " " MPLOCKED " " \
+ " cmpxchg %3,%1 ; " \
+ " sete %0 ; " \
+ "# atomic_cmpset_" #TYPE " " \
+ : "=q" (res), /* 0 */ \
+ "+m" (*dst), /* 1 */ \
+ "+a" (expect) /* 2 */ \
+ : CONS (src) /* 3 */ \
+ : "memory", "cc"); \
+ return (res); \
+} \
+ \
+static __inline int \
+atomic_fcmpset_##TYPE(volatile u_##TYPE *dst, u_##TYPE *expect, u_##TYPE src) \
+{ \
+ u_char res; \
+ \
+ __asm __volatile( \
+ " " MPLOCKED " " \
+ " cmpxchg %3,%1 ; " \
+ " sete %0 ; " \
+ "# atomic_fcmpset_" #TYPE " " \
+ : "=q" (res), /* 0 */ \
+ "+m" (*dst), /* 1 */ \
+ "+a" (*expect) /* 2 */ \
+ : CONS (src) /* 3 */ \
+ : "memory", "cc"); \
+ return (res); \
}
-static __inline int
-atomic_fcmpset_int(volatile u_int *dst, u_int *expect, u_int src)
-{
- u_char res;
+ATOMIC_CMPSET(char, "q");
+ATOMIC_CMPSET(short, "r");
+ATOMIC_CMPSET(int, "r");
- __asm __volatile(
- " " MPLOCKED " "
- " cmpxchgl %3,%1 ; "
- " sete %0 ; "
- "# atomic_cmpset_int"
- : "=q" (res), /* 0 */
- "+m" (*dst), /* 1 */
- "+a" (*expect) /* 2 */
- : "r" (src) /* 3 */
- : "memory", "cc");
- return (res);
-}
-
/*
* Atomically add the value of v to the integer pointed to by p and return
* the previous value of *p.
@@ -668,6 +685,10 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_add_rel_char atomic_add_barr_char
#define atomic_subtract_acq_char atomic_subtract_barr_char
#define atomic_subtract_rel_char atomic_subtract_barr_char
+#define atomic_cmpset_acq_char atomic_cmpset_char
+#define atomic_cmpset_rel_char atomic_cmpset_char
+#define atomic_fcmpset_acq_char atomic_fcmpset_char
+#define atomic_fcmpset_rel_char atomic_fcmpset_char
#define atomic_set_acq_short atomic_set_barr_short
#define atomic_set_rel_short atomic_set_barr_short
@@ -677,6 +698,10 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_add_rel_short atomic_add_barr_short
#define atomic_subtract_acq_short atomic_subtract_barr_short
#define atomic_subtract_rel_short atomic_subtract_barr_short
+#define atomic_cmpset_acq_short atomic_cmpset_short
+#define atomic_cmpset_rel_short atomic_cmpset_short
+#define atomic_fcmpset_acq_short atomic_fcmpset_short
+#define atomic_fcmpset_rel_short atomic_fcmpset_short
#define atomic_set_acq_int atomic_set_barr_int
#define atomic_set_rel_int atomic_set_barr_int
@@ -722,6 +747,12 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_subtract_rel_8 atomic_subtract_rel_char
#define atomic_load_acq_8 atomic_load_acq_char
#define atomic_store_rel_8 atomic_store_rel_char
+#define atomic_cmpset_8 atomic_cmpset_char
+#define atomic_cmpset_acq_8 atomic_cmpset_acq_char
+#define atomic_cmpset_rel_8 atomic_cmpset_rel_char
+#define atomic_fcmpset_8 atomic_fcmpset_char
+#define atomic_fcmpset_acq_8 atomic_fcmpset_acq_char
+#define atomic_fcmpset_rel_8 atomic_fcmpset_rel_char
/* Operations on 16-bit words. */
#define atomic_set_16 atomic_set_short
@@ -738,6 +769,12 @@ u_long atomic_swap_long(volatile u_long *p, u_long v);
#define atomic_subtract_rel_16 atomic_subtract_rel_short
#define atomic_load_acq_16 atomic_load_acq_short
#define atomic_store_rel_16 atomic_store_rel_short
+#define atomic_cmpset_16 atomic_cmpset_short
+#define atomic_cmpset_acq_16 atomic_cmpset_acq_short
+#define atomic_cmpset_rel_16 atomic_cmpset_rel_short
+#define atomic_fcmpset_16 atomic_fcmpset_short
+#define atomic_fcmpset_acq_16 atomic_fcmpset_acq_short
+#define atomic_fcmpset_rel_16 atomic_fcmpset_rel_short
/* Operations on 32-bit double words. */
#define atomic_set_32 atomic_set_int
More information about the svn-src-stable
mailing list