X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=lib%2Faxmap.c;h=27301bd8465848d3cf8af57fb4c28b1078084742;hb=029e6147e9005ddb08774193aa8b3a01174007b1;hp=336d7048e07d3c607d7c61542c1200797e3c616b;hpb=15a4f4962fad9e1777bcc662b3391f521ace8c5b;p=fio.git diff --git a/lib/axmap.c b/lib/axmap.c index 336d7048..27301bd8 100644 --- a/lib/axmap.c +++ b/lib/axmap.c @@ -110,7 +110,7 @@ void axmap_free(struct axmap *axmap) } /* Allocate memory for a set that can store the numbers 0 .. @nr_bits - 1. */ -struct axmap *axmap_new(unsigned long nr_bits) +struct axmap *axmap_new(uint64_t nr_bits) { struct axmap *axmap; unsigned int i, levels; @@ -135,13 +135,14 @@ struct axmap *axmap_new(unsigned long nr_bits) for (i = 0; i < axmap->nr_levels; i++) { struct axmap_level *al = &axmap->levels[i]; + nr_bits = (nr_bits + BLOCKS_PER_UNIT - 1) >> UNIT_SHIFT; + al->level = i; - al->map_size = (nr_bits + BLOCKS_PER_UNIT - 1) >> UNIT_SHIFT; + al->map_size = nr_bits; al->map = malloc(al->map_size * sizeof(unsigned long)); if (!al->map) goto free_levels; - nr_bits = (nr_bits + BLOCKS_PER_UNIT - 1) >> UNIT_SHIFT; } axmap_reset(axmap); @@ -164,7 +165,7 @@ free_axmap: * returns true. */ static bool axmap_handler(struct axmap *axmap, uint64_t bit_nr, - bool (*func)(struct axmap_level *, unsigned long, unsigned int, + bool (*func)(struct axmap_level *, uint64_t, unsigned int, void *), void *data) { struct axmap_level *al; @@ -193,12 +194,12 @@ static bool axmap_handler(struct axmap *axmap, uint64_t bit_nr, * returns true. */ static bool axmap_handler_topdown(struct axmap *axmap, uint64_t bit_nr, - bool (*func)(struct axmap_level *, unsigned long, unsigned int, void *)) + bool (*func)(struct axmap_level *, uint64_t, unsigned int, void *)) { int i; for (i = axmap->nr_levels - 1; i >= 0; i--) { - unsigned long index = bit_nr >> (UNIT_SHIFT * i); + uint64_t index = bit_nr >> (UNIT_SHIFT * i); unsigned long offset = index >> UNIT_SHIFT; unsigned int bit = index & BLOCKS_PER_UNIT_MASK; @@ -219,7 +220,7 @@ struct axmap_set_data { * the boundary of the element at offset @offset. Return the number of bits * that have been set in @__data->set_bits if @al->level == 0. */ -static bool axmap_set_fn(struct axmap_level *al, unsigned long offset, +static bool axmap_set_fn(struct axmap_level *al, uint64_t offset, unsigned int bit, void *__data) { struct axmap_set_data *data = __data; @@ -241,6 +242,8 @@ static bool axmap_set_fn(struct axmap_level *al, unsigned long offset, if (overlap) { nr_bits = ffz(~overlap) - bit; + if (!nr_bits) + return true; mask = bit_masks[nr_bits] << bit; } @@ -268,29 +271,16 @@ static bool axmap_set_fn(struct axmap_level *al, unsigned long offset, 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) @@ -332,10 +322,10 @@ unsigned int axmap_set_nr(struct axmap *axmap, uint64_t bit_nr, return set_bits; } -static bool axmap_isset_fn(struct axmap_level *al, unsigned long offset, +static bool axmap_isset_fn(struct axmap_level *al, uint64_t offset, unsigned int bit, void *unused) { - return (al->map[offset] & (1UL << bit)) != 0; + return (al->map[offset] & (1ULL << bit)) != 0; } bool axmap_isset(struct axmap *axmap, uint64_t bit_nr)