Line data Source code
1 : #ifndef __BITOPS_H__
2 : #define __BITOPS_H__
3 :
4 : /*
5 : * Non-atomic bitops.
6 : */
7 :
8 : #include <stdbool.h>
9 : #include <bits/wordsize.h>
10 :
11 : #define BITS_PER_LONG __WORDSIZE
12 : #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
13 : #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
14 :
15 : #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
16 : #define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
17 : #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
18 :
19 : static inline void __set_bit(int nr, volatile unsigned long *addr)
20 : {
21 148238006 : unsigned long mask = BIT_MASK(nr);
22 148238006 : unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
23 :
24 148238006 : *p |= mask;
25 : }
26 :
27 : static inline void set_bit(int nr, volatile unsigned long *addr)
28 : {
29 145657373 : __set_bit(nr, addr);
30 : }
31 :
32 : static inline void __clear_bit(int nr, volatile unsigned long *addr)
33 : {
34 4752341 : unsigned long mask = BIT_MASK(nr);
35 4752341 : unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
36 :
37 4752341 : *p &= ~mask;
38 : }
39 :
40 : static inline void clear_bit(int nr, volatile unsigned long *addr)
41 : {
42 1426678 : __clear_bit(nr, addr);
43 : }
44 :
45 : static inline bool test_bit(int nr, const volatile unsigned long *addr)
46 : {
47 6967274119 : unsigned long mask = BIT_MASK(nr);
48 6967274119 : unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
49 :
50 6967274119 : return (*p & mask) != 0;
51 : }
52 :
53 : /* Sets and returns original value of the bit */
54 : static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
55 : {
56 115585472 : if (test_bit(nr, addr))
57 : return 1;
58 2562098 : set_bit(nr, addr);
59 : return 0;
60 : }
61 :
62 : /**
63 : * fls - find last (most-significant) bit set
64 : * @x: the word to search
65 : *
66 : * This is defined the same way as ffs.
67 : * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
68 : */
69 19300 : static inline int fls(int x)
70 : {
71 19300 : int r = 32;
72 :
73 19300 : if (!x)
74 : return 0;
75 19300 : if (!(x & 0xffff0000u)) {
76 15258 : x <<= 16;
77 15258 : r -= 16;
78 : }
79 19300 : if (!(x & 0xff000000u)) {
80 11061 : x <<= 8;
81 11061 : r -= 8;
82 : }
83 19300 : if (!(x & 0xf0000000u)) {
84 13458 : x <<= 4;
85 13458 : r -= 4;
86 : }
87 19300 : if (!(x & 0xc0000000u)) {
88 11914 : x <<= 2;
89 11914 : r -= 2;
90 : }
91 19300 : if (!(x & 0x80000000u)) {
92 8210 : x <<= 1;
93 8210 : r -= 1;
94 : }
95 : return r;
96 : }
97 :
98 : /**
99 : * __ffs - find first bit in word.
100 : * @word: The word to search
101 : *
102 : * Undefined if no bit exists, so code should check against 0 first.
103 : */
104 19640 : static inline unsigned long __ffs(unsigned long word)
105 : {
106 19640 : int num = 0;
107 :
108 : #if BITS_PER_LONG == 64
109 19640 : if ((word & 0xffffffff) == 0) {
110 9452 : num += 32;
111 9452 : word >>= 32;
112 : }
113 : #endif
114 19640 : if ((word & 0xffff) == 0) {
115 9643 : num += 16;
116 9643 : word >>= 16;
117 : }
118 19640 : if ((word & 0xff) == 0) {
119 9595 : num += 8;
120 9595 : word >>= 8;
121 : }
122 19640 : if ((word & 0xf) == 0) {
123 9679 : num += 4;
124 9679 : word >>= 4;
125 : }
126 19640 : if ((word & 0x3) == 0) {
127 9694 : num += 2;
128 9694 : word >>= 2;
129 : }
130 19640 : if ((word & 0x1) == 0)
131 9628 : num += 1;
132 19640 : return num;
133 : }
134 :
135 : unsigned long _find_next_bit(const unsigned long *addr,
136 : unsigned long nbits, unsigned long start, unsigned long invert);
137 :
138 : /*
139 : * Find the next set bit in a memory region.
140 : */
141 : static inline unsigned long find_next_bit(const unsigned long *addr,
142 : unsigned long size, unsigned long offset)
143 : {
144 : return _find_next_bit(addr, size, offset, 0UL);
145 : }
146 :
147 : static inline unsigned long find_next_zero_bit(const unsigned long *addr,
148 : unsigned long size, unsigned long offset)
149 : {
150 19640 : return _find_next_bit(addr, size, offset, ~0UL);
151 : }
152 :
153 : #endif
|