^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * From lib/bitmap.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Helper functions for bitmap.h.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) int __bitmap_weight(const unsigned long *bitmap, int bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) int k, w = 0, lim = bits/BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) for (k = 0; k < lim; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) w += hweight_long(bitmap[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) if (bits % BITS_PER_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) return w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) const unsigned long *bitmap2, int bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) int nr = BITS_TO_LONGS(bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) for (k = 0; k < nr; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) dst[k] = bitmap1[k] | bitmap2[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) size_t bitmap_scnprintf(unsigned long *bitmap, int nbits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) char *buf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* current bit is 'cur', most recently seen range is [rbot, rtop] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int cur, rbot, rtop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) bool first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) size_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) rbot = cur = find_first_bit(bitmap, nbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) while (cur < nbits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) rtop = cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) cur = find_next_bit(bitmap, nbits, cur + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (cur < nbits && cur <= rtop + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (!first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ret += scnprintf(buf + ret, size - ret, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ret += scnprintf(buf + ret, size - ret, "%d", rbot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (rbot < rtop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ret += scnprintf(buf + ret, size - ret, "-%d", rtop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) rbot = cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) const unsigned long *bitmap2, unsigned int bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned int lim = bits/BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned long result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) for (k = 0; k < lim; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) result |= (dst[k] = bitmap1[k] & bitmap2[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (bits % BITS_PER_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) result |= (dst[k] = bitmap1[k] & bitmap2[k] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) BITMAP_LAST_WORD_MASK(bits));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return result != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int __bitmap_equal(const unsigned long *bitmap1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) const unsigned long *bitmap2, unsigned int bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) unsigned int k, lim = bits/BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) for (k = 0; k < lim; ++k)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (bitmap1[k] != bitmap2[k])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (bits % BITS_PER_LONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }