Commit f63ea4e9 authored by Vladimir Sementsov-Ogievskiy's avatar Vladimir Sementsov-Ogievskiy Committed by Max Reitz
Browse files

hbitmap: improve dirty iter



Make dirty iter resistant to resetting bits in corresponding HBitmap.

Signed-off-by: default avatarVladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Reviewed-by: default avatarJohn Snow <jsnow@redhat.com>
Message-id: 20170628120530.31251-4-vsementsov@virtuozzo.com
Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
parent b348c262
Loading
Loading
Loading
Loading
+4 −22
Original line number Diff line number Diff line
@@ -256,10 +256,9 @@ void hbitmap_free(HBitmap *hb);
 * the lowest-numbered bit that is set in @hb, starting at @first.
 *
 * Concurrent setting of bits is acceptable, and will at worst cause the
 * iteration to miss some of those bits.  Resetting bits before the current
 * position of the iterator is also okay.  However, concurrent resetting of
 * bits can lead to unexpected behavior if the iterator has not yet reached
 * those bits.
 * iteration to miss some of those bits.
 *
 * The concurrent resetting of bits is OK.
 */
void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first);

@@ -298,24 +297,7 @@ void hbitmap_free_meta(HBitmap *hb);
 * Return the next bit that is set in @hbi's associated HBitmap,
 * or -1 if all remaining bits are zero.
 */
static inline int64_t hbitmap_iter_next(HBitmapIter *hbi)
{
    unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1];
    int64_t item;

    if (cur == 0) {
        cur = hbitmap_iter_skip_words(hbi);
        if (cur == 0) {
            return -1;
        }
    }

    /* The next call will resume work from the next bit.  */
    hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1);
    item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur);

    return item << hbi->granularity;
}
int64_t hbitmap_iter_next(HBitmapIter *hbi);

/**
 * hbitmap_iter_next_word:
+22 −1
Original line number Diff line number Diff line
@@ -106,8 +106,9 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi)

    unsigned long cur;
    do {
        cur = hbi->cur[--i];
        i--;
        pos >>= BITS_PER_LEVEL;
        cur = hbi->cur[i] & hb->levels[i][pos];
    } while (cur == 0);

    /* Check for end of iteration.  We always use fewer than BITS_PER_LONG
@@ -139,6 +140,26 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi)
    return cur;
}

int64_t hbitmap_iter_next(HBitmapIter *hbi)
{
    unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1] &
            hbi->hb->levels[HBITMAP_LEVELS - 1][hbi->pos];
    int64_t item;

    if (cur == 0) {
        cur = hbitmap_iter_skip_words(hbi);
        if (cur == 0) {
            return -1;
        }
    }

    /* The next call will resume work from the next bit.  */
    hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1);
    item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur);

    return item << hbi->granularity;
}

void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first)
{
    unsigned i, bit;