summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorivmai <ivmai>2009-09-10 15:43:48 +0000
committerIvan Maidanski <ivmai@mail.ru>2011-07-25 16:03:25 +0400
commit400e40b4333174f83f138cc1690b680eccb5a79d (patch)
tree9b4d1be8ff7f6194b37f962cc3a96eeb8ee70486
parent07e9ea93f8c50194757f0d73f6b60d308b9366a4 (diff)
downloadlibatomic_ops-400e40b4333174f83f138cc1690b680eccb5a79d.tar.gz
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.
-rw-r--r--ChangeLog16
-rwxr-xr-xsrc/atomic_ops/sysdeps/msftc/arm.h45
2 files changed, 53 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 80817de..db61b07 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,20 @@
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
(AO_compare_double_and_swap_double): Replace false/true with 0/1.
diff --git a/src/atomic_ops/sysdeps/msftc/arm.h b/src/atomic_ops/sysdeps/msftc/arm.h
index 4ebc09b..507b70a 100755
--- a/src/atomic_ops/sysdeps/msftc/arm.h
+++ b/src/atomic_ops/sysdeps/msftc/arm.h
@@ -27,8 +27,10 @@
# 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"
@@ -39,23 +41,50 @@
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 */