rand: cleanup rand_between() and helpers
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index 61d09ba872e9c816ed0f07b8a07c39b32ccb34e0..580c414622db161fe78061413ac5bef6de7e0efb 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -1,12 +1,8 @@
 #include <unistd.h>
-#include <fcntl.h>
 #include <string.h>
-#include <signal.h>
-#include <time.h>
 #include <assert.h>
 
 #include "fio.h"
-#include "hash.h"
 #include "verify.h"
 #include "trim.h"
 #include "lib/rand.h"
@@ -81,11 +77,6 @@ static uint64_t last_block(struct thread_data *td, struct fio_file *f,
        return max_blocks;
 }
 
-struct rand_off {
-       struct flist_head list;
-       uint64_t off;
-};
-
 static int __get_next_rand_offset(struct thread_data *td, struct fio_file *f,
                                  enum fio_ddir ddir, uint64_t *b,
                                  uint64_t lastb)
@@ -177,7 +168,7 @@ bail:
        /*
         * Generate a value, v, between 1 and 100, both inclusive
         */
-       v = rand32_between(&td->zone_state, 1, 100);
+       v = rand_between(&td->zone_state, 1, 100);
 
        /*
         * Find our generated table. 'send' is the end block of this zone,
@@ -234,7 +225,7 @@ bail:
        /*
         * Generate a value, v, between 1 and 100, both inclusive
         */
-       v = rand32_between(&td->zone_state, 1, 100);
+       v = rand_between(&td->zone_state, 1, 100);
 
        zsi = &td->zone_state_index[ddir][v - 1];
        stotal = zsi->size_perc_prev;
@@ -276,16 +267,8 @@ bail:
        return 0;
 }
 
