Merge r198724 to Book-E. casuword() non-atomically read the current value

of its argument before atomically replacing it, which could occasionally
return the wrong value on an SMP system. This resulted in user mutex
operations hanging when using threaded applications.
This commit is contained in:
Nathan Whitehorn 2010-02-20 16:13:43 +00:00
parent 4ed925457a
commit 19317dfd85

View File

@ -295,8 +295,19 @@ casuword(volatile u_long *addr, u_long old, u_long new)
return (EFAULT);
}
val = *addr;
(void) atomic_cmpset_32((volatile uint32_t *)addr, old, new);
__asm __volatile (
"1:\tlwarx %0, 0, %2\n\t" /* load old value */
"cmplw %3, %0\n\t" /* compare */
"bne 2f\n\t" /* exit if not equal */
"stwcx. %4, 0, %2\n\t" /* attempt to store */
"bne- 1b\n\t" /* spin if failed */
"b 3f\n\t" /* we've succeeded */
"2:\n\t"
"stwcx. %0, 0, %2\n\t" /* clear reservation (74xx) */
"3:\n\t"
: "=&r" (val), "=m" (*addr)
: "r" (addr), "r" (old), "r" (new), "m" (*addr)
: "cc", "memory");
td->td_pcb->pcb_onfault = NULL;