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 | |
parent | d4abeca50400747402a5a33f3a8aa0941be076d5 (diff) | |
download | glibc-edac0a60c7514b8c9b59488cffdac6b22267e757.zip glibc-edac0a60c7514b8c9b59488cffdac6b22267e757.tar.gz glibc-edac0a60c7514b8c9b59488cffdac6b22267e757.tar.bz2 |
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.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/bits/atomic.h | 15 |
2 files changed, 14 insertions, 7 deletions
@@ -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. diff --git a/sysdeps/sparc/sparc32/bits/atomic.h b/sysdeps/sparc/sparc32/bits/atomic.h index 5f21b83..4242ba8 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. */ |