Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/export.h>
0003 #include <linux/bug.h>
0004 #include <linux/bitmap.h>
0005 
0006 /**
0007  * memweight - count the total number of bits set in memory area
0008  * @ptr: pointer to the start of the area
0009  * @bytes: the size of the area
0010  */
0011 size_t memweight(const void *ptr, size_t bytes)
0012 {
0013     size_t ret = 0;
0014     size_t longs;
0015     const unsigned char *bitmap = ptr;
0016 
0017     for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long);
0018             bytes--, bitmap++)
0019         ret += hweight8(*bitmap);
0020 
0021     longs = bytes / sizeof(long);
0022     if (longs) {
0023         BUG_ON(longs >= INT_MAX / BITS_PER_LONG);
0024         ret += bitmap_weight((unsigned long *)bitmap,
0025                 longs * BITS_PER_LONG);
0026         bytes -= longs * sizeof(long);
0027         bitmap += longs * sizeof(long);
0028     }
0029     /*
0030      * The reason that this last loop is distinct from the preceding
0031      * bitmap_weight() call is to compute 1-bits in the last region smaller
0032      * than sizeof(long) properly on big-endian systems.
0033      */
0034     for (; bytes > 0; bytes--, bitmap++)
0035         ret += hweight8(*bitmap);
0036 
0037     return ret;
0038 }
0039 EXPORT_SYMBOL(memweight);