[PATCH] bitops: use non atomic operations for minix_*_bit() and ext2_*_bit()
[linux-3.10.git] / include / asm-sparc64 / bitops.h
1 /* $Id: bitops.h,v 1.39 2002/01/30 01:40:00 davem Exp $
2  * bitops.h: Bit string operations on the V9.
3  *
4  * Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
5  */
6
7 #ifndef _SPARC64_BITOPS_H
8 #define _SPARC64_BITOPS_H
9
10 #include <linux/config.h>
11 #include <linux/compiler.h>
12 #include <asm/byteorder.h>
13
14 extern int test_and_set_bit(unsigned long nr, volatile unsigned long *addr);
15 extern int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr);
16 extern int test_and_change_bit(unsigned long nr, volatile unsigned long *addr);
17 extern void set_bit(unsigned long nr, volatile unsigned long *addr);
18 extern void clear_bit(unsigned long nr, volatile unsigned long *addr);
19 extern void change_bit(unsigned long nr, volatile unsigned long *addr);
20
21 /* "non-atomic" versions... */
22
23 static inline void __set_bit(int nr, volatile unsigned long *addr)
24 {
25         unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
26
27         *m |= (1UL << (nr & 63));
28 }
29
30 static inline void __clear_bit(int nr, volatile unsigned long *addr)
31 {
32         unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
33
34         *m &= ~(1UL << (nr & 63));
35 }
36
37 static inline void __change_bit(int nr, volatile unsigned long *addr)
38 {
39         unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
40
41         *m ^= (1UL << (nr & 63));
42 }
43
44 static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
45 {
46         unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
47         unsigned long old = *m;
48         unsigned long mask = (1UL << (nr & 63));
49
50         *m = (old | mask);
51         return ((old & mask) != 0);
52 }
53
54 static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
55 {
56         unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
57         unsigned long old = *m;
58         unsigned long mask = (1UL << (nr & 63));
59
60         *m = (old & ~mask);
61         return ((old & mask) != 0);
62 }
63
64 static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
65 {
66         unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
67         unsigned long old = *m;
68         unsigned long mask = (1UL << (nr & 63));
69
70         *m = (old ^ mask);
71         return ((old & mask) != 0);
72 }
73
74 #ifdef CONFIG_SMP
75 #define smp_mb__before_clear_bit()      membar_storeload_loadload()
76 #define smp_mb__after_clear_bit()       membar_storeload_storestore()
77 #else
78 #define smp_mb__before_clear_bit()      barrier()
79 #define smp_mb__after_clear_bit()       barrier()
80 #endif
81
82 static inline int test_bit(int nr, __const__ volatile unsigned long *addr)
83 {
84         return (1UL & (addr[nr >> 6] >> (nr & 63))) != 0UL;
85 }
86
87 /* The easy/cheese version for now. */
88 static inline unsigned long ffz(unsigned long word)
89 {
90         unsigned long result;
91
92         result = 0;
93         while(word & 1) {
94                 result++;
95                 word >>= 1;
96         }
97         return result;
98 }
99
100 /**
101  * __ffs - find first bit in word.
102  * @word: The word to search
103  *
104  * Undefined if no bit exists, so code should check against 0 first.
105  */
106 static inline unsigned long __ffs(unsigned long word)
107 {
108         unsigned long result = 0;
109
110         while (!(word & 1UL)) {
111                 result++;
112                 word >>= 1;
113         }
114         return result;
115 }
116
117 /*
118  * fls: find last bit set.
119  */
120
121 #define fls(x) generic_fls(x)
122 #define fls64(x)   generic_fls64(x)
123
124 #ifdef __KERNEL__
125
126 /*
127  * Every architecture must define this function. It's the fastest
128  * way of searching a 140-bit bitmap where the first 100 bits are
129  * unlikely to be set. It's guaranteed that at least one of the 140
130  * bits is cleared.
131  */
132 static inline int sched_find_first_bit(unsigned long *b)
133 {
134         if (unlikely(b[0]))
135                 return __ffs(b[0]);
136         if (unlikely(((unsigned int)b[1])))
137                 return __ffs(b[1]) + 64;
138         if (b[1] >> 32)
139                 return __ffs(b[1] >> 32) + 96;
140         return __ffs(b[2]) + 128;
141 }
142
143 /*
144  * ffs: find first bit set. This is defined the same way as
145  * the libc and compiler builtin ffs routines, therefore
146  * differs in spirit from the above ffz (man ffs).
147  */
148 static inline int ffs(int x)
149 {
150         if (!x)
151                 return 0;
152         return __ffs((unsigned long)x) + 1;
153 }
154
155 /*
156  * hweightN: returns the hamming weight (i.e. the number
157  * of bits set) of a N-bit word
158  */
159
160 #ifdef ULTRA_HAS_POPULATION_COUNT
161
162 static inline unsigned int hweight64(unsigned long w)
163 {
164         unsigned int res;
165
166         __asm__ ("popc %1,%0" : "=r" (res) : "r" (w));
167         return res;
168 }
169
170 static inline unsigned int hweight32(unsigned int w)
171 {
172         unsigned int res;
173
174         __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff));
175         return res;
176 }
177
178 static inline unsigned int hweight16(unsigned int w)
179 {
180         unsigned int res;
181
182         __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff));
183         return res;
184 }
185
186 static inline unsigned int hweight8(unsigned int w)
187 {
188         unsigned int res;
189
190         __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff));
191         return res;
192 }
193
194 #else
195
196 #define hweight64(x) generic_hweight64(x)
197 #define hweight32(x) generic_hweight32(x)
198 #define hweight16(x) generic_hweight16(x)
199 #define hweight8(x) generic_hweight8(x)
200
201 #endif
202 #endif /* __KERNEL__ */
203
204 /**
205  * find_next_bit - find the next set bit in a memory region
206  * @addr: The address to base the search on
207  * @offset: The bitnumber to start searching at
208  * @size: The maximum size to search
209  */
210 extern unsigned long find_next_bit(const unsigned long *, unsigned long,
211                                         unsigned long);
212
213 /**
214  * find_first_bit - find the first set bit in a memory region
215  * @addr: The address to start the search at
216  * @size: The maximum size to search
217  *
218  * Returns the bit-number of the first set bit, not the number of the byte
219  * containing a bit.
220  */
221 #define find_first_bit(addr, size) \
222         find_next_bit((addr), (size), 0)
223
224 /* find_next_zero_bit() finds the first zero bit in a bit string of length
225  * 'size' bits, starting the search at bit 'offset'. This is largely based
226  * on Linus's ALPHA routines, which are pretty portable BTW.
227  */
228
229 extern unsigned long find_next_zero_bit(const unsigned long *,
230                                         unsigned long, unsigned long);
231
232 #define find_first_zero_bit(addr, size) \
233         find_next_zero_bit((addr), (size), 0)
234
235 #define test_and_set_le_bit(nr,addr)    \
236         test_and_set_bit((nr) ^ 0x38, (addr))
237 #define test_and_clear_le_bit(nr,addr)  \
238         test_and_clear_bit((nr) ^ 0x38, (addr))
239
240 static inline int test_le_bit(int nr, __const__ unsigned long * addr)
241 {
242         int                     mask;
243         __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
244
245         ADDR += nr >> 3;
246         mask = 1 << (nr & 0x07);
247         return ((mask & *ADDR) != 0);
248 }
249
250 #define find_first_zero_le_bit(addr, size) \
251         find_next_zero_le_bit((addr), (size), 0)
252
253 extern unsigned long find_next_zero_le_bit(unsigned long *, unsigned long, unsigned long);
254
255 #ifdef __KERNEL__
256
257 #define __set_le_bit(nr, addr) \
258         __set_bit((nr) ^ 0x38, (addr))
259 #define __clear_le_bit(nr, addr) \
260         __clear_bit((nr) ^ 0x38, (addr))
261 #define __test_and_clear_le_bit(nr, addr) \
262         __test_and_clear_bit((nr) ^ 0x38, (addr))
263 #define __test_and_set_le_bit(nr, addr) \
264         __test_and_set_bit((nr) ^ 0x38, (addr))
265
266 #define ext2_set_bit(nr,addr)   \
267         __test_and_set_le_bit((nr),(unsigned long *)(addr))
268 #define ext2_set_bit_atomic(lock,nr,addr) \
269         test_and_set_le_bit((nr),(unsigned long *)(addr))
270 #define ext2_clear_bit(nr,addr) \
271         __test_and_clear_le_bit((nr),(unsigned long *)(addr))
272 #define ext2_clear_bit_atomic(lock,nr,addr) \
273         test_and_clear_le_bit((nr),(unsigned long *)(addr))
274 #define ext2_test_bit(nr,addr)  \
275         test_le_bit((nr),(unsigned long *)(addr))
276 #define ext2_find_first_zero_bit(addr, size) \
277         find_first_zero_le_bit((unsigned long *)(addr), (size))
278 #define ext2_find_next_zero_bit(addr, size, off) \
279         find_next_zero_le_bit((unsigned long *)(addr), (size), (off))
280
281 /* Bitmap functions for the minix filesystem.  */
282 #define minix_test_and_set_bit(nr,addr) \
283         __test_and_set_bit((nr),(unsigned long *)(addr))
284 #define minix_set_bit(nr,addr)  \
285         __set_bit((nr),(unsigned long *)(addr))
286 #define minix_test_and_clear_bit(nr,addr) \
287         __test_and_clear_bit((nr),(unsigned long *)(addr))
288 #define minix_test_bit(nr,addr) \
289         test_bit((nr),(unsigned long *)(addr))
290 #define minix_find_first_zero_bit(addr,size) \
291         find_first_zero_bit((unsigned long *)(addr),(size))
292
293 #endif /* __KERNEL__ */
294
295 #endif /* defined(_SPARC64_BITOPS_H) */