2584. [bug] alpha: gcc optimization could break atomic operations.

[RT #19227]
This commit is contained in:
Tatuya JINMEI 神明達哉 2009-04-08 05:46:22 +00:00
parent 3dc1cb7e96
commit af2e2f5ed7
2 changed files with 27 additions and 10 deletions

View file

@ -1,3 +1,6 @@
2584. [bug] alpha: gcc optimization could break atomic operations.
[RT #19227]
2583. [port] netbsd: provide a control to not add the compile
date to the version string, -DNO_VERSION_DATE.

View file

@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: atomic.h,v 1.5 2007/06/19 23:47:17 tbox Exp $ */
/* $Id: atomic.h,v 1.6 2009/04/08 05:46:22 jinmei Exp $ */
/*
* This code was written based on FreeBSD's kernel source whose copyright
@ -62,16 +62,20 @@
/*
* This routine atomically increments the value stored in 'p' by 'val', and
* returns the previous value.
* returns the previous value. Memory access ordering around this function
* can be critical, so we add explicit memory block instructions at the
* beginning and the end of it (same for other functions).
*/
static inline isc_int32_t
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
return (asm("1:"
return (asm("mb;"
"1:"
"ldl_l %t0, 0(%a0);" /* load old value */
"mov %t0, %v0;" /* copy the old value */
"addl %t0, %a1, %t0;" /* calculate new value */
"stl_c %t0, 0(%a0);" /* attempt to store */
"beq %t0, 1b;", /* spin if failed */
"beq %t0, 1b;" /* spin if failed */
"mb;",
p, val));
}
@ -80,11 +84,13 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
*/
static inline void
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
(void)asm("1:"
(void)asm("mb;"
"1:"
"ldl_l %t0, 0(%a0);" /* load old value */
"mov %a1, %t0;" /* value to store */
"stl_c %t0, 0(%a0);" /* attempt to store */
"beq %t0, 1b;", /* spin if failed */
"beq %t0, 1b;" /* spin if failed */
"mb;",
p, val);
}
@ -96,7 +102,8 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
static inline isc_int32_t
isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
return(asm("1:"
return(asm("mb;"
"1:"
"ldl_l %t0, 0(%a0);" /* load old value */
"mov %t0, %v0;" /* copy the old value */
"cmpeq %t0, %a1, %t0;" /* compare */
@ -104,7 +111,8 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
"mov %a2, %t0;" /* value to store */
"stl_c %t0, 0(%a0);" /* attempt to store */
"beq %t0, 1b;" /* if it failed, spin */
"2:",
"2:"
"mb;",
p, cmpval, val));
}
#elif defined (ISC_PLATFORM_USEGCCASM)
@ -113,13 +121,15 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
isc_int32_t temp, prev;
__asm__ volatile(
"mb;"
"1:"
"ldl_l %0, %1;" /* load old value */
"mov %0, %2;" /* copy the old value */
"addl %0, %3, %0;" /* calculate new value */
"stl_c %0, %1;" /* attempt to store */
"beq %0, 1b;" /* spin if failed */
: "=&r"(temp), "+m"(*p), "=r"(prev)
"mb;"
: "=&r"(temp), "+m"(*p), "=&r"(prev)
: "r"(val)
: "memory");
@ -131,11 +141,13 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
isc_int32_t temp;
__asm__ volatile(
"mb;"
"1:"
"ldl_l %0, %1;" /* load old value */
"mov %2, %0;" /* value to store */
"stl_c %0, %1;" /* attempt to store */
"beq %0, 1b;" /* if it failed, spin */
"mb;"
: "=&r"(temp), "+m"(*p)
: "r"(val)
: "memory");
@ -146,6 +158,7 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
isc_int32_t temp, prev;
__asm__ volatile(
"mb;"
"1:"
"ldl_l %0, %1;" /* load old value */
"mov %0, %2;" /* copy the old value */
@ -155,7 +168,8 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
"stl_c %0, %1;" /* attempt to store */
"beq %0, 1b;" /* if it failed, spin */
"2:"
: "=&r"(temp), "+m"(*p), "=r"(prev)
"mb;"
: "=&r"(temp), "+m"(*p), "=&r"(prev)
: "r"(cmpval), "r"(val)
: "memory");