Soby Mathew | b4c6df4 | 2022-11-09 11:13:29 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * SPDX-License-Identifier: BSD-3-Clause |
| 3 | * SPDX-FileCopyrightText: Copyright TF-RMM Contributors. |
| 4 | */ |
| 5 | |
| 6 | #ifndef BITMAP_H |
| 7 | #define BITMAP_H |
| 8 | |
| 9 | #include <sizes.h> |
| 10 | |
| 11 | /* |
| 12 | * Returns the index of the first bit set in @bitmap from @start inclusive. |
| 13 | * The index is zero-based from LSB (0) to MSB (63). |
| 14 | * When no such bits are set, returns BITS_PER_UL (64). |
| 15 | */ |
| 16 | static inline unsigned long bitmap_find_next_set_bit(unsigned long bitmap, |
| 17 | unsigned long start) |
| 18 | { |
| 19 | if (start < BITS_PER_UL) { |
| 20 | bitmap &= ~0UL << start; |
| 21 | if (bitmap != 0UL) { |
| 22 | return (unsigned long)(__builtin_ffsl(bitmap) - 1); |
| 23 | } |
| 24 | } |
| 25 | return BITS_PER_UL; |
| 26 | } |
| 27 | |
| 28 | #define bitmap_for_each_set_bit(_bit, _bitmap, _max) \ |
| 29 | for ((_bit) = find_next_set_bit((_bitmap), 0); \ |
| 30 | (_bit) < (_max); \ |
| 31 | (_bit) = find_next_set_bit((_bitmap), (_bit) + 1)) |
| 32 | |
| 33 | #endif /* BITMAP_H */ |