1 /*
2 * include/asm-s390/semaphore-helper.h
3 *
4 * S390 version
5 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 *
7 * Derived from "include/asm-i386/semaphore-helper.h"
8 * (C) Copyright 1996 Linus Torvalds
9 * (C) Copyright 1999 Andrea Arcangeli
10 */
11
12 #ifndef _S390_SEMAPHORE_HELPER_H
13 #define _S390_SEMAPHORE_HELPER_H
14
15 /*
16 * These two _must_ execute atomically wrt each other.
17 *
18 * This is trivially done with load_locked/store_cond,
19 * but on the x86 we need an external synchronizer.
20 */
21 static inline void wake_one_more(struct semaphore * sem)
22 {
23 unsigned long flags;
24
25 spin_lock_irqsave(&semaphore_wake_lock, flags);
26 sem->waking++;
27 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
28 }
29
30 static inline int waking_non_zero(struct semaphore *sem)
31 {
32 unsigned long flags;
33 int ret = 0;
34
35 spin_lock_irqsave(&semaphore_wake_lock, flags);
36 if (sem->waking > 0) {
37 sem->waking--;
38 ret = 1;
39 }
40 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
41 return ret;
42 }
43
44 /*
45 * waking_non_zero_interruptible:
46 * 1 got the lock
47 * 0 go to sleep
48 * -EINTR interrupted
49 *
50 * If we give up we must undo our count-decrease we previously did in down().
51 * Subtle: up() can continue to happens and increase the semaphore count
52 * even during our critical section protected by the spinlock. So
53 * we must remeber to undo the sem->waking that will be run from
54 * wake_one_more() some time soon, if the semaphore count become > 0.
55 */
56 static inline int waking_non_zero_interruptible(struct semaphore *sem,
57 struct task_struct *tsk)
58 {
59 unsigned long flags;
60 int ret = 0;
61
62 spin_lock_irqsave(&semaphore_wake_lock, flags);
63 if (sem->waking > 0) {
64 sem->waking--;
65 ret = 1;
66 } else if (signal_pending(tsk)) {
67 if (atomic_inc_and_test_greater_zero(&sem->count))
68 sem->waking--;
69 ret = -EINTR;
70 }
71 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
72 return ret;
73 }
74
75 /*
76 * waking_non_zero_trylock:
77 * 1 failed to lock
78 * 0 got the lock
79 *
80 * Implementation details are the same of the interruptible case.
81 */
82 static inline int waking_non_zero_trylock(struct semaphore *sem)
83 {
84 unsigned long flags;
85 int ret = 1;
86
87 spin_lock_irqsave(&semaphore_wake_lock, flags);
88 if (sem->waking <= 0)
89 {
90 if (atomic_inc_and_test_greater_zero(&sem->count))
91 sem->waking--;
92 } else {
93 sem->waking--;
94 ret = 0;
95 }
96 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
97 return ret;
98 }
99
100 #endif
101
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.