sh: Fix up the SH-4A mutex fastpath semantics.

This fixes up the __mutex_fastpath_xxx() routines to match the semantics
noted in the comment. Previously these were looping rather than doing a
single-pass, which is counter-intuitive, as the slow path takes care of
the looping for us in the event of contention.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
Paul Mundt 2008-12-08 11:25:50 +09:00
parent c6f17cb227
commit 77ba93a7ac

View File

@ -21,16 +21,18 @@
static inline void static inline void
__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
{ {
int __res; int __ex_flag, __res;
__asm__ __volatile__ ( __asm__ __volatile__ (
"movli.l @%1, %0 \n" "movli.l @%2, %0 \n"
"dt %0 \n" "add #-1, %0 \n"
"movco.l %0, @%1 \n" "movco.l %0, @%2 \n"
: "=&z" (__res) "movt %1 \n"
: "=&z" (__res), "=&r" (__ex_flag)
: "r" (&(count)->counter) : "r" (&(count)->counter)
: "t"); : "t");
__res |= !__ex_flag;
if (unlikely(__res != 0)) if (unlikely(__res != 0))
fail_fn(count); fail_fn(count);
} }
@ -38,16 +40,18 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
static inline int static inline int
__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
{ {
int __res; int __ex_flag, __res;
__asm__ __volatile__ ( __asm__ __volatile__ (
"movli.l @%1, %0 \n" "movli.l @%2, %0 \n"
"dt %0 \n" "add #-1, %0 \n"
"movco.l %0, @%1 \n" "movco.l %0, @%2 \n"
: "=&z" (__res) "movt %1 \n"
: "=&z" (__res), "=&r" (__ex_flag)
: "r" (&(count)->counter) : "r" (&(count)->counter)
: "t"); : "t");
__res |= !__ex_flag;
if (unlikely(__res != 0)) if (unlikely(__res != 0))
__res = fail_fn(count); __res = fail_fn(count);
@ -57,18 +61,19 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
static inline void static inline void
__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
{ {
int __res; int __ex_flag, __res;
__asm__ __volatile__ ( __asm__ __volatile__ (
"1: movli.l @%1, %0 \n\t" "movli.l @%2, %0 \n\t"
"add #1, %0 \n\t" "add #1, %0 \n\t"
"movco.l %0, @%1 \n\t" "movco.l %0, @%2 \n\t"
"bf 1b\n\t" "movt %1 \n\t"
: "=&z" (__res) : "=&z" (__res), "=&r" (__ex_flag)
: "r" (&(count)->counter) : "r" (&(count)->counter)
: "t"); : "t");
if (unlikely(__res <= 0)) __res |= !__ex_flag;
if (unlikely(__res != 0))
fail_fn(count); fail_fn(count);
} }