memweight.c (1035B)
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 */ 11size_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 for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long); 18 bytes--, bitmap++) 19 ret += hweight8(*bitmap); 20 21 longs = bytes / sizeof(long); 22 if (longs) { 23 BUG_ON(longs >= INT_MAX / BITS_PER_LONG); 24 ret += bitmap_weight((unsigned long *)bitmap, 25 longs * BITS_PER_LONG); 26 bytes -= longs * sizeof(long); 27 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 for (; bytes > 0; bytes--, bitmap++) 35 ret += hweight8(*bitmap); 36 37 return ret; 38} 39EXPORT_SYMBOL(memweight);