Line data Source code
1 : #include <linux/export.h>
2 : #include <linux/bug.h>
3 : #include <linux/bitmap.h>
4 :
5 : /**
6 : * memweight - count the total number of bits set in memory area
7 : * @ptr: pointer to the start of the area
8 : * @bytes: the size of the area
9 : */
10 0 : size_t memweight(const void *ptr, size_t bytes)
11 : {
12 : size_t ret = 0;
13 : size_t longs;
14 : const unsigned char *bitmap = ptr;
15 :
16 0 : for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long);
17 0 : bytes--, bitmap++)
18 0 : ret += hweight8(*bitmap);
19 :
20 0 : longs = bytes / sizeof(long);
21 0 : if (longs) {
22 : BUG_ON(longs >= INT_MAX / BITS_PER_LONG);
23 0 : ret += bitmap_weight((unsigned long *)bitmap,
24 : longs * BITS_PER_LONG);
25 0 : bytes -= longs * sizeof(long);
26 0 : bitmap += longs * sizeof(long);
27 : }
28 : /*
29 : * The reason that this last loop is distinct from the preceding
30 : * bitmap_weight() call is to compute 1-bits in the last region smaller
31 : * than sizeof(long) properly on big-endian systems.
32 : */
33 0 : for (; bytes > 0; bytes--, bitmap++)
34 0 : ret += hweight8(*bitmap);
35 :
36 0 : return ret;
37 : }
38 : EXPORT_SYMBOL(memweight);
|