linux/lib/memweight.c
<<
>>
Prefs
   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);
  40