]> granicus.if.org Git - libatomic_ops/commitdiff
Define AO_nop_full as compiler barrier for pre-ARMv6 single-core case
authorIvan Maidanski <ivmai@mail.ru>
Thu, 14 Feb 2013 07:36:06 +0000 (11:36 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 14 Feb 2013 07:36:06 +0000 (11:36 +0400)
* 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.

src/atomic_ops/sysdeps/gcc/arm.h
src/atomic_ops/sysdeps/msftc/arm.h

index 746f11bfbe1c86f0565635d94f700f2730ba9192..17cb56814972f985d9764cbd52f196fdc5c9d914 100644 (file)
                 /* 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.                */
 # 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 */
index cd7500a40d2141e82cea6537939e433043211e1f..c01bef17a2a0985b188d835998a774a0a6ec573a 100644 (file)
@@ -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
   }
 # 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