Reseed random generator for loop/time based runs
authorJens Axboe <jens.axboe@oracle.com>
Tue, 7 Apr 2009 11:28:12 +0000 (13:28 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Tue, 7 Apr 2009 11:28:12 +0000 (13:28 +0200)
Then we get repeatable 2nd/3rd/etc runs. This is important
if the file layout was random, otherwise subsequent runs will
get very different results.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
fio.c
fio.h
init.c
io_u.c

diff --git a/fio.c b/fio.c
index f699951..ad2282d 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -876,6 +876,11 @@ static void reset_io_counters(struct thread_data *td)
         */
        if (td->o.time_based || td->o.loops)
                td->nr_done_files = 0;
+
+       /*
+        * Set the same seed to get repeatable runs
+        */
+       td_fill_rand_seeds(td);
 }
 
 void reset_all_stats(struct thread_data *td)
diff --git a/fio.h b/fio.h
index 4077a5b..ff0068c 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -572,6 +572,8 @@ struct thread_data {
 
        char *sysfs_root;
 
+       unsigned long rand_seeds[6];
+
        os_random_state_t bsrange_state;
        os_random_state_t verify_state;
 
@@ -854,6 +856,7 @@ extern int fio_show_option_help(const char *);
 extern void fio_options_dup_and_init(struct option *);
 extern void options_mem_dupe(struct thread_data *);
 extern void options_mem_free(struct thread_data *);
+extern void td_fill_rand_seeds(struct thread_data *);
 #define FIO_GETOPT_JOB         0x89988998
 #define FIO_NR_OPTIONS         128
 
diff --git a/init.c b/init.c
index 80d098d..8deedcc 100644 (file)
--- a/init.c
+++ b/init.c
@@ -408,13 +408,32 @@ static int exists_and_not_file(const char *filename)
        return 1;
 }
 
+void td_fill_rand_seeds(struct thread_data *td)
+{
+       os_random_seed(td->rand_seeds[0], &td->bsrange_state);
+       os_random_seed(td->rand_seeds[1], &td->verify_state);
+       os_random_seed(td->rand_seeds[2], &td->rwmix_state);
+
+       if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
+               os_random_seed(td->rand_seeds[3], &td->next_file_state);
+
+       os_random_seed(td->rand_seeds[5], &td->file_size_state);
+
+       if (!td_random(td))
+               return;
+
+       if (td->o.rand_repeatable)
+               td->rand_seeds[4] = FIO_RANDSEED * td->thread_number;
+
+       os_random_seed(td->rand_seeds[4], &td->random_state);
+}
+
 /*
  * Initialize the various random states we need (random io, block size ranges,
  * read/write mix, etc).
  */
 static int init_random_state(struct thread_data *td)
 {
-       unsigned long seeds[6];
        int fd;
 
        fd = open("/dev/urandom", O_RDONLY);
@@ -423,30 +442,15 @@ static int init_random_state(struct thread_data *td)
                return 1;
        }
 
-       if (read(fd, seeds, sizeof(seeds)) < (int) sizeof(seeds)) {
+       if (read(fd, td->rand_seeds, sizeof(td->rand_seeds)) <
+           (int) sizeof(td->rand_seeds)) {
                td_verror(td, EIO, "read");
                close(fd);
                return 1;
        }
 
        close(fd);
-
-       os_random_seed(seeds[0], &td->bsrange_state);
-       os_random_seed(seeds[1], &td->verify_state);
-       os_random_seed(seeds[2], &td->rwmix_state);
-
-       if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
-               os_random_seed(seeds[3], &td->next_file_state);
-
-       os_random_seed(seeds[5], &td->file_size_state);
-
-       if (!td_random(td))
-               return 0;
-
-       if (td->o.rand_repeatable)
-               seeds[4] = FIO_RANDSEED * td->thread_number;
-
-       os_random_seed(seeds[4], &td->random_state);
+       td_fill_rand_seeds(td);
        return 0;
 }
 
diff --git a/io_u.c b/io_u.c
index 476658e..7108939 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -748,23 +748,12 @@ static int set_io_u_file(struct thread_data *td, struct io_u *io_u)
                if (!f)
                        return 1;
 
-set_file:
                io_u->file = f;
                get_file(f);
 
                if (!fill_io_u(td, io_u))
                        break;
 
-               /*
-                * optimization to prevent close/open of the same file. This
-                * way we preserve queueing etc.
-                */
-               if (td->o.nr_files == 1 && td->o.time_based) {
-                       put_file_log(td, f);
-                       fio_file_reset(f);
-                       goto set_file;
-               }
-
                put_file_log(td, f);
                td_io_close_file(td, f);
                io_u->file = NULL;