1 #ifndef _ALPHA_SEMAPHORE_HELPER_H
2 #define _ALPHA_SEMAPHORE_HELPER_H
5 * SMP- and interrupt-safe semaphores helper functions.
7 * (C) Copyright 1996 Linus Torvalds
8 * (C) Copyright 1999 Richard Henderson
12 * These two _must_ execute atomically wrt each other.
14 * This is trivially done with load_locked/store_cond,
15 * which we have. Let the rest of the losers suck eggs.
19 wake_one_more(struct semaphore
* sem
)
21 atomic_inc(&sem
->waking
);
25 waking_non_zero(struct semaphore
*sem
)
29 /* An atomic conditional decrement. */
37 ".section .text2,\"ax\"\n"
40 : "=r"(ret
), "=r"(tmp
), "=m"(__atomic_fool_gcc(&sem
->waking
))
48 * waking_non_zero_interruptible:
53 * We must undo the sem->count down_interruptible decrement
54 * simultaneously and atomicly with the sem->waking adjustment,
55 * otherwise we can race with wake_one_more.
57 * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words.
61 waking_non_zero_interruptible(struct semaphore
*sem
, struct task_struct
*tsk
)
63 long ret
, tmp
, tmp2
, tmp3
;
65 /* "Equivalent" C. Note that we have to do this all without
66 (taken) branches in order to be a valid ll/sc sequence.
72 tmp += 0xffffffff00000000;
76 // Since -1 + 1 carries into the high word, we have
77 // to be more careful adding 1 here.
78 tmp = (tmp & 0xffffffff00000000)
79 | ((tmp + 1) & 0x00000000ffffffff;
83 break; // ideally. we don't actually break
84 // since this is a predicate we don't
85 // have, and is more trouble to build
86 // than to elide the noop stq_c.
107 ".section .text2,\"ax\"\n"
110 : "=&r"(ret
), "=&r"(tmp
), "=&r"(tmp2
), "=&r"(tmp3
), "=m"(*sem
)
111 : "r"(signal_pending(tsk
)), "r"(-EINTR
),
112 "r"(0xffffffff00000000));
118 * waking_non_zero_trylock is unused. we do everything in
119 * down_trylock and let non-ll/sc hosts bounce around.
123 waking_non_zero_trylock(struct semaphore
*sem
)