Skip to content

Commit

Permalink
Support double-wide CAS on armv7+ (MS VC)
Browse files Browse the repository at this point in the history
* src/atomic_ops/sysdeps/msftc/arm.h [_M_ARM>=6]: Remove TODO about
double-wide operations support.
* src/atomic_ops/sysdeps/msftc/arm.h [_M_ARM>=7 && !AO_NO_DOUBLE_CAS]:
Include standard_ao_double_t.h.
* src/atomic_ops/sysdeps/msftc/arm.h [_M_ARM>=7 && !AO_NO_DOUBLE_CAS]
(_InterlockedCompareExchange64, _InterlockedCompareExchange64_acq,
_InterlockedCompareExchange64_nf, _InterlockedCompareExchange64_rel):
Specify as intrinsic.
* src/atomic_ops/sysdeps/msftc/arm.h [_M_ARM>=7 && !AO_NO_DOUBLE_CAS]
(AO_double_compare_and_swap, AO_double_compare_and_swap_acquire,
AO_double_compare_and_swap_release, AO_double_compare_and_swap_full):
Implement (similar to that in msftc/x86.h).
  • Loading branch information
ivmai committed Oct 20, 2021
1 parent 1f8f5af commit 086a92a
Showing 1 changed file with 60 additions and 4 deletions.
64 changes: 60 additions & 4 deletions src/atomic_ops/sysdeps/msftc/arm.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,67 @@
#if _M_ARM >= 6
/* ARMv6 is the first architecture providing support for simple LL/SC. */

/* #include "../standard_ao_double_t.h" */
/* TODO: implement double-wide operations (similar to x86). */

#else /* _M_ARM < 6 */

/* TODO: implement AO_test_and_set_full using SWP. */

#endif /* _M_ARM < 6 */

#if _M_ARM >= 7 && !defined(AO_NO_DOUBLE_CAS)

# include "../standard_ao_double_t.h"

/* These intrinsics are supposed to use LDREXD/STREXD. */
# pragma intrinsic (_InterlockedCompareExchange64)
# pragma intrinsic (_InterlockedCompareExchange64_acq)
# pragma intrinsic (_InterlockedCompareExchange64_nf)
# pragma intrinsic (_InterlockedCompareExchange64_rel)

AO_INLINE int
AO_double_compare_and_swap(volatile AO_double_t *addr,
AO_double_t old_val, AO_double_t new_val)
{
AO_ASSERT_ADDR_ALIGNED(addr);
return (double_ptr_storage)_InterlockedCompareExchange64_nf(
(__int64 volatile *)addr,
new_val.AO_whole /* exchange */,
old_val.AO_whole) == old_val.AO_whole;
}
# define AO_HAVE_double_compare_and_swap

AO_INLINE int
AO_double_compare_and_swap_acquire(volatile AO_double_t *addr,
AO_double_t old_val, AO_double_t new_val)
{
AO_ASSERT_ADDR_ALIGNED(addr);
return (double_ptr_storage)_InterlockedCompareExchange64_acq(
(__int64 volatile *)addr,
new_val.AO_whole /* exchange */,
old_val.AO_whole) == old_val.AO_whole;
}
# define AO_HAVE_double_compare_and_swap_acquire

AO_INLINE int
AO_double_compare_and_swap_release(volatile AO_double_t *addr,
AO_double_t old_val, AO_double_t new_val)
{
AO_ASSERT_ADDR_ALIGNED(addr);
return (double_ptr_storage)_InterlockedCompareExchange64_rel(
(__int64 volatile *)addr,
new_val.AO_whole /* exchange */,
old_val.AO_whole) == old_val.AO_whole;
}
# define AO_HAVE_double_compare_and_swap_release

AO_INLINE int
AO_double_compare_and_swap_full(volatile AO_double_t *addr,
AO_double_t old_val, AO_double_t new_val)
{
AO_ASSERT_ADDR_ALIGNED(addr);
return (double_ptr_storage)_InterlockedCompareExchange64(
(__int64 volatile *)addr,
new_val.AO_whole /* exchange */,
old_val.AO_whole) == old_val.AO_whole;
}
# define AO_HAVE_double_compare_and_swap_full

#endif /* _M_ARM >= 7 && !AO_NO_DOUBLE_CAS */

0 comments on commit 086a92a

Please sign in to comment.