-static int flist_cmp(void *data, struct flist_head *a, struct flist_head *b)
-{
-       struct rand_off *r1 = flist_entry(a, struct rand_off, list);
-       struct rand_off *r2 = flist_entry(b, struct rand_off, list);
-
-       return r1->off - r2->off;
-}
-
-static int get_off_from_method(struct thread_data *td, struct fio_file *f,
-                              enum fio_ddir ddir, uint64_t *b)
+static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
+                               enum fio_ddir ddir, uint64_t *b)
 {
        if (td->o.random_distribution == FIO_RAND_DIST_RANDOM) {
                uint64_t lastb;
@@ -310,25 +293,6 @@ static int get_off_from_method(struct thread_data *td, struct fio_file *f,
        return 1;
 }
 
-/*
- * Sort the reads for a verify phase in batches of verifysort_nr, if
- * specified.
- */
-static inline bool should_sort_io(struct thread_data *td)
-{
-       if (!td->o.verifysort_nr || !td->o.do_verify)
-               return false;
-       if (!td_random(td))
-               return false;
-       if (td->runstate != TD_VERIFYING)
-               return false;
-       if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE ||
-           td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64)
-               return false;
-
-       return true;
-}
-
 static bool should_do_random(struct thread_data *td, enum fio_ddir ddir)
 {
        unsigned int v;
@@ -336,49 +300,11 @@ static bool should_do_random(struct thread_data *td, enum fio_ddir ddir)
        if (td->o.perc_rand[ddir] == 100)
                return true;
 
-       v = rand32_between(&td->seq_rand_state[ddir], 1, 100);
+       v = rand_between(&td->seq_rand_state[ddir], 1, 100);
 
        return v <= td->o.perc_rand[ddir];
 }
 
-static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
-                               enum fio_ddir ddir, uint64_t *b)
-{
-       struct rand_off *r;
-       int i, ret = 1;
-
-       if (!should_sort_io(td))
-               return get_off_from_method(td, f, ddir, b);
-
-       if (!flist_empty(&td->next_rand_list)) {
-fetch:
-               r = flist_first_entry(&td->next_rand_list, struct rand_off, list);
-               flist_del(&r->list);
-               *b = r->off;
-               free(r);
-               return 0;
-       }
-
-       for (i = 0; i < td->o.verifysort_nr; i++) {
-               r = malloc(sizeof(*r));
-
-               ret = get_off_from_method(td, f, ddir, &r->off);
-               if (ret) {
-                       free(r);
-                       break;
-               }
-
-               flist_add(&r->list, &td->next_rand_list);
-       }
-
-       if (ret && !i)
-               return ret;
-
-       assert(!flist_empty(&td->next_rand_list));
-       flist_sort(NULL, &td->next_rand_list, flist_cmp);
-       goto fetch;
-}
-
 static void loop_cache_invalidate(struct thread_data *td, struct fio_file *f)
 {
        struct thread_options *o = &td->o;
@@ -399,9 +325,9 @@ static int get_next_rand_block(struct thread_data *td, struct fio_file *f,
        if (td->o.time_based ||
            (td->o.file_service_type & __FIO_FSERVICE_NONUNIFORM)) {
                fio_file_reset(td, f);
+               loop_cache_invalidate(td, f);
                if (!get_next_rand_offset(td, f, ddir, b))
                        return 0;
-               loop_cache_invalidate(td, f);
        }
 
        dprint(FD_IO, "%s: rand offset failed, last=%llu, size=%llu\n",
@@ -430,7 +356,11 @@ static int get_next_seq_offset(struct thread_data *td, struct fio_file *f,
        if (f->last_pos[ddir] < f->real_file_size) {
                uint64_t pos;
 
-               if (f->last_pos[ddir] == f->file_offset && o->ddir_seq_add < 0) {
+               /*
+                * Only rewind if we already hit the end
+                */
+               if (f->last_pos[ddir] == f->file_offset &&
+                   f->file_offset && o->ddir_seq_add < 0) {
                        if (f->real_file_size > f->io_size)
                                f->last_pos[ddir] = f->io_size;
                        else
@@ -470,7 +400,7 @@ static int get_next_seq_offset(struct thread_data *td, struct fio_file *f,
 
 static int get_next_block(struct thread_data *td, struct io_u *io_u,
                          enum fio_ddir ddir, int rw_seq,
-                         unsigned int *is_random)
+                         bool *is_random)
 {
        struct fio_file *f = io_u->file;
        uint64_t b, offset;
@@ -484,27 +414,27 @@ static int get_next_block(struct thread_data *td, struct io_u *io_u,
                if (td_random(td)) {
                        if (should_do_random(td, ddir)) {
                                ret = get_next_rand_block(td, f, ddir, &b);
-                               *is_random = 1;
+                               *is_random = true;
                        } else {
-                               *is_random = 0;
+                               *is_random = false;
                                io_u_set(td, io_u, IO_U_F_BUSY_OK);
                                ret = get_next_seq_offset(td, f, ddir, &offset);
                                if (ret)
                                        ret = get_next_rand_block(td, f, ddir, &b);
                        }
                } else {
-                       *is_random = 0;
+                       *is_random = false;
                        ret = get_next_seq_offset(td, f, ddir, &offset);
                }
        } else {
                io_u_set(td, io_u, IO_U_F_BUSY_OK);
-               *is_random = 0;
+               *is_random = false;
 
                if (td->o.rw_seq == RW_SEQ_SEQ) {
                        ret = get_next_seq_offset(td, f, ddir, &offset);
                        if (ret) {
                                ret = get_next_rand_block(td, f, ddir, &b);
-                               *is_random = 0;
+                               *is_random = false;
                        }
                } else if (td->o.rw_seq == RW_SEQ_IDENT) {
                        if (f->last_start[ddir] != -1ULL)
@@ -537,8 +467,8 @@ static int get_next_block(struct thread_data *td, struct io_u *io_u,
  * until we find a free one. For sequential io, just return the end of
  * the last io issued.
  */
-static int __get_next_offset(struct thread_data *td, struct io_u *io_u,
-                            unsigned int *is_random)
+static int get_next_offset(struct thread_data *td, struct io_u *io_u,
+                          bool *is_random)
 {
        struct fio_file *f = io_u->file;
        enum fio_ddir ddir = io_u->ddir;
@@ -572,19 +502,6 @@ static int __get_next_offset(struct thread_data *td, struct io_u *io_u,
        return 0;
 }
 
-static int get_next_offset(struct thread_data *td, struct io_u *io_u,
-                          unsigned int *is_random)
-{
-       if (td->flags & TD_F_PROFILE_OPS) {
-               struct prof_io_ops *ops = &td->prof_io_ops;
-
-               if (ops->fill_io_u_off)
-                       return ops->fill_io_u_off(td, io_u, is_random);
-       }
-
-       return __get_next_offset(td, io_u, is_random);
-}
-
 static inline bool io_u_fits(struct thread_data *td, struct io_u *io_u,
                             unsigned int buflen)
 {
@@ -593,8 +510,8 @@ static inline bool io_u_fits(struct thread_data *td, struct io_u *io_u,
        return io_u->offset + buflen <= f->io_size + get_start_offset(td, f);
 }
 
-static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u,
-                                     unsigned int is_random)
+static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u,
+                                   bool is_random)
 {
        int ddir = io_u->ddir;
        unsigned int buflen = 0;
@@ -605,7 +522,7 @@ static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u,
        assert(ddir_rw(ddir));
 
        if (td->o.bs_is_seq_rand)
-               ddir = is_random ? DDIR_WRITE: DDIR_READ;
+               ddir = is_random ? DDIR_WRITE : DDIR_READ;
 
        minbs = td->o.min_bs[ddir];
        maxbs = td->o.max_bs[ddir];
@@ -655,19 +572,6 @@ static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u,
        return buflen;
 }
 
-static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u,
-                                   unsigned int is_random)
-{
-       if (td->flags & TD_F_PROFILE_OPS) {
-               struct prof_io_ops *ops = &td->prof_io_ops;
-
-               if (ops->fill_io_u_size)
-                       return ops->fill_io_u_size(td, io_u, is_random);
-       }
-
-       return __get_next_buflen(td, io_u, is_random);
-}
-
 static void set_rwmix_bytes(struct thread_data *td)
 {
        unsigned int diff;
@@ -685,7 +589,7 @@ static inline enum fio_ddir get_rand_ddir(struct thread_data *td)
 {
        unsigned int v;
 
-       v = rand32_between(&td->rwmix_state, 1, 100);
+       v = rand_between(&td->rwmix_state, 1, 100);
 
        if (v <= td->o.rwmix[DDIR_READ])
                return DDIR_READ;
@@ -706,11 +610,8 @@ int io_u_quiesce(struct thread_data *td)
         * io's that have been actually submitted to an async engine,
         * and cur_depth is meaningless for sync engines.
         */
-       if (td->io_u_queued || td->cur_depth) {
-               int fio_unused ret;
-
-               ret = td_io_commit(td);
-       }
+       if (td->io_u_queued || td->cur_depth)
+               td_io_commit(td);
 
        while (td->io_u_in_flight) {
                int ret;
@@ -878,8 +779,8 @@ void put_io_u(struct thread_data *td, struct io_u *io_u)
                assert(!(td->flags & TD_F_CHILD));
        }
        io_u_qpush(&td->io_u_freelist, io_u);
-       td_io_u_unlock(td);
        td_io_u_free_notify(td);
+       td_io_u_unlock(td);
 }
 
 void clear_io_u(struct thread_data *td, struct io_u *io_u)
@@ -911,8 +812,8 @@ void requeue_io_u(struct thread_data *td, struct io_u **io_u)
        }
 
        io_u_rpush(&td->io_u_requeues, __io_u);
-       td_io_u_unlock(td);
        td_io_u_free_notify(td);
+       td_io_u_unlock(td);
        *io_u = NULL;
 }
 
@@ -957,7 +858,7 @@ static void __fill_io_u_zone(struct thread_data *td, struct io_u *io_u)
 
 static int fill_io_u(struct thread_data *td, struct io_u *io_u)
 {
-       unsigned int is_random;
+       bool is_random;
 
        if (td_ioengine_flagged(td, FIO_NOIO))
                goto out;
@@ -1387,13 +1288,6 @@ out:
 
 static struct fio_file *get_next_file(struct thread_data *td)
 {
-       if (td->flags & TD_F_PROFILE_OPS) {
-               struct prof_io_ops *ops = &td->prof_io_ops;
-
-               if (ops->get_next_file)
-                       return ops->get_next_file(td);
-       }
-
        return __get_next_file(td);
 }
 
@@ -1587,6 +1481,7 @@ bool queue_full(const struct thread_data *td)
 struct io_u *__get_io_u(struct thread_data *td)
 {
        struct io_u *io_u = NULL;
+       int ret;
 
        if (td->stop_io)
                return NULL;
@@ -1623,7 +1518,8 @@ again:
                 * return one
                 */
                assert(!(td->flags & TD_F_CHILD));
-               assert(!pthread_cond_wait(&td->free_cond, &td->io_u_lock));
+               ret = pthread_cond_wait(&td->free_cond, &td->io_u_lock);
+               assert(ret == 0);
                goto again;
        }
 
@@ -1730,7 +1626,7 @@ static void small_content_scramble(struct io_u *io_u)
 
 /*
  * Return an io_u to be processed. Gets a buflen and offset, sets direction,
- * etc. The returned io_u is fully ready to be prepped and submitted.
+ * etc. The returned io_u is fully ready to be prepped, populated and submitted.
  */
 struct io_u *get_io_u(struct thread_data *td)
 {
@@ -1791,12 +1687,9 @@ struct io_u *get_io_u(struct thread_data *td)
                                        td->o.min_bs[DDIR_WRITE],
                                        io_u->buflen);
                        } else if ((td->flags & TD_F_SCRAMBLE_BUFFERS) &&
-                                  !(td->flags & TD_F_COMPRESS))
+                                  !(td->flags & TD_F_COMPRESS) &&
+                                  !(td->flags & TD_F_DO_VERIFY))
                                do_scramble = 1;
-                       if (td->flags & TD_F_VER_NONE) {
-                               populate_verify_io_u(td, io_u);
-                               do_scramble = 0;
-                       }
                } else if (io_u->ddir == DDIR_READ) {
                        /*
                         * Reset the buf_filled parameters so next time if the
@@ -2176,7 +2069,7 @@ static struct frand_state *get_buf_state(struct thread_data *td)
                return &td->buf_state;
        }
 
-       v = rand32_between(&td->dedupe_state, 1, 100);
+       v = rand_between(&td->dedupe_state, 1, 100);
 
        if (v <= td->o.dedupe_percentage)
                return &td->buf_state_prev;