From owner-svn-src-all@freebsd.org Fri Feb 16 16:41:20 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 55155F239ED; Fri, 16 Feb 2018 16:41:20 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 0751E84A2C; Fri, 16 Feb 2018 16:41:20 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id DC0EC1042F; Fri, 16 Feb 2018 16:41:19 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w1GGfJo3091776; Fri, 16 Feb 2018 16:41:19 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w1GGfJFr091773; Fri, 16 Feb 2018 16:41:19 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201802161641.w1GGfJFr091773@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Fri, 16 Feb 2018 16:41:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r329383 - in stable/11: share/man/man9 sys/amd64/include sys/i386/include X-SVN-Group: stable-11 X-SVN-Commit-Author: markj X-SVN-Commit-Paths: in stable/11: share/man/man9 sys/amd64/include sys/i386/include X-SVN-Commit-Revision: 329383 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Feb 2018 16:41:20 -0000 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