X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=lib%2Faxmap.c;h=c29597f80e78748043b63db3756463596c164646;hp=2ee3a2563f818b04ec0edd0400fee7287d7800f9;hb=8cd5a2fdad69fcc7acc85863b69cc9ded97edceb;hpb=e39c0676d1af779004194ae4b3cc111db49bef7a diff --git a/lib/axmap.c b/lib/axmap.c index 2ee3a256..c29597f8 100644 --- a/lib/axmap.c +++ b/lib/axmap.c @@ -102,7 +102,7 @@ struct axmap *axmap_new(unsigned long nr_bits) } axmap->nr_levels = levels; - axmap->levels = malloc(axmap->nr_levels * sizeof(struct axmap_level)); + axmap->levels = calloc(axmap->nr_levels, sizeof(struct axmap_level)); axmap->nr_bits = nr_bits; for (i = 0; i < axmap->nr_levels; i++) { @@ -184,6 +184,9 @@ static bool axmap_clear_fn(struct axmap_level *al, unsigned long offset, void axmap_clear(struct axmap *axmap, uint64_t bit_nr) { axmap_handler(axmap, bit_nr, axmap_clear_fn, NULL); + + if (bit_nr < axmap->first_free) + axmap->first_free = bit_nr; } struct axmap_set_data { @@ -191,7 +194,7 @@ struct axmap_set_data { unsigned int set_bits; }; -static unsigned long bit_masks[] = { +static const unsigned long bit_masks[] = { 0x0000000000000000, 0x0000000000000001, 0x0000000000000003, 0x0000000000000007, 0x000000000000000f, 0x000000000000001f, 0x000000000000003f, 0x000000000000007f, 0x00000000000000ff, 0x00000000000001ff, 0x00000000000003ff, 0x00000000000007ff, @@ -231,17 +234,18 @@ static bool axmap_set_fn(struct axmap_level *al, unsigned long offset, if (overlap == mask) return true; - while (overlap) { - unsigned long clear_mask = ~(1UL << ffz(~overlap)); + if (overlap) { + const int __bit = ffz(~overlap); + + if (__bit == bit) + return true; - mask &= clear_mask; - overlap &= clear_mask; - nr_bits--; + nr_bits = __bit - bit; + mask = bit_masks[nr_bits] << bit; } assert(mask); assert(!(al->map[offset] & mask)); - al->map[offset] |= mask; if (!al->level) @@ -372,10 +376,9 @@ static uint64_t axmap_find_first_free(struct axmap *axmap, unsigned int level, static uint64_t axmap_first_free(struct axmap *axmap) { - if (firstfree_valid(axmap)) - return axmap->first_free; + if (!firstfree_valid(axmap)) + axmap->first_free = axmap_find_first_free(axmap, axmap->nr_levels - 1, 0); - axmap->first_free = axmap_find_first_free(axmap, axmap->nr_levels - 1, 0); return axmap->first_free; }