X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=lib%2Faxmap.c;h=03e712f53be7a7623f90b12a3eecf57d73fc6f62;hp=4a907fec22d2f8a2723121d8236d7a56be6db01c;hb=49e1ade14949b737dbd111b19a4057faf9aa77bb;hpb=c71430182a39fdf358d161ac2d0e01eb4ac285ce diff --git a/lib/axmap.c b/lib/axmap.c index 4a907fec..03e712f5 100644 --- a/lib/axmap.c +++ b/lib/axmap.c @@ -83,14 +83,6 @@ struct axmap { uint64_t nr_bits; }; -static inline unsigned long ulog64(unsigned long val, unsigned int log) -{ - while (log-- && val) - val >>= UNIT_SHIFT; - - return val; -} - /* Remove all elements from the @axmap set */ void axmap_reset(struct axmap *axmap) { @@ -136,6 +128,8 @@ struct axmap *axmap_new(unsigned long nr_bits) axmap->nr_levels = levels; axmap->levels = calloc(axmap->nr_levels, sizeof(struct axmap_level)); + if (!axmap->levels) + goto free_axmap; axmap->nr_bits = nr_bits; for (i = 0; i < axmap->nr_levels; i++) { @@ -145,19 +139,21 @@ struct axmap *axmap_new(unsigned long nr_bits) al->map_size = (nr_bits + BLOCKS_PER_UNIT - 1) >> UNIT_SHIFT; al->map = malloc(al->map_size * sizeof(unsigned long)); if (!al->map) - goto err; + goto free_levels; nr_bits = (nr_bits + BLOCKS_PER_UNIT - 1) >> UNIT_SHIFT; } axmap_reset(axmap); return axmap; -err: + +free_levels: for (i = 0; i < axmap->nr_levels; i++) - if (axmap->levels[i].map) - free(axmap->levels[i].map); + free(axmap->levels[i].map); free(axmap->levels); + +free_axmap: free(axmap); return NULL; } @@ -202,7 +198,7 @@ static bool axmap_handler_topdown(struct axmap *axmap, uint64_t bit_nr, int i; for (i = axmap->nr_levels - 1; i >= 0; i--) { - unsigned long index = ulog64(bit_nr, i); + unsigned long index = bit_nr >> (UNIT_SHIFT * i); unsigned long offset = index >> UNIT_SHIFT; unsigned int bit = index & BLOCKS_PER_UNIT_MASK; @@ -239,18 +235,14 @@ static bool axmap_set_fn(struct axmap_level *al, unsigned long offset, */ overlap = al->map[offset] & mask; if (overlap == mask) { -done: data->set_bits = 0; return true; } if (overlap) { - const int __bit = ffz(~overlap); - - nr_bits = __bit - bit; + nr_bits = ffz(~overlap) - bit; if (!nr_bits) - goto done; - + return true; mask = bit_masks[nr_bits] << bit; } @@ -278,29 +270,16 @@ done: static void __axmap_set(struct axmap *axmap, uint64_t bit_nr, struct axmap_set_data *data) { - unsigned int set_bits, nr_bits = data->nr_bits; + unsigned int nr_bits = data->nr_bits; if (bit_nr > axmap->nr_bits) return; else if (bit_nr + nr_bits > axmap->nr_bits) nr_bits = axmap->nr_bits - bit_nr; - set_bits = 0; - while (nr_bits) { - axmap_handler(axmap, bit_nr, axmap_set_fn, data); - set_bits += data->set_bits; - - if (!data->set_bits || - data->set_bits != (BLOCKS_PER_UNIT - nr_bits)) - break; - - nr_bits -= data->set_bits; - bit_nr += data->set_bits; - - data->nr_bits = nr_bits; - } + assert(nr_bits <= BLOCKS_PER_UNIT); - data->set_bits = set_bits; + axmap_handler(axmap, bit_nr, axmap_set_fn, data); } void axmap_set(struct axmap *axmap, uint64_t bit_nr)