Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* $Id: semaphore-helper.h,v 1.3 2001/03/26 15:00:33 orjanf Exp $ |
2 | * | |
3 | * SMP- and interrupt-safe semaphores helper functions. Generic versions, no | |
4 | * optimizations whatsoever... | |
5 | * | |
6 | */ | |
7 | ||
8 | #ifndef _ASM_SEMAPHORE_HELPER_H | |
9 | #define _ASM_SEMAPHORE_HELPER_H | |
10 | ||
11 | #include <asm/atomic.h> | |
12 | #include <linux/errno.h> | |
13 | ||
14 | #define read(a) ((a)->counter) | |
15 | #define inc(a) (((a)->counter)++) | |
16 | #define dec(a) (((a)->counter)--) | |
17 | ||
18 | #define count_inc(a) ((*(a))++) | |
19 | ||
20 | /* | |
21 | * These two _must_ execute atomically wrt each other. | |
22 | */ | |
23 | extern inline void wake_one_more(struct semaphore * sem) | |
24 | { | |
25 | atomic_inc(&sem->waking); | |
26 | } | |
27 | ||
28 | extern inline int waking_non_zero(struct semaphore *sem) | |
29 | { | |
30 | unsigned long flags; | |
31 | int ret = 0; | |
32 | ||
33 | local_save_flags(flags); | |
34 | local_irq_disable(); | |
35 | if (read(&sem->waking) > 0) { | |
36 | dec(&sem->waking); | |
37 | ret = 1; | |
38 | } | |
39 | local_irq_restore(flags); | |
40 | return ret; | |
41 | } | |
42 | ||
43 | extern inline int waking_non_zero_interruptible(struct semaphore *sem, | |
44 | struct task_struct *tsk) | |
45 | { | |
46 | int ret = 0; | |
47 | unsigned long flags; | |
48 | ||
49 | local_save_flags(flags); | |
50 | local_irq_disable(); | |
51 | if (read(&sem->waking) > 0) { | |
52 | dec(&sem->waking); | |
53 | ret = 1; | |
54 | } else if (signal_pending(tsk)) { | |
55 | inc(&sem->count); | |
56 | ret = -EINTR; | |
57 | } | |
58 | local_irq_restore(flags); | |
59 | return ret; | |
60 | } | |
61 | ||
62 | extern inline int waking_non_zero_trylock(struct semaphore *sem) | |
63 | { | |
64 | int ret = 1; | |
65 | unsigned long flags; | |
66 | ||
67 | local_save_flags(flags); | |
68 | local_irq_disable(); | |
69 | if (read(&sem->waking) <= 0) | |
70 | inc(&sem->count); | |
71 | else { | |
72 | dec(&sem->waking); | |
73 | ret = 0; | |
74 | } | |
75 | local_irq_restore(flags); | |
76 | return ret; | |
77 | } | |
78 | ||
79 | #endif /* _ASM_SEMAPHORE_HELPER_H */ | |
80 | ||
81 |