From: Ivan Maidanski Date: Mon, 23 Jan 2017 22:42:06 +0000 (+0300) Subject: Implement char CAS and char/short add for msftc X86[_64] (VS 2013+) X-Git-Tag: v7.6.0~125 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=90281551455f043fc027ad98ac9e7063803b7b31;p=libatomic_ops Implement char CAS and char/short add for msftc X86[_64] (VS 2013+) * src/atomic_ops/sysdeps/msftc/common32_defs.h [_MSC_VER>=1800] (_InterlockedCompareExchange8): Declare intrinsic. * src/atomic_ops/sysdeps/msftc/common32_defs.h [_MSC_VER>=1800 && !AO_PREFER_GENERALIZED && !_M_ARM] (_InterlockedExchangeAdd16, _InterlockedExchangeAdd8): Likewise. * src/atomic_ops/sysdeps/msftc/x86_64.h [_MSC_VER>=1800] (_InterlockedCompareExchange8): Likewise. * src/atomic_ops/sysdeps/msftc/x86_64.h [_MSC_VER>=1800 && !AO_PREFER_GENERALIZED] (_InterlockedExchangeAdd16, _InterlockedExchangeAdd8): Likewise. * src/atomic_ops/sysdeps/msftc/common32_defs.h [_MSC_VER>=1800] (AO_char_fetch_compare_and_swap_full): Implement using intrinsic. * src/atomic_ops/sysdeps/msftc/common32_defs.h [_MSC_VER>=1800 && !AO_PREFER_GENERALIZED && !_M_ARM] (AO_char_fetch_and_add_full, AO_short_fetch_and_add_full): Likewise. * src/atomic_ops/sysdeps/msftc/x86_64.h [_MSC_VER>=1800] (AO_char_fetch_compare_and_swap_full): Likewise. * src/atomic_ops/sysdeps/msftc/x86_64.h [_MSC_VER>=1800 && !AO_PREFER_GENERALIZED] (AO_char_fetch_and_add_full, AO_short_fetch_and_add_full): Likewise. * src/atomic_ops/sysdeps/msftc/x86.h [!AO_NO_ASM_XADD] (AO_char_fetch_and_add_full, AO_short_fetch_and_add_full): Do not define if AO_HAVE_char_fetch_and_add_full. * src/atomic_ops/sysdeps/msftc/x86_64.h [AO_ASM_X64_AVAILABLE] (AO_char_fetch_and_add_full, AO_short_fetch_and_add_full): Do not use asm-based implementation if _MSC_VER>=1800. --- diff --git a/src/atomic_ops/sysdeps/msftc/common32_defs.h b/src/atomic_ops/sysdeps/msftc/common32_defs.h index c3f5ee9..92f8092 100644 --- a/src/atomic_ops/sysdeps/msftc/common32_defs.h +++ b/src/atomic_ops/sysdeps/msftc/common32_defs.h @@ -174,3 +174,38 @@ AO_fetch_and_sub1_full(volatile AO_t *p) # define AO_HAVE_short_fetch_and_sub1_full # endif /* !AO_PREFER_GENERALIZED */ #endif /* _MSC_VER > 1400 */ + +#if _MSC_VER >= 1800 /* Visual Studio 2013+ */ + +# pragma intrinsic (_InterlockedCompareExchange8) + + AO_INLINE unsigned char + AO_char_fetch_compare_and_swap_full(volatile unsigned char *addr, + unsigned char old_val, + unsigned char new_val) + { + return _InterlockedCompareExchange8((char volatile *)addr, + new_val, old_val); + } +# define AO_HAVE_char_fetch_compare_and_swap_full + +# if !defined(AO_PREFER_GENERALIZED) && !defined(_M_ARM) +# pragma intrinsic (_InterlockedExchangeAdd16) +# pragma intrinsic (_InterlockedExchangeAdd8) + + AO_INLINE unsigned char + AO_char_fetch_and_add_full(volatile unsigned char *p, unsigned char incr) + { + return _InterlockedExchangeAdd8((char volatile *)p, incr); + } +# define AO_HAVE_char_fetch_and_add_full + + AO_INLINE unsigned short + AO_short_fetch_and_add_full(volatile unsigned short *p, + unsigned short incr) + { + return _InterlockedExchangeAdd16((short volatile *)p, incr); + } +# define AO_HAVE_short_fetch_and_add_full +# endif /* !AO_PREFER_GENERALIZED && !_M_ARM */ +#endif /* _MSC_VER >= 1800 */ diff --git a/src/atomic_ops/sysdeps/msftc/x86.h b/src/atomic_ops/sysdeps/msftc/x86.h index d9272f5..3de9616 100644 --- a/src/atomic_ops/sysdeps/msftc/x86.h +++ b/src/atomic_ops/sysdeps/msftc/x86.h @@ -63,7 +63,7 @@ AO_nop_full(void) #endif -#ifndef AO_NO_ASM_XADD +#if !defined(AO_NO_ASM_XADD) && !defined(AO_HAVE_char_fetch_and_add_full) AO_INLINE unsigned char AO_char_fetch_and_add_full(volatile unsigned char *p, unsigned char incr) { diff --git a/src/atomic_ops/sysdeps/msftc/x86_64.h b/src/atomic_ops/sysdeps/msftc/x86_64.h index b5eb298..fead273 100644 --- a/src/atomic_ops/sysdeps/msftc/x86_64.h +++ b/src/atomic_ops/sysdeps/msftc/x86_64.h @@ -171,7 +171,41 @@ AO_int_fetch_and_add_full(volatile unsigned int *p, unsigned int incr) # endif /* !AO_PREFER_GENERALIZED */ #endif /* _MSC_VER > 1400 */ -#ifdef AO_ASM_X64_AVAILABLE +#if _MSC_VER >= 1800 /* Visual Studio 2013+ */ + +# pragma intrinsic (_InterlockedCompareExchange8) + + AO_INLINE unsigned char + AO_char_fetch_compare_and_swap_full(volatile unsigned char *addr, + unsigned char old_val, + unsigned char new_val) + { + return _InterlockedCompareExchange8((char volatile *)addr, + new_val, old_val); + } +# define AO_HAVE_char_fetch_compare_and_swap_full + +# ifndef AO_PREFER_GENERALIZED +# pragma intrinsic (_InterlockedExchangeAdd16) +# pragma intrinsic (_InterlockedExchangeAdd8) + + AO_INLINE unsigned char + AO_char_fetch_and_add_full(volatile unsigned char *p, unsigned char incr) + { + return _InterlockedExchangeAdd8((char volatile *)p, incr); + } +# define AO_HAVE_char_fetch_and_add_full + + AO_INLINE unsigned short + AO_short_fetch_and_add_full(volatile unsigned short *p, + unsigned short incr) + { + return _InterlockedExchangeAdd16((short volatile *)p, incr); + } +# define AO_HAVE_short_fetch_and_add_full +# endif /* !AO_PREFER_GENERALIZED */ + +#elif defined(AO_ASM_X64_AVAILABLE) AO_INLINE unsigned char AO_char_fetch_and_add_full(volatile unsigned char *p, unsigned char incr) @@ -197,6 +231,10 @@ AO_int_fetch_and_add_full(volatile unsigned int *p, unsigned int incr) } # define AO_HAVE_short_fetch_and_add_full +#endif /* _MSC_VER < 1800 && AO_ASM_X64_AVAILABLE */ + +#ifdef AO_ASM_X64_AVAILABLE + /* As far as we can tell, the lfence and sfence instructions are not */ /* currently needed or useful for cached memory accesses. */