Branch data 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 : : size_t ret = 0; 14 : : size_t longs; 15 : : 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);