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