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