Files
Linux/lib/memweight.c
T
Akinobu Mita 639b9e34f1 string: introduce memweight()
memweight() is the function that counts the total number of bits set in
memory area.  Unlike bitmap_weight(), memweight() takes pointer and size
in bytes to specify a memory area which does not need to be aligned to
long-word boundary.

[[email protected]: rename `w' to `ret']
Signed-off-by: Akinobu Mita <[email protected]>
Cc: Anders Larsen <[email protected]>
Cc: Alasdair Kergon <[email protected]>
Cc: Laurent Pinchart <[email protected]>
Cc: Mark Fasheh <[email protected]>
Cc: Joel Becker <[email protected]>
Cc: Jan Kara <[email protected]>
Cc: Andreas Dilger <[email protected]>
Cc: "Theodore Ts'o" <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Mauro Carvalho Chehab <[email protected]>
Cc: Tony Luck <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
2012-07-30 17:25:16 -07:00

39 lines
999 B
C

#include <linux/export.h>
#include <linux/bug.h>
#include <linux/bitmap.h>
/**
* memweight - count the total number of bits set in memory area
* @ptr: pointer to the start of the area
* @bytes: the size of the area
*/
size_t memweight(const void *ptr, size_t bytes)
{
size_t ret = 0;
size_t longs;
const unsigned char *bitmap = ptr;
for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long);
bytes--, bitmap++)
ret += hweight8(*bitmap);
longs = bytes / sizeof(long);
if (longs) {
BUG_ON(longs >= INT_MAX / BITS_PER_LONG);
ret += bitmap_weight((unsigned long *)bitmap,
longs * BITS_PER_LONG);
bytes -= longs * sizeof(long);
bitmap += longs * sizeof(long);
}
/*
* The reason that this last loop is distinct from the preceding
* bitmap_weight() call is to compute 1-bits in the last region smaller
* than sizeof(long) properly on big-endian systems.
*/
for (; bytes > 0; bytes--, bitmap++)
ret += hweight8(*bitmap);
return ret;
}
EXPORT_SYMBOL(memweight);