2 * SMP- and interrupt-safe semaphores helper functions.
4 * (C) Copyright 1996 Linus Torvalds
5 * (C) Copyright 1999 Andrea Arcangeli
6 * (C) Copyright 1999 Ralf Baechle
7 * (C) Copyright 1999 Silicon Graphics, Inc.
9 #ifndef _ASM_SEMAPHORE_HELPER_H
10 #define _ASM_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" (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.
53 * If(sem->waking > 0) {
54 * Decrement(sem->waking)
56 * } else If(segnal_pending(tsk)) {
57 * Increment(sem->count)
65 waking_non_zero_interruptible(struct semaphore
*sem
, struct task_struct
*tsk
)
71 __asm__
__volatile__("
84 dli $1, 0x0000000100000000
90 : "=&r" (ret
), "=&r" (tmp
), "=m" (*sem
)
91 : "r" (signal_pending(tsk
)), "i" (-EINTR
));
93 #elif defined(__MIPSEL__)
95 __asm__
__volatile__("
102 dli $1, 0x0000000100000000
110 * It would be nice to assume that sem->count
111 * is != -1, but we will guard against that case
123 : "=&r" (ret
), "=&r" (tmp
), "=m" (*sem
)
124 : "r" (signal_pending(tsk
)), "i" (-EINTR
));
127 #error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
134 * waking_non_zero_trylock is unused. we do everything in
135 * down_trylock and let non-ll/sc hosts bounce around.
139 waking_non_zero_trylock(struct semaphore
*sem
)
142 CHECK_MAGIC(sem
->__magic
);
148 #endif /* _ASM_SEMAPHORE_HELPER_H */