Fix two bugs in sparc atomics.
authorDavid S. Miller <davem@davemloft.net>
Sun, 1 Feb 2015 03:07:28 +0000 (19:07 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sun, 1 Feb 2015 07:39:50 +0000 (23:39 -0800)
* sysdeps/sparc/sparc32/bits/atomic.h
(__sparc32_atomic_do_unlock24): Put the memory barrier before the
unlock not after it.
(__v9_compare_and_exchange_val_32_acq): Use unions to avoid getting
volatile register usage warnings from the compiler.

ChangeLog
sysdeps/sparc/sparc32/bits/atomic.h

index 0376c5d..50e8153 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2015-01-31  David S. Miller  <davem@davemloft.net>
 
+       * sysdeps/sparc/sparc32/bits/atomic.h
+       (__sparc32_atomic_do_unlock24): Put the memory barrier before the
+       unlock not after it.
+       (__v9_compare_and_exchange_val_32_acq): Use unions to avoid getting
+       volatile register usage warnings from the compiler.
+
        * sysdeps/sparc/nptl/sem_init.c: Delete.
        * sysdeps/sparc/nptl/sem_post.c: Delete.
        * sysdeps/sparc/nptl/sem_timedwait.c: Delete.
index 5f21b83..4242ba8 100644 (file)
@@ -105,27 +105,28 @@ volatile unsigned char __sparc32_atomic_locks[64]
 #define __sparc32_atomic_do_unlock24(addr) \
   do                                                                 \
     {                                                                \
-      *(char *) (addr) = 0;                                          \
       __asm __volatile ("" ::: "memory");                            \
+      *(char *) (addr) = 0;                                          \
     }                                                                \
   while (0)
 
 
 #ifndef SHARED
 # define __v9_compare_and_exchange_val_32_acq(mem, newval, oldval) \
-({                                                                           \
-  register __typeof (*(mem)) __acev_tmp __asm ("%g6");                       \
+({union { __typeof (oldval) a; uint32_t v; } oldval_arg = { .a = (oldval) };  \
+  union { __typeof (newval) a; uint32_t v; } newval_arg = { .a = (newval) };  \
+  register uint32_t __acev_tmp __asm ("%g6");                                \
   register __typeof (mem) __acev_mem __asm ("%g1") = (mem);                  \
-  register __typeof (*(mem)) __acev_oldval __asm ("%g5");                    \
-  __acev_tmp = (newval);                                                     \
-  __acev_oldval = (oldval);                                                  \
+  register uint32_t __acev_oldval __asm ("%g5");                             \
+  __acev_tmp = newval_arg.v;                                                 \
+  __acev_oldval = oldval_arg.v;                                                      \
   /* .word 0xcde05005 is cas [%g1], %g5, %g6.  Can't use cas here though,     \
      because as will then mark the object file as V8+ arch.  */                      \
   __asm __volatile (".word 0xcde05005"                                       \
                    : "+r" (__acev_tmp), "=m" (*__acev_mem)                   \
                    : "r" (__acev_oldval), "m" (*__acev_mem),                 \
                      "r" (__acev_mem) : "memory");                           \
-  __acev_tmp; })
+  (__typeof (oldval)) __acev_tmp; })
 #endif
 
 /* The only basic operation needed is compare and exchange.  */