1 /* $Id: semaphore-helper.h,v 1.3 1999/06/11 14:30:15 ralf Exp $
3 * SMP- and interrupt-safe semaphores helper functions.
5 * (C) Copyright 1996 Linus Torvalds
6 * (C) Copyright 1999 Andrea Arcangeli
7 * (C) Copyright 1999 Ralf Baechle
9 #ifndef __ASM_MIPS_SEMAPHORE_HELPER_H
10 #define __ASM_MIPS_SEMAPHORE_HELPER_H
13 * These two _must_ execute atomically wrt each other.
15 static inline void wake_one_more(struct semaphore
* sem
)
17 atomic_inc(&sem
->waking
);
21 waking_non_zero(struct semaphore
*sem
)
33 : "=r"(ret
), "=r"(tmp
), "=m"(__atomic_fool_gcc(&sem
->waking
))
40 * waking_non_zero_interruptible:
45 * We must undo the sem->count down_interruptible decrement
46 * simultaneously and atomicly with the sem->waking adjustment,
47 * otherwise we can race with wake_one_more.
49 * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words.
51 * This is crazy. Normally it stricly forbidden to use 64-bit operation
52 * in the 32-bit MIPS kernel. In this case it's however ok because if an
53 * interrupt has destroyed the upper half of registers sc will fail.
56 waking_non_zero_interruptible(struct semaphore
*sem
, struct task_struct
*tsk
)
61 __asm__
__volatile__("
69 dli $1, 0xffffffff00000000
90 : "=&r"(ret
), "=&r"(tmp
), "=m"(*sem
)
91 : "r"(signal_pending(tsk
)), "i"(-EINTR
));
95 #error "FIXME: waking_non_zero_interruptible doesn't support little endian machines yet."
102 * waking_non_zero_trylock:
109 #error FIXME, waking_non_zero_trylock is broken for SMP.
111 static inline int waking_non_zero_trylock(struct semaphore
*sem
)
115 if (atomic_read(&sem
->waking
) <= 0)
116 atomic_inc(&sem
->count
);
118 atomic_dec(&sem
->waking
);
125 #endif /* __ASM_MIPS_SEMAPHORE_HELPER_H */