]> asedeno.scripts.mit.edu Git - linux.git/blob - tools/testing/radix-tree/linux/bitops/non-atomic.h
radix tree test suite: use common find-bit code
[linux.git] / tools / testing / radix-tree / linux / bitops / non-atomic.h
1 #ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
2 #define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
3
4 #include <asm/types.h>
5
6 #define BITOP_WORD(nr)          ((nr) / BITS_PER_LONG)
7
8 /**
9  * __set_bit - Set a bit in memory
10  * @nr: the bit to set
11  * @addr: the address to start counting from
12  *
13  * Unlike set_bit(), this function is non-atomic and may be reordered.
14  * If it's called on the same region of memory simultaneously, the effect
15  * may be that only one operation succeeds.
16  */
17 static inline void __set_bit(int nr, volatile unsigned long *addr)
18 {
19         unsigned long mask = BIT_MASK(nr);
20         unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
21
22         *p  |= mask;
23 }
24
25 static inline void __clear_bit(int nr, volatile unsigned long *addr)
26 {
27         unsigned long mask = BIT_MASK(nr);
28         unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
29
30         *p &= ~mask;
31 }
32
33 /**
34  * __change_bit - Toggle a bit in memory
35  * @nr: the bit to change
36  * @addr: the address to start counting from
37  *
38  * Unlike change_bit(), this function is non-atomic and may be reordered.
39  * If it's called on the same region of memory simultaneously, the effect
40  * may be that only one operation succeeds.
41  */
42 static inline void __change_bit(int nr, volatile unsigned long *addr)
43 {
44         unsigned long mask = BIT_MASK(nr);
45         unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
46
47         *p ^= mask;
48 }
49
50 /**
51  * __test_and_set_bit - Set a bit and return its old value
52  * @nr: Bit to set
53  * @addr: Address to count from
54  *
55  * This operation is non-atomic and can be reordered.
56  * If two examples of this operation race, one can appear to succeed
57  * but actually fail.  You must protect multiple accesses with a lock.
58  */
59 static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
60 {
61         unsigned long mask = BIT_MASK(nr);
62         unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
63         unsigned long old = *p;
64
65         *p = old | mask;
66         return (old & mask) != 0;
67 }
68
69 /**
70  * __test_and_clear_bit - Clear a bit and return its old value
71  * @nr: Bit to clear
72  * @addr: Address to count from
73  *
74  * This operation is non-atomic and can be reordered.
75  * If two examples of this operation race, one can appear to succeed
76  * but actually fail.  You must protect multiple accesses with a lock.
77  */
78 static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
79 {
80         unsigned long mask = BIT_MASK(nr);
81         unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
82         unsigned long old = *p;
83
84         *p = old & ~mask;
85         return (old & mask) != 0;
86 }
87
88 /* WARNING: non atomic and it can be reordered! */
89 static inline int __test_and_change_bit(int nr,
90                                             volatile unsigned long *addr)
91 {
92         unsigned long mask = BIT_MASK(nr);
93         unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
94         unsigned long old = *p;
95
96         *p = old ^ mask;
97         return (old & mask) != 0;
98 }
99
100 /**
101  * test_bit - Determine whether a bit is set
102  * @nr: bit number to test
103  * @addr: Address to start counting from
104  */
105 static inline int test_bit(int nr, const volatile unsigned long *addr)
106 {
107         return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
108 }
109
110 #endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */