summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2017-01-17 00:34:48 +0300
committerIvan Maidanski <ivmai@mail.ru>2017-01-17 00:34:48 +0300
commit8262e52fb577c634d8d93d76ec2ddecbdba1f995 (patch)
tree05164f6f4598045f28e72af51ae6421881c6371f /src
parentaff8affc945d070b0fb5ed8540d78616535ea826 (diff)
downloadlibatomic_ops-8262e52fb577c634d8d93d76ec2ddecbdba1f995.tar.gz
Implement int CAS/inc/dec for msftc/x86_64
* src/atomic_ops/sysdeps/msftc/x86_64.h (_InterlockedExchangeAdd): Declare (as intrinsic) only unless AO_PREFER_GENERALIZED. * src/atomic_ops/sysdeps/msftc/x86_64.h (_InterlockedCompareExchange): Declare intrinsic. * src/atomic_ops/sysdeps/msftc/x86_64.h [!AO_PREFER_GENERALIZED] (_InterlockedIncrement, _InterlockedDecrement): Likewise. * src/atomic_ops/sysdeps/msftc/x86_64.h (AO_int_fetch_compare_and_swap_full): Define inline function (using _InterlockedCompareExchange). * src/atomic_ops/sysdeps/msftc/x86_64.h (AO_int_fetch_and_add_full): Do not define if AO_PREFER_GENERALIZED. * src/atomic_ops/sysdeps/msftc/x86_64.h [!AO_PREFER_GENERALIZED] (AO_int_fetch_and_add1_full, AO_int_fetch_and_sub1_full): Define inline function _InterlockedIncrement/Decrement).
Diffstat (limited to 'src')
-rw-r--r--src/atomic_ops/sysdeps/msftc/x86_64.h29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/atomic_ops/sysdeps/msftc/x86_64.h b/src/atomic_ops/sysdeps/msftc/x86_64.h
index b4b0a3c..41df6e2 100644
--- a/src/atomic_ops/sysdeps/msftc/x86_64.h
+++ b/src/atomic_ops/sysdeps/msftc/x86_64.h
@@ -44,13 +44,16 @@
/* Assume _MSC_VER >= 1400 */
#include <intrin.h>
-#pragma intrinsic (_InterlockedExchangeAdd)
+#pragma intrinsic (_InterlockedCompareExchange)
#pragma intrinsic (_InterlockedCompareExchange64)
#ifndef AO_PREFER_GENERALIZED
+# pragma intrinsic (_InterlockedIncrement)
# pragma intrinsic (_InterlockedIncrement64)
+# pragma intrinsic (_InterlockedDecrement)
# pragma intrinsic (_InterlockedDecrement64)
+# pragma intrinsic (_InterlockedExchangeAdd)
# pragma intrinsic (_InterlockedExchangeAdd64)
AO_INLINE AO_t
@@ -85,12 +88,36 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
#define AO_HAVE_fetch_compare_and_swap_full
AO_INLINE unsigned int
+AO_int_fetch_compare_and_swap_full(volatile unsigned int *addr,
+ unsigned int old_val, unsigned int new_val)
+{
+ return _InterlockedCompareExchange((LONG volatile *)addr, new_val, old_val);
+}
+#define AO_HAVE_int_fetch_compare_and_swap_full
+
+#ifndef AO_PREFER_GENERALIZED
+AO_INLINE unsigned int
AO_int_fetch_and_add_full(volatile unsigned int *p, unsigned int incr)
{
return _InterlockedExchangeAdd((LONG volatile *)p, incr);
}
#define AO_HAVE_int_fetch_and_add_full
+ AO_INLINE unsigned int
+ AO_int_fetch_and_add1_full(volatile unsigned int *p)
+ {
+ return _InterlockedIncrement((LONG volatile *)p) - 1;
+ }
+# define AO_HAVE_int_fetch_and_add1_full
+
+ AO_INLINE unsigned int
+ AO_int_fetch_and_sub1_full(volatile unsigned int *p)
+ {
+ return _InterlockedDecrement((LONG volatile *)p) + 1;
+ }
+# define AO_HAVE_int_fetch_and_sub1_full
+#endif /* !AO_PREFER_GENERALIZED */
+
#ifdef AO_ASM_X64_AVAILABLE
AO_INLINE unsigned char