Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / include / asm-m68k / semaphore-helper.h
blob1516a642f9a57da31c0585a9f61eb1c9bc6841ed
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>
13 #include <linux/errno.h>
16 * These two _must_ execute atomically wrt each other.
18 static inline void wake_one_more(struct semaphore * sem)
20 atomic_inc(&sem->waking);
23 #ifndef CONFIG_RMW_INSNS
24 extern spinlock_t semaphore_wake_lock;
25 #endif
27 static inline int waking_non_zero(struct semaphore *sem)
29 int ret;
30 #ifndef CONFIG_RMW_INSNS
31 unsigned long flags;
33 spin_lock_irqsave(&semaphore_wake_lock, flags);
34 ret = 0;
35 if (atomic_read(&sem->waking) > 0) {
36 atomic_dec(&sem->waking);
37 ret = 1;
39 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
40 #else
41 int tmp1, tmp2;
43 __asm__ __volatile__
44 ("1: movel %1,%2\n"
45 " jle 2f\n"
46 " subql #1,%2\n"
47 " casl %1,%2,%3\n"
48 " jne 1b\n"
49 " moveq #1,%0\n"
50 "2:"
51 : "=d" (ret), "=d" (tmp1), "=d" (tmp2)
52 : "m" (sem->waking), "0" (0), "1" (sem->waking));
53 #endif
55 return ret;
59 * waking_non_zero_interruptible:
60 * 1 got the lock
61 * 0 go to sleep
62 * -EINTR interrupted
64 static inline int waking_non_zero_interruptible(struct semaphore *sem,
65 struct task_struct *tsk)
67 int ret;
68 #ifndef CONFIG_RMW_INSNS
69 unsigned long flags;
71 spin_lock_irqsave(&semaphore_wake_lock, flags);
72 ret = 0;
73 if (atomic_read(&sem->waking) > 0) {
74 atomic_dec(&sem->waking);
75 ret = 1;
76 } else if (signal_pending(tsk)) {
77 atomic_inc(&sem->count);
78 ret = -EINTR;
80 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
81 #else
82 int tmp1, tmp2;
84 __asm__ __volatile__
85 ("1: movel %1,%2\n"
86 " jle 2f\n"
87 " subql #1,%2\n"
88 " casl %1,%2,%3\n"
89 " jne 1b\n"
90 " moveq #1,%0\n"
91 " jra %a4\n"
92 "2:"
93 : "=d" (ret), "=d" (tmp1), "=d" (tmp2)
94 : "m" (sem->waking), "i" (&&next), "0" (0), "1" (sem->waking));
95 if (signal_pending(tsk)) {
96 atomic_inc(&sem->count);
97 ret = -EINTR;
99 next:
100 #endif
102 return ret;
106 * waking_non_zero_trylock:
107 * 1 failed to lock
108 * 0 got the lock
110 static inline int waking_non_zero_trylock(struct semaphore *sem)
112 int ret;
113 #ifndef CONFIG_RMW_INSNS
114 unsigned long flags;
116 spin_lock_irqsave(&semaphore_wake_lock, flags);
117 ret = 1;
118 if (atomic_read(&sem->waking) > 0) {
119 atomic_dec(&sem->waking);
120 ret = 0;
121 } else
122 atomic_inc(&sem->count);
123 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
124 #else
125 int tmp1, tmp2;
127 __asm__ __volatile__
128 ("1: movel %1,%2\n"
129 " jle 2f\n"
130 " subql #1,%2\n"
131 " casl %1,%2,%3\n"
132 " jne 1b\n"
133 " moveq #0,%0\n"
134 "2:"
135 : "=d" (ret), "=d" (tmp1), "=d" (tmp2)
136 : "m" (sem->waking), "0" (1), "1" (sem->waking));
137 if (ret)
138 atomic_inc(&sem->count);
139 #endif
140 return ret;
143 #endif