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 | */ | |
bb8cc641 | 23 | static inline void wake_one_more(struct semaphore * sem) |
1da177e4 LT |
24 | { |
25 | atomic_inc(&sem->waking); | |
26 | } | |
27 | ||
bb8cc641 | 28 | static inline int waking_non_zero(struct semaphore *sem) |
1da177e4 LT |
29 | { |
30 | unsigned long flags; | |
31 | int ret = 0; | |
32 | ||
047c7c42 | 33 | local_irq_save(flags); |
1da177e4 LT |
34 | if (read(&sem->waking) > 0) { |
35 | dec(&sem->waking); | |
36 | ret = 1; | |
37 | } | |
38 | local_irq_restore(flags); | |
39 | return ret; | |
40 | } | |
41 | ||
bb8cc641 | 42 | static inline int waking_non_zero_interruptible(struct semaphore *sem, |
1da177e4 LT |
43 | struct task_struct *tsk) |
44 | { | |
45 | int ret = 0; | |
46 | unsigned long flags; | |
47 | ||
047c7c42 | 48 | local_irq_save(flags); |
1da177e4 LT |
49 | if (read(&sem->waking) > 0) { |
50 | dec(&sem->waking); | |
51 | ret = 1; | |
52 | } else if (signal_pending(tsk)) { | |
53 | inc(&sem->count); | |
54 | ret = -EINTR; | |
55 | } | |
56 | local_irq_restore(flags); | |
57 | return ret; | |
58 | } | |
59 | ||
bb8cc641 | 60 | static inline int waking_non_zero_trylock(struct semaphore *sem) |
1da177e4 LT |
61 | { |
62 | int ret = 1; | |
63 | unsigned long flags; | |
64 | ||
047c7c42 | 65 | local_irq_save(flags); |
1da177e4 LT |
66 | if (read(&sem->waking) <= 0) |
67 | inc(&sem->count); | |
68 | else { | |
69 | dec(&sem->waking); | |
70 | ret = 0; | |
71 | } | |
72 | local_irq_restore(flags); | |
73 | return ret; | |
74 | } | |
75 | ||
76 | #endif /* _ASM_SEMAPHORE_HELPER_H */ | |
77 | ||
78 |