Linux 2.3.1pre3
[davej-history.git] / include / asm-m68k / semaphore-helper.h
blob0ae0b97059fe9e2b396086c7e9b3fb394515892a
1 #ifndef _M68K_SEMAPHORE_HELPER_H
2 #define _M68K_SEMAPHORE_HELPER_H
4 /*
5 * SMP- and interrupt-safe semaphores helper functions.
7 * (C) Copyright 1996 Linus Torvalds
9 * m68k version by Andreas Schwab
12 #include <linux/config.h>
15 * These two _must_ execute atomically wrt each other.
17 static inline void wake_one_more(struct semaphore * sem)
19 atomic_inc(&sem->waking);
22 static inline int waking_non_zero(struct semaphore *sem)
24 int ret;
25 #ifndef CONFIG_RMW_INSNS
26 unsigned long flags;
28 spin_lock_irqsave(&semaphore_wake_lock, flags);
29 ret = 0;
30 if (atomic_read(&sem->waking) > 0) {
31 atomic_dec(&sem->waking);
32 ret = 1;
34 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
35 #else
36 int tmp1, tmp2;
38 __asm__ __volatile__
39 ("1: movel %1,%2\n"
40 " jle 2f\n"
41 " subql #1,%2\n"
42 " casl %1,%2,%3\n"
43 " jne 1b\n"
44 " moveq #1,%0\n"
45 "2:"
46 : "=d" (ret), "=d" (tmp1), "=d" (tmp2)
47 : "m" (sem->waking), "0" (0), "1" (sem->waking));
48 #endif
50 return ret;
54 * waking_non_zero_interruptible:
55 * 1 got the lock
56 * 0 go to sleep
57 * -EINTR interrupted
59 static inline int waking_non_zero_interruptible(struct semaphore *sem,
60 struct task_struct *tsk)
62 int ret;
63 #ifndef CONFIG_RMW_INSNS
64 unsigned long flags;
66 spin_lock_irqsave(&semaphore_wake_lock, flags);
67 ret = 0;
68 if (atomic_read(&sem->waking) > 0) {
69 atomic_dec(&sem->waking);
70 ret = 1;
71 } else if (signal_pending(tsk)) {
72 atomic_inc(&sem->count);
73 ret = -EINTR;
75 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
76 #else
77 int tmp1, tmp2;
79 __asm__ __volatile__
80 ("1: movel %1,%2\n"
81 " jle 2f\n"
82 " subql #1,%2\n"
83 " casl %1,%2,%3\n"
84 " jne 1b\n"
85 " moveq #1,%0\n"
86 " jra %a4\n"
87 "2:"
88 : "=d" (ret), "=d" (tmp1), "=d" (tmp2)
89 : "m" (sem->waking), "i" (&&next), "0" (0), "1" (sem->waking));
90 if (signal_pending(tsk)) {
91 atomic_inc(&sem->count);
92 ret = -EINTR;
94 next:
95 #endif
97 return ret;
101 * waking_non_zero_trylock:
102 * 1 failed to lock
103 * 0 got the lock
105 static inline int waking_non_zero_trylock(struct semaphore *sem)
107 int ret;
108 #ifndef CONFIG_RMW_INSNS
109 unsigned long flags;
111 spin_lock_irqsave(&semaphore_wake_lock, flags);
112 ret = 1;
113 if (atomic_read(&sem->waking) > 0) {
114 atomic_dec(&sem->waking);
115 ret = 0;
116 } else
117 atomic_inc(&sem->count);
118 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
119 #else
120 int tmp1, tmp2;
122 __asm__ __volatile__
123 ("1: movel %1,%2\n"
124 " jle 2f\n"
125 " subql #1,%2\n"
126 " casl %1,%2,%3\n"
127 " jne 1b\n"
128 " moveq #0,%0\n"
129 "2:"
130 : "=d" (ret), "=d" (tmp1), "=d" (tmp2)
131 : "m" (sem->waking), "0" (1), "1" (sem->waking));
132 if (ret)
133 atomic_inc(&sem->count);
134 #endif
135 return ret;
138 #endif