diff options
| author | Ivan Maidanski <ivmai@mail.ru> | 2017-01-24 01:42:06 +0300 |
|---|---|---|
| committer | Ivan Maidanski <ivmai@mail.ru> | 2017-01-24 01:42:06 +0300 |
| commit | 90281551455f043fc027ad98ac9e7063803b7b31 (patch) | |
| tree | d4c71939199809f73e0c4b445cd579f0cc0061e6 /src/atomic_ops | |
| parent | a013152ae8fb09223b91f3183b40869960a7a79e (diff) | |
| download | libatomic_ops-90281551455f043fc027ad98ac9e7063803b7b31.tar.gz | |
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.
Diffstat (limited to 'src/atomic_ops')
| -rw-r--r-- | src/atomic_ops/sysdeps/msftc/common32_defs.h | 35 | ||||
| -rw-r--r-- | src/atomic_ops/sysdeps/msftc/x86.h | 2 | ||||
| -rw-r--r-- | src/atomic_ops/sysdeps/msftc/x86_64.h | 40 |
3 files changed, 75 insertions, 2 deletions
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. */ |
