diff options
author | David S. Miller <davem@davemloft.net> | 2015-01-31 19:07:28 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-31 23:39:50 -0800 |
commit | edac0a60c7514b8c9b59488cffdac6b22267e757 (patch) | |
tree | 51417325552e5133fe74301e6053bc60fbef9ed4 /sysdeps/sparc/sparc32 | |
parent | d4abeca50400747402a5a33f3a8aa0941be076d5 (diff) | |
download | glibc-edac0a60c7514b8c9b59488cffdac6b22267e757.tar glibc-edac0a60c7514b8c9b59488cffdac6b22267e757.tar.gz glibc-edac0a60c7514b8c9b59488cffdac6b22267e757.tar.bz2 glibc-edac0a60c7514b8c9b59488cffdac6b22267e757.zip |
Fix two bugs in sparc atomics.
* 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.
Diffstat (limited to 'sysdeps/sparc/sparc32')
-rw-r--r-- | sysdeps/sparc/sparc32/bits/atomic.h | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/sysdeps/sparc/sparc32/bits/atomic.h b/sysdeps/sparc/sparc32/bits/atomic.h index 5f21b83646..4242ba831a 100644 --- a/sysdeps/sparc/sparc32/bits/atomic.h +++ b/sysdeps/sparc/sparc32/bits/atomic.h @@ -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. */ |