From patchwork Mon Jun 11 23:17:25 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v3,1/9] string: introduce memweight From: Andrew Morton X-Patchwork-Id: 164290 Message-Id: <20120611161725.84330925.akpm@linux-foundation.org> To: Akinobu Mita Cc: linux-kernel@vger.kernel.org, Anders Larsen , Alasdair Kergon , dm-devel@redhat.com, linux-fsdevel@vger.kernel.org, Laurent Pinchart , linux-media@vger.kernel.org, Mark Fasheh , Joel Becker , ocfs2-devel@oss.oracle.com, Jan Kara , linux-ext4@vger.kernel.org, Andreas Dilger , "Theodore Ts'o" , Matthew Wilcox Date: Mon, 11 Jun 2012 16:17:25 -0700 On Sat, 9 Jun 2012 09:50:30 +0900 Akinobu Mita wrote: > 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. > > ... > > +/** > + * 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 w = 0; Calling the return value "ret" is a useful convention and fits well here. > + size_t longs; > + const unsigned char *bitmap = ptr; > + > + for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long); > + bytes--, bitmap++) > + w += hweight8(*bitmap); > + > + longs = bytes / sizeof(long); > + if (longs) { > + BUG_ON(longs >= INT_MAX / BITS_PER_LONG); > + w += 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++) > + w += hweight8(*bitmap); > + > + return w; > +} > +EXPORT_SYMBOL(memweight); diff -puN lib/string.c~string-introduce-memweight-fix lib/string.c --- a/lib/string.c~string-introduce-memweight-fix +++ a/lib/string.c @@ -833,18 +833,18 @@ EXPORT_SYMBOL(memchr_inv); */ size_t memweight(const void *ptr, size_t bytes) { - size_t w = 0; + size_t ret = 0; size_t longs; const unsigned char *bitmap = ptr; for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long); bytes--, bitmap++) - w += hweight8(*bitmap); + ret += hweight8(*bitmap); longs = bytes / sizeof(long); if (longs) { BUG_ON(longs >= INT_MAX / BITS_PER_LONG); - w += bitmap_weight((unsigned long *)bitmap, + ret += bitmap_weight((unsigned long *)bitmap, longs * BITS_PER_LONG); bytes -= longs * sizeof(long); bitmap += longs * sizeof(long); @@ -855,8 +855,8 @@ size_t memweight(const void *ptr, size_t * than sizeof(long) properly on big-endian systems. */ for (; bytes > 0; bytes--, bitmap++) - w += hweight8(*bitmap); + ret += hweight8(*bitmap); - return w; + return ret; } EXPORT_SYMBOL(memweight);