Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp771043imm; Tue, 15 May 2018 08:57:55 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqvy44JAk9bEufKNYg6cWxg+LuviusbqyHZuJRPVjzEFHcviRcGMOhOc2RP82Gly1pczPFl X-Received: by 2002:a17:902:8218:: with SMTP id x24-v6mr14978969pln.57.1526399875825; Tue, 15 May 2018 08:57:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526399875; cv=none; d=google.com; s=arc-20160816; b=OtRG94sjA4dIyvD9uB5hI/t6N7Vbj1hycknifLRaOgG1cx/c6t1A1Zb5DbWKkncN6B Dn7Lbg5FXq1hhSD+wcoWOGegR6achgoAYETO8fXesrVP8uNGYC7/IQeFy7RsbKt89EOl j021RwQ8oX13B0t7d4CXguMmpkKhnfJz1c4aqjBpcio3h5SX33baVk9yHEZcuX4nTbqy q+FGap8ho4967Pnu4iu6Q7ikq2xnpt4azOytZwA5shI5nr1FSTx1nqjo21wkMzT6MtKJ Dolaej9f8nc86Qnt0zJAKP151ZryUckgPSmw8a9EVw+mDyucJ6hi2Rpz8ICQVbbb9BvO t4eQ== 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=RNewPB5eCe3R1a+Ap8yU95H+NO3s0OA47lP/S86nOaVmi2DikE6DEVbfwyVDdWAZEi qiutF5TDLrBW2//i0iqODekNU2p07oWTpw7pgfPq0xYtD+5YUSCaakk/voE9CSY6JLkh dpcp3uUeHHDR93d0R7MEzoJbXtibuK4D4iaGtTRaSzJXsaiCe5Lf6e2r5+J2jAgZgK6g lQGKbJ6mQ4aahufZygoYKoCKJqYu5FPJMTJni0YbcGjhzYW9YC8TEX2B5ofDS2Xymwsr lMzA648hYPDb4DrWtwGmWHXb4EpHmoecg+S7ShLsB8yI56giufkF6dOgPWd+VW2d1Oop 7Yaw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=TQhQSEmr; 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 n20-v6si308361pff.370.2018.05.15.08.57.41; Tue, 15 May 2018 08:57:55 -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=TQhQSEmr; 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 S1753441AbeEOPuL (ORCPT + 99 others); Tue, 15 May 2018 11:50:11 -0400 Received: from mail-yb0-f194.google.com ([209.85.213.194]:33418 "EHLO mail-yb0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751309AbeEOPuI (ORCPT ); Tue, 15 May 2018 11:50:08 -0400 Received: by mail-yb0-f194.google.com with SMTP id y5-v6so223202ybg.0; Tue, 15 May 2018 08:50:08 -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=TQhQSEmrnKsJWtYrwniZ3cR3gwu/4hCy+Iv3euZ2tyHnx70BJHWHlqt31C8Zddua4I Vl8LaCVQJSOBi0xEdTk3z5Jo2RKQVU+jM1xYuu2JVerpzIM6Lw7UuQ3S1mQqSFO9R58v 529kC5W8Toy7exERriKow7Wee1tugK55mhsJUgZ8d0vxEU2EWZP6Ve+Z1CSsDKrGbPXd 6eZhTJqwVq97RT1sSDwqsLB8+lw4hmKgAoAIZEOGiD3S8hUBrnnVakZ6clrpgxCsa7RN 3zD/bHsx8l2tZyHD2ySb/tWcUQxDP5fEXr6+G/No3qA8NQM3YJrSCPk6+okdsnJKWVVx +TeA== 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=szPPSRIyR8QiXHlJe/c/wa0AuZ9Gybyadg8iU9XAVPBK3Tof9Q0Mm5oD1oi9APTKeI 7WPiZakY/Lb6VCY3D6TLM8i/nhRNDlYLsiCP/cf8SqodAseJM5T64NZaLwHkdyecyc4q LYuXMQNERX9C604aXxk5i65YYHrHttw2BRVsWzdltKEqFr7wheYh8QljqsIzLVUZM/fO frKiHUu8N4g5AxRIatw5NqYNKcWmbcIYOj2IEM9DhxMqFsR96nB0W9uvc3DjJxY0yKlJ dJnKbvlLvNlVTVC3zmwQ/vCnd4LyZKT52IInhOHZE7YETqz5uqfPdSJQJgNbxKJXZ7iA xksg== X-Gm-Message-State: ALKqPwfHNjo5IysBLRpfcDyZSPTk3wrgyF4XzE5rk24i21I3eiqKPOTS UEZGuD8rfhDi5r9yqsLsnk8= X-Received: by 2002:a25:45:: with SMTP id 66-v6mr9484591yba.434.1526399407749; Tue, 15 May 2018 08:50:07 -0700 (PDT) Received: from localhost ([72.188.97.40]) by smtp.gmail.com with ESMTPSA id x16-v6sm135130ywj.22.2018.05.15.08.50.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 15 May 2018 08:50:07 -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 v3 1/8] bitops: Introduce the for_each_set_clump macro Date: Tue, 15 May 2018 11:50:01 -0400 Message-Id: <87c7edee3bd6789345bd1cc6fd0cb91c2d508eda.1526397764.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