Merge branch 'samples-colnames' of https://github.com/parallel-fs-utils/fio
[fio.git] / lib / axmap.c
index 336d7048e07d3c607d7c61542c1200797e3c616b..27301bd8465848d3cf8af57fb4c28b1078084742 100644 (file)
@@ -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)