+2009-09-10 Ivan Maidanski <ivmai@mail.ru>
+ (ivmai123.diff)
+ * src/atomic_ops/sysdeps/msftc/arm.h: Add FIXME for InterlockedOps
+ (regarding memory barrier).
+ * src/atomic_ops/sysdeps/msftc/arm.h: Don't recognize
+ AO_ASSUME_ARM_ARCH6 anymore; check for _M_ARM >= 6 instead.
+ * src/atomic_ops/sysdeps/msftc/arm.h (AO_nop_full,
+ AO_test_and_set): Replace FIXME with the comment saying it is
+ emulated (in generalize.h); include test_and_set_t_is_ao_t.h.
+ * src/atomic_ops/sysdeps/msftc/arm.h (AO_store_full): Implement
+ using InterlockedCompareExchange() (assuming the latter has a full
+ mbar) for ARMv6+.
+ * src/atomic_ops/sysdeps/msftc/arm.h: Include
+ all_atomic_load_store.h and test_and_set_t_is_ao_t.h for the case
+ of pre-ARMv6; add the comment.
+
2009-09-10 Ivan Maidanski <ivmai@mail.ru>
(ivmai122.diff)
* src/atomic_ops/sysdeps/armcc/arm_v6.h
# define AO_ASSUME_WINDOWS98
#endif
#include "common32_defs.h"
+/* FIXME: Do _InterlockedOps really have a full memory barrier? */
+/* (MSDN WinCE docs say nothing about it.) */
-#ifdef AO_ASSUME_ARM_ARCH6
+#if _M_ARM >= 6
/* ARMv6 is the first architecture providing support for simple LL/SC. */
#include "../standard_ao_double_t.h"
AO_INLINE void AO_nop_full(void) {}
# define AO_HAVE_nop_full
#else
-/* FIXME: implement AO_nop_full() */
+/* AO_nop_full() is emulated using AO_test_and_set_full(). */
#endif
+#include "../test_and_set_t_is_ao_t.h"
+/* AO_test_and_set() is emulated using CAS. */
+
AO_INLINE AO_t
AO_load(const volatile AO_t *addr)
{
/* Cast away the volatile in case it adds fence semantics */
return (*(const AO_t *)addr);
}
-
#define AO_HAVE_load
-/* FIXME: implement AO_store() */
-
-/* #include "../test_and_set_t_is_ao_t.h" */
-/* FIXME: implement AO_test_and_set() */
+AO_INLINE void
+AO_store_full(volatile AO_t *addr, AO_t value)
+{
+ /* Emulate atomic store using CAS. */
+ AO_t old = AO_load(addr);
+ AO_t current;
+# ifdef AO_OLD_STYLE_INTERLOCKED_COMPARE_EXCHANGE
+ while ((current = (AO_t)_InterlockedCompareExchange(
+ (PVOID AO_INTERLOCKED_VOLATILE *)addr,
+ (PVOID)value, (PVOID)old)) != old)
+ old = current;
+# else
+ while ((current = (AO_t)_InterlockedCompareExchange(
+ (LONG AO_INTERLOCKED_VOLATILE *)addr,
+ (LONG)value, (LONG)old)) != old)
+ old = current;
+# endif
+}
+#define AO_HAVE_store_full
/* FIXME: implement AO_compare_double_and_swap_double() */
-#endif /* AO_ASSUME_ARM_ARCH6 */
+#else /* _M_ARM < 6 */
+
+/* Some slide set, if it has been red correctly, claims that Loads */
+/* followed by either a Load or a Store are ordered, but nothing */
+/* else is. It appears that SWP is the only simple memory barrier. */
+#include "../all_atomic_load_store.h"
+
+#include "../test_and_set_t_is_ao_t.h"
+/* AO_test_and_set_full() is emulated using CAS. */
+
+#endif /* _M_ARM < 6 */