]> granicus.if.org Git - libatomic_ops/commitdiff
Implement char CAS and char/short add for msftc X86[_64] (VS 2013+)
authorIvan Maidanski <ivmai@mail.ru>
Mon, 23 Jan 2017 22:42:06 +0000 (01:42 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 23 Jan 2017 22:42:06 +0000 (01:42 +0300)
* 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.

src/atomic_ops/sysdeps/msftc/common32_defs.h
src/atomic_ops/sysdeps/msftc/x86.h
src/atomic_ops/sysdeps/msftc/x86_64.h

index c3f5ee9ed796556ce31e3c75bcc857e322cebe47..92f80927637ef0e25e71dafbaaf3c77e3c73c446 100644 (file)
@@ -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 */
index d9272f5aad61ab58bd8af78a7d9f7e9e35173eed..3de961699d6fe26315e6c02164463ed05bb8d03e 100644 (file)
@@ -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)
   {
index b5eb29836a1a9b7bcca8adfa614547e9228f6078..fead27342cc2bb157e0031baf2f3ad79fbc5eb59 100644 (file)
@@ -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.               */