~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/include/linux/bitops.h

Version: ~ [ linux-5.9-rc6 ] ~ [ linux-5.8.10 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.66 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.146 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.198 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.236 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.236 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef _PERF_LINUX_BITOPS_H_
  2 #define _PERF_LINUX_BITOPS_H_
  3 
  4 #include <linux/kernel.h>
  5 #include <linux/compiler.h>
  6 #include <asm/hweight.h>
  7 
  8 #ifndef __WORDSIZE
  9 #define __WORDSIZE (__SIZEOF_LONG__ * 8)
 10 #endif
 11 
 12 #define BITS_PER_LONG __WORDSIZE
 13 #define BITS_PER_BYTE           8
 14 #define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
 15 #define BITS_TO_U64(nr)         DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64))
 16 #define BITS_TO_U32(nr)         DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32))
 17 #define BITS_TO_BYTES(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE)
 18 
 19 #define for_each_set_bit(bit, addr, size) \
 20         for ((bit) = find_first_bit((addr), (size));            \
 21              (bit) < (size);                                    \
 22              (bit) = find_next_bit((addr), (size), (bit) + 1))
 23 
 24 /* same as for_each_set_bit() but use bit as value to start with */
 25 #define for_each_set_bit_from(bit, addr, size) \
 26         for ((bit) = find_next_bit((addr), (size), (bit));      \
 27              (bit) < (size);                                    \
 28              (bit) = find_next_bit((addr), (size), (bit) + 1))
 29 
 30 static inline void set_bit(int nr, unsigned long *addr)
 31 {
 32         addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
 33 }
 34 
 35 static inline void clear_bit(int nr, unsigned long *addr)
 36 {
 37         addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
 38 }
 39 
 40 static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
 41 {
 42         return ((1UL << (nr % BITS_PER_LONG)) &
 43                 (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
 44 }
 45 
 46 static inline unsigned long hweight_long(unsigned long w)
 47 {
 48         return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
 49 }
 50 
 51 #define BITOP_WORD(nr)          ((nr) / BITS_PER_LONG)
 52 
 53 /**
 54  * __ffs - find first bit in word.
 55  * @word: The word to search
 56  *
 57  * Undefined if no bit exists, so code should check against 0 first.
 58  */
 59 static __always_inline unsigned long __ffs(unsigned long word)
 60 {
 61         int num = 0;
 62 
 63 #if BITS_PER_LONG == 64
 64         if ((word & 0xffffffff) == 0) {
 65                 num += 32;
 66                 word >>= 32;
 67         }
 68 #endif
 69         if ((word & 0xffff) == 0) {
 70                 num += 16;
 71                 word >>= 16;
 72         }
 73         if ((word & 0xff) == 0) {
 74                 num += 8;
 75                 word >>= 8;
 76         }
 77         if ((word & 0xf) == 0) {
 78                 num += 4;
 79                 word >>= 4;
 80         }
 81         if ((word & 0x3) == 0) {
 82                 num += 2;
 83                 word >>= 2;
 84         }
 85         if ((word & 0x1) == 0)
 86                 num += 1;
 87         return num;
 88 }
 89 
 90 /*
 91  * Find the first set bit in a memory region.
 92  */
 93 static inline unsigned long
 94 find_first_bit(const unsigned long *addr, unsigned long size)
 95 {
 96         const unsigned long *p = addr;
 97         unsigned long result = 0;
 98         unsigned long tmp;
 99 
100         while (size & ~(BITS_PER_LONG-1)) {
101                 if ((tmp = *(p++)))
102                         goto found;
103                 result += BITS_PER_LONG;
104                 size -= BITS_PER_LONG;
105         }
106         if (!size)
107                 return result;
108 
109         tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
110         if (tmp == 0UL)         /* Are any bits set? */
111                 return result + size;   /* Nope. */
112 found:
113         return result + __ffs(tmp);
114 }
115 
116 /*
117  * Find the next set bit in a memory region.
118  */
119 static inline unsigned long
120 find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset)
121 {
122         const unsigned long *p = addr + BITOP_WORD(offset);
123         unsigned long result = offset & ~(BITS_PER_LONG-1);
124         unsigned long tmp;
125 
126         if (offset >= size)
127                 return size;
128         size -= result;
129         offset %= BITS_PER_LONG;
130         if (offset) {
131                 tmp = *(p++);
132                 tmp &= (~0UL << offset);
133                 if (size < BITS_PER_LONG)
134                         goto found_first;
135                 if (tmp)
136                         goto found_middle;
137                 size -= BITS_PER_LONG;
138                 result += BITS_PER_LONG;
139         }
140         while (size & ~(BITS_PER_LONG-1)) {
141                 if ((tmp = *(p++)))
142                         goto found_middle;
143                 result += BITS_PER_LONG;
144                 size -= BITS_PER_LONG;
145         }
146         if (!size)
147                 return result;
148         tmp = *p;
149 
150 found_first:
151         tmp &= (~0UL >> (BITS_PER_LONG - size));
152         if (tmp == 0UL)         /* Are any bits set? */
153                 return result + size;   /* Nope. */
154 found_middle:
155         return result + __ffs(tmp);
156 }
157 
158 #endif
159 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp