summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2013-02-14 11:36:06 +0400
committerIvan Maidanski <ivmai@mail.ru>2013-02-14 11:36:06 +0400
commitad70f34ff55146a66b761d95e20199b792407f0c (patch)
tree74936d431453a815efb8142e98d89bf3a6ff3963
parent31aba24cf225fde556bd005a0a92278f885822b8 (diff)
downloadlibatomic_ops-ad70f34ff55146a66b761d95e20199b792407f0c.tar.gz
Define AO_nop_full as compiler barrier for pre-ARMv6 single-core case
* src/atomic_ops/sysdeps/gcc/arm.h (AO_nop_full): Define for pre-ARMv6 as well (as a compiler barrier) if AO_UNIPROCESSOR; refine comment. * src/atomic_ops/sysdeps/msftc/arm.h (AO_nop_full): Likewise. * src/atomic_ops/sysdeps/msftc/arm.h: Eliminate duplicated include of test_and_set_t_is_ao_t.h.
-rw-r--r--src/atomic_ops/sysdeps/gcc/arm.h107
-rw-r--r--src/atomic_ops/sysdeps/msftc/arm.h13
2 files changed, 60 insertions, 60 deletions
diff --git a/src/atomic_ops/sysdeps/gcc/arm.h b/src/atomic_ops/sysdeps/gcc/arm.h
index 746f11b..17cb568 100644
--- a/src/atomic_ops/sysdeps/gcc/arm.h
+++ b/src/atomic_ops/sysdeps/gcc/arm.h
@@ -78,6 +78,61 @@
/* Note: ARMv6M is excluded due to no ARM mode support. */
#endif /* !__thumb2__ */
+#ifdef AO_UNIPROCESSOR
+ /* If only a single processor (core) is used, AO_UNIPROCESSOR could */
+ /* be defined by the client to avoid unnecessary memory barrier. */
+ AO_INLINE void
+ AO_nop_full(void)
+ {
+ AO_compiler_barrier();
+ }
+# define AO_HAVE_nop_full
+
+#elif defined(AO_ARM_HAVE_DMB)
+ /* ARMv7 is compatible to ARMv6 but has a simpler command for issuing */
+ /* a memory barrier (DMB). Raising it via CP15 should still work */
+ /* (but slightly less efficient because it requires the use of */
+ /* a general-purpose register). */
+ AO_INLINE void
+ AO_nop_full(void)
+ {
+ /* AO_THUMB_GO_ARM is empty. */
+ __asm__ __volatile__("dmb" : : : "memory");
+ }
+# define AO_HAVE_nop_full
+
+ AO_INLINE void
+ AO_nop_write(void)
+ {
+ /* AO_THUMB_GO_ARM is empty. */
+ __asm__ __volatile__("dmb st" : : : "memory");
+ }
+# define AO_HAVE_nop_write
+
+#elif defined(AO_ARM_HAVE_LDREX)
+ /* ARMv6 is the first architecture providing support for a simple */
+ /* LL/SC. A data memory barrier must be raised via CP15 command. */
+ AO_INLINE void
+ AO_nop_full(void)
+ {
+ unsigned dest = 0;
+
+ /* Issue a data memory barrier (keeps ordering of memory */
+ /* transactions before and after this operation). */
+ __asm__ __volatile__("@AO_nop_full\n"
+ AO_THUMB_GO_ARM
+ " mcr p15,0,%0,c7,c10,5\n"
+ AO_THUMB_RESTORE_MODE
+ : "=&r"(dest)
+ : /* empty */
+ : AO_THUMB_SWITCH_CLOBBERS "memory");
+ }
+# define AO_HAVE_nop_full
+
+#else
+ /* AO_nop_full() is emulated using AO_test_and_set_full(). */
+#endif /* !AO_UNIPROCESSOR && !AO_ARM_HAVE_LDREX */
+
#ifdef AO_ARM_HAVE_LDREX
/* AO_t/char/short/int load is simple reading. */
@@ -87,58 +142,6 @@
# define AO_ACCESS_int_CHECK_ALIGNED
# include "../all_atomic_only_load.h"
- /* ARMv6 is the first architecture providing support for simple */
- /* LL/SC. A data memory barrier must be raised via CP15 command (see */
- /* documentation). ARMv7 is compatible to ARMv6 but has a simpler */
- /* command for issuing a memory barrier (DMB). Raising it via CP15 */
- /* should still work (but slightly less efficient because it requires */
- /* the use of a general-purpose register). If only a single */
- /* processor (core) is used, AO_UNIPROCESSOR could be defined by */
- /* client to avoid unnecessary memory barrier. */
-
-# if defined(AO_ARM_HAVE_DMB) && !defined(AO_UNIPROCESSOR)
-
- AO_INLINE void
- AO_nop_full(void)
- {
- /* AO_THUMB_GO_ARM is empty. */
- __asm__ __volatile__("dmb" : : : "memory");
- }
-# define AO_HAVE_nop_full
-
- AO_INLINE void
- AO_nop_write(void)
- {
- /* AO_THUMB_GO_ARM is empty. */
- __asm__ __volatile__("dmb st" : : : "memory");
- }
-# define AO_HAVE_nop_write
-
-# else
-
- AO_INLINE void
- AO_nop_full(void)
- {
-# ifndef AO_UNIPROCESSOR
- unsigned dest = 0;
-
- /* Issue a data memory barrier (keeps ordering of memory */
- /* transactions before and after this operation). */
- __asm__ __volatile__("@AO_nop_full\n"
- AO_THUMB_GO_ARM
- " mcr p15,0,%0,c7,c10,5\n"
- AO_THUMB_RESTORE_MODE
- : "=&r"(dest)
- : /* empty */
- : AO_THUMB_SWITCH_CLOBBERS "memory");
-# else
- AO_compiler_barrier();
-# endif
- }
-# define AO_HAVE_nop_full
-
-# endif /* !AO_ARM_HAVE_DMB */
-
/* "ARM Architecture Reference Manual" (chapter A3.5.3) says that the */
/* single-copy atomic processor accesses are all byte accesses, all */
/* halfword accesses to halfword-aligned locations, all word accesses */
diff --git a/src/atomic_ops/sysdeps/msftc/arm.h b/src/atomic_ops/sysdeps/msftc/arm.h
index cd7500a..c01bef1 100644
--- a/src/atomic_ops/sysdeps/msftc/arm.h
+++ b/src/atomic_ops/sysdeps/msftc/arm.h
@@ -28,8 +28,8 @@
/* FIXME: Do _InterlockedOps really have a full memory barrier? */
/* (MSDN WinCE docs say nothing about it.) */
-#if _M_ARM >= 6
-/* ARMv6 is the first architecture providing support for simple LL/SC. */
+#include "../test_and_set_t_is_ao_t.h"
+/* AO_test_and_set_full() is emulated using CAS. */
/* If only a single processor is used, we can define AO_UNIPROCESSOR. */
#ifdef AO_UNIPROCESSOR
@@ -39,11 +39,11 @@
}
# define AO_HAVE_nop_full
#else
-/* AO_nop_full() is emulated using AO_test_and_set_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. */
+#if _M_ARM >= 6
+/* ARMv6 is the first architecture providing support for simple LL/SC. */
AO_INLINE AO_t
AO_load(const volatile AO_t *addr)
@@ -66,9 +66,6 @@ AO_load(const volatile AO_t *addr)
/* 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 */
#define AO_T_IS_INT