return ffsl(bits) - 1 + nl * VIR_BITMAP_BITS_PER_UNIT;
}
+/**
+ * virBitmapLastSetBit:
+ * @bitmap: the bitmap
+ *
+ * Search for the last set bit in bitmap @bitmap.
+ *
+ * Returns the position of the found bit, or -1 if no bit is set.
+ */
+ssize_t
+virBitmapLastSetBit(virBitmapPtr bitmap)
+{
+ ssize_t i;
+ int unusedBits;
+ ssize_t sz;
+ unsigned long bits;
+
+ unusedBits = bitmap->map_len * VIR_BITMAP_BITS_PER_UNIT - bitmap->max_bit;
+
+ sz = bitmap->map_len - 1;
+ if (unusedBits > 0) {
+ bits = bitmap->map[sz] & (VIR_BITMAP_BIT(VIR_BITMAP_BITS_PER_UNIT - unusedBits) - 1);
+ if (bits != 0)
+ goto found;
+
+ sz--;
+ }
+
+ for (; sz >= 0; sz--) {
+ bits = bitmap->map[sz];
+ if (bits != 0)
+ goto found;
+ }
+
+ if (bits == 0)
+ return -1;
+
+ found:
+ for (i = VIR_BITMAP_BITS_PER_UNIT - 1; i >= 0; i--) {
+ if (bits & 1UL << i)
+ return i + sz * VIR_BITMAP_BITS_PER_UNIT;
+ }
+
+ return -1;
+}
+
/**
* virBitmapNextClearBit:
* @bitmap: the bitmap
ssize_t virBitmapNextSetBit(virBitmapPtr bitmap, ssize_t pos)
ATTRIBUTE_NONNULL(1);
+ssize_t virBitmapLastSetBit(virBitmapPtr bitmap)
+ ATTRIBUTE_NONNULL(1);
+
ssize_t virBitmapNextClearBit(virBitmapPtr bitmap, ssize_t pos)
ATTRIBUTE_NONNULL(1);
return ret;
}
-/* test for virBitmapNextSetBit, virBitmapNextClearBit */
+/* test for virBitmapNextSetBit, virBitmapLastSetBit, virBitmapNextClearBit */
static int
test4(const void *data ATTRIBUTE_UNUSED)
{
if (virBitmapNextSetBit(bitmap, -1) != -1)
goto error;
+ if (virBitmapLastSetBit(bitmap) != -1)
+ goto error;
+
for (i = 0; i < size; i++) {
if (virBitmapNextClearBit(bitmap, i - 1) != i)
goto error;
if (virBitmapNextSetBit(bitmap, i) != -1)
goto error;
+ j = sizeof(bitsPos)/sizeof(int) - 1;
+
+ if (virBitmapLastSetBit(bitmap) != bitsPos[j])
+ goto error;
+
j = 0;
i = -1;
if (virBitmapNextSetBit(bitmap, i) != -1)
goto error;
+ if (virBitmapLastSetBit(bitmap) != size - 1)
+ goto error;
+
if (virBitmapNextClearBit(bitmap, -1) != -1)
goto error;