Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp805586imm; Tue, 15 May 2018 09:24:58 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqwFD9ncFUX8INWi9IBY4Nr4y7y3GCt89T6KoNC0qI1T1ZRnUGMLLfJyLFyrLhSnu5AvzZM X-Received: by 2002:a62:ec18:: with SMTP id k24-v6mr15877022pfh.204.1526401498751; Tue, 15 May 2018 09:24:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526401498; cv=none; d=google.com; s=arc-20160816; b=w7s1OWnUotAxaD3MEj1lrRcq6yepyUyMHLhcT5TRdnuJn6q6ehf5HtO7s2f8qFKrZV AtqXRzUja/mI95x6D1yd+9mawZ9GlP7IDZHwSAnfPyFOx3ENKLk0hWq7exANbIRnvkiy XXY78hV7vo4Ja1ZU3y6ZoQUFjhuf2nU9Yh+qrF+Lg6YCaGA+fFjBAAW2VscN/UMbWolZ w/Ynfipy5qL2rJAC7+xMNDquWCsgcvX6qihvboJgHrX7zsVZGE92li+WZApEr06bn33m 447/h8GkAyl9Csxm9HOMwhTzOf6249hR+va6K8/UthVQWWCjJJ8bVRWhW7Z5CYrHBuo3 xENg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=zXWx52J09B2XRIIWL2fJqPQYDuMBxPhU30oY293qaME=; b=EvUshTdttuJu8F/tnBB35A2ErOD9y9RQJCFc3XEyKUeCouUI75ZFQNc6YwQLUJjYPv D4A0UB4lWA6p4sdm8kLhPl1bCsA6qRs8FoniByBNsVJ0JYGzea0TzNAVQMjrpsYdy6WM jOGALRdpQxzV/wZ97h3X6nfFngwlxov8iGQNzT72WEYf181nsC/pJUokeDsPnL/m+zgn tpbZrh7D4rDpaiOn5t28ulTzwKEANDUV6qAnv0FzPt32uNDPAr0bAmVcc9SxwQ/Dip3d fHf3mdhi80MheYPMnCfU0vGR2ctjkSGZ7v87pJiUmiu3s5Ss60+sMM1xV3SYhHBAGNZ3 FgjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=WWqNbXJL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l81-v6si404727pfj.127.2018.05.15.09.24.25; Tue, 15 May 2018 09:24:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=WWqNbXJL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753734AbeEOQWf (ORCPT + 99 others); Tue, 15 May 2018 12:22:35 -0400 Received: from mail-yb0-f193.google.com ([209.85.213.193]:33988 "EHLO mail-yb0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753169AbeEOQWd (ORCPT ); Tue, 15 May 2018 12:22:33 -0400 Received: by mail-yb0-f193.google.com with SMTP id i1-v6so260214ybe.1; Tue, 15 May 2018 09:22:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zXWx52J09B2XRIIWL2fJqPQYDuMBxPhU30oY293qaME=; b=WWqNbXJLI9rq4GUn54LE/T+RMmUb5qKQ8QKBWfyrS/jgA9BpNwU3jxvv9pGwFHjEuv rwsWwUWFPpVD0/cVETOfz0S/AYB4siQVHr/0HbihrR407NUqigc3ONZIKaIzpTLDpF+8 u/V36P3Y25zwe2XHyvmLbDDLfWkNUd/oYEzbU/ifQD6p/8fLJ96qQ4jcrx3TKwxNoBLe LZcD9QKCZ0yc4Fc6BoipKhUvQ1ApuleJcJxVhFRso4d6kaYcuxGxPmY51/4/qAPMu4dO 7cNpSIzWu/OmhGC8jN95MjoNU9tfJ0PxEqU/mbQ1uokaXj2OnxlBBDMxuARvyJlGTB3s pmiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zXWx52J09B2XRIIWL2fJqPQYDuMBxPhU30oY293qaME=; b=qV7AbcU9FTr1IbJ7KngCZ67MTKycdDpm5HodBmgMm0/7vgWywkbbC0aLQKULC+va0b mJiJjKEH1n1oeDTlkRnNGEZafHxFlnchvix+BiD5ahc9BpDvUuMWhkyfEIo02b1Zx0am ARbAv77TIexp0b8jaS9AP/T2F510dGDGH/xzglWCAPUc2gBQ55A7GVf73GvwTup1Lm89 lI9+KeL4+83xmKbzbsjvUy2jlHv6i2EXq49SoBWygqs301MyJ/CyVXzmctNAapXI1rSJ 5oknVpsIO98CNjz+7+NlW48gT+nNXhDT8fS0lSVseYGPr6V86VaZmHKc4MzD7pr+2x9e 1h0A== X-Gm-Message-State: ALKqPwcJtSxKVcydersloRDU+5Q8l1oq4Gtem3TAdd5nxCfA0Y3q/8Y8 31jLNl4olPL9Nj31yYkdheI= X-Received: by 2002:a25:51c9:: with SMTP id f192-v6mr8828470ybb.288.1526401352353; Tue, 15 May 2018 09:22:32 -0700 (PDT) Received: from localhost ([72.188.97.40]) by smtp.gmail.com with ESMTPSA id r81-v6sm156289ywb.13.2018.05.15.09.22.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 15 May 2018 09:22:31 -0700 (PDT) From: William Breathitt Gray To: linus.walleij@linaro.org Cc: linux-gpio@vger.kernel.org, linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org, William Breathitt Gray , Arnd Bergmann Subject: [PATCH v4 1/8] bitops: Introduce the for_each_set_clump macro Date: Tue, 15 May 2018 12:22:26 -0400 Message-Id: <87c7edee3bd6789345bd1cc6fd0cb91c2d508eda.1526400945.git.vilhelm.gray@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This macro iterates for each group of bits (clump) with set bits, within a bitmap memory region. For each iteration, "clump" is set to the found clump index, "index" is set to the word index of the bitmap containing the found clump, and "offset" is set to the bit offset of the found clump within the respective bitmap word. Suggested-by: Andy Shevchenko Cc: Arnd Bergmann Signed-off-by: William Breathitt Gray --- include/asm-generic/bitops/find.h | 9 +++++++ include/linux/bitops.h | 7 ++++++ lib/find_bit.c | 40 +++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/include/asm-generic/bitops/find.h b/include/asm-generic/bitops/find.h index 8a1ee10014de..3d3b2fc34908 100644 --- a/include/asm-generic/bitops/find.h +++ b/include/asm-generic/bitops/find.h @@ -2,6 +2,8 @@ #ifndef _ASM_GENERIC_BITOPS_FIND_H_ #define _ASM_GENERIC_BITOPS_FIND_H_ +#include + #ifndef find_next_bit /** * find_next_bit - find the next set bit in a memory region @@ -80,4 +82,11 @@ extern unsigned long find_first_zero_bit(const unsigned long *addr, #endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ +size_t find_next_clump(size_t *const index, unsigned int *const offset, + const unsigned long *const bits, const size_t size, + const size_t clump_index, const unsigned int clump_size); + +#define find_first_clump(index, offset, bits, size, clump_size) \ + find_next_clump((index), (offset), (bits), (size), 0, (clump_size)) + #endif /*_ASM_GENERIC_BITOPS_FIND_H_ */ diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 4cac4e1a72ff..cfaff6a14406 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -59,6 +59,13 @@ extern unsigned long __sw_hweight64(__u64 w); (bit) < (size); \ (bit) = find_next_zero_bit((addr), (size), (bit) + 1)) +#define for_each_set_clump(clump, index, offset, bits, size, clump_size) \ + for ((clump) = find_first_clump(&(index), &(offset), (bits), (size), \ + (clump_size)); \ + (clump) < (size); \ + (clump) = find_next_clump(&(index), &(offset), (bits), (size), \ + (clump) + 1, (clump_size))) + static inline int get_bitmask_order(unsigned int count) { int order; diff --git a/lib/find_bit.c b/lib/find_bit.c index ee3df93ba69a..1d547fe9304f 100644 --- a/lib/find_bit.c +++ b/lib/find_bit.c @@ -218,3 +218,43 @@ EXPORT_SYMBOL(find_next_bit_le); #endif #endif /* __BIG_ENDIAN */ + +/** + * find_next_clump - find next clump with set bits in a memory region + * @index: location to store bitmap word index of found clump + * @offset: bits offset of the found clump within the respective bitmap word + * @bits: address to base the search on + * @size: bitmap size in number of clumps + * @clump_index: clump index at which to start searching + * @clump_size: clump size in bits + * + * Returns the clump index for the next clump with set bits; the respective + * bitmap word index is stored at the location pointed by @index, and the bits + * offset of the found clump within the respective bitmap word is stored at the + * location pointed by @offset. If no bits are set, returns @size. + */ +size_t find_next_clump(size_t *const index, unsigned int *const offset, + const unsigned long *const bits, const size_t size, + const size_t clump_index, const unsigned int clump_size) +{ + size_t i; + unsigned int bits_offset; + unsigned long word_mask; + const unsigned long clump_mask = GENMASK(clump_size - 1, 0); + + for (i = clump_index; i < size; i++) { + bits_offset = i * clump_size; + + *index = BIT_WORD(bits_offset); + *offset = bits_offset % BITS_PER_LONG; + + word_mask = bits[*index] & (clump_mask << *offset); + if (!word_mask) + continue; + + return i; + } + + return size; +} +EXPORT_SYMBOL(find_next_clump); -- 2.17.0