1 #ifndef ASMARM_SEMAPHORE_HELPER_H
2 #define ASMARM_SEMAPHORE_HELPER_H
3 
4 /*
5  * These two _must_ execute atomically wrt each other.
6  */
wake_one_more(struct semaphore * sem)7 static inline void wake_one_more(struct semaphore * sem)
8 {
9 	unsigned long flags;
10 
11 	spin_lock_irqsave(&semaphore_wake_lock, flags);
12 	if (atomic_read(&sem->count) <= 0)
13 		sem->waking++;
14 	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
15 }
16 
waking_non_zero(struct semaphore * sem)17 static inline int waking_non_zero(struct semaphore *sem)
18 {
19 	unsigned long flags;
20 	int ret = 0;
21 
22 	spin_lock_irqsave(&semaphore_wake_lock, flags);
23 	if (sem->waking > 0) {
24 		sem->waking--;
25 		ret = 1;
26 	}
27 	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
28 	return ret;
29 }
30 
31 /*
32  * waking non zero interruptible
33  *	1	got the lock
34  *	0	go to sleep
35  *	-EINTR	interrupted
36  *
37  * We must undo the sem->count down_interruptible() increment while we are
38  * protected by the spinlock in order to make this atomic_inc() with the
39  * atomic_read() in wake_one_more(), otherwise we can race. -arca
40  */
waking_non_zero_interruptible(struct semaphore * sem,struct task_struct * tsk)41 static inline int waking_non_zero_interruptible(struct semaphore *sem,
42 						struct task_struct *tsk)
43 {
44 	unsigned long flags;
45 	int ret = 0;
46 
47 	spin_lock_irqsave(&semaphore_wake_lock, flags);
48 	if (sem->waking > 0) {
49 		sem->waking--;
50 		ret = 1;
51 	} else if (signal_pending(tsk)) {
52 		atomic_inc(&sem->count);
53 		ret = -EINTR;
54 	}
55 	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
56 	return ret;
57 }
58 
59 /*
60  * waking_non_zero_try_lock:
61  *	1	failed to lock
62  *	0	got the lock
63  *
64  * We must undo the sem->count down_interruptible() increment while we are
65  * protected by the spinlock in order to make this atomic_inc() with the
66  * atomic_read() in wake_one_more(), otherwise we can race. -arca
67  */
waking_non_zero_trylock(struct semaphore * sem)68 static inline int waking_non_zero_trylock(struct semaphore *sem)
69 {
70 	unsigned long flags;
71 	int ret = 1;
72 
73 	spin_lock_irqsave(&semaphore_wake_lock, flags);
74 	if (sem->waking <= 0)
75 		atomic_inc(&sem->count);
76 	else {
77 		sem->waking--;
78 		ret = 0;
79 	}
80 	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
81 	return ret;
82 }
83 
84 #endif
85