diff options
| author | Ivan Maidanski <ivmai@mail.ru> | 2017-01-17 00:34:48 +0300 |
|---|---|---|
| committer | Ivan Maidanski <ivmai@mail.ru> | 2017-01-17 00:34:48 +0300 |
| commit | 8262e52fb577c634d8d93d76ec2ddecbdba1f995 (patch) | |
| tree | 05164f6f4598045f28e72af51ae6421881c6371f /src | |
| parent | aff8affc945d070b0fb5ed8540d78616535ea826 (diff) | |
| download | libatomic_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.h | 29 |
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 |
