Switch all random generators to be decided by use_os_rand
authorJens Axboe <jaxboe@fusionio.com>
Mon, 28 Mar 2011 07:51:09 +0000 (09:51 +0200)
committerJens Axboe <jaxboe@fusionio.com>
Mon, 28 Mar 2011 07:51:09 +0000 (09:51 +0200)
This includes file sizing, next file, block size selection,
trim state, and verify state.

Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
filesetup.c
fio.h
init.c
io_u.c
trim.c

index 0454cc4007936611ac53bad147b7f06b2afd2faa..2b690c8930d91cc39eeac8e4fb8a845409c96a86 100644 (file)
@@ -210,9 +210,16 @@ static unsigned long long get_rand_file_size(struct thread_data *td)
        unsigned long long ret, sized;
        long r;
 
-       r = os_random_long(&td->file_size_state);
-       sized = td->o.file_size_high - td->o.file_size_low;
-       ret = (unsigned long long) ((double) sized * (r / (OS_RAND_MAX + 1.0)));
+       if (td->o.use_os_rand) {
+               r = os_random_long(&td->file_size_state);
+               sized = td->o.file_size_high - td->o.file_size_low;
+               ret = (unsigned long long) ((double) sized * (r / (OS_RAND_MAX + 1.0)));
+       } else {
+               r = __rand(&td->__file_size_state);
+               sized = td->o.file_size_high - td->o.file_size_low;
+               ret = (unsigned long long) ((double) sized * (r / (FRAND_MAX + 1.0)));
+       }
+
        ret += td->o.file_size_low;
        ret -= (ret % td->o.rw_min_bs);
        return ret;
diff --git a/fio.h b/fio.h
index e5607bc7a7ec9d7b034e9d05d5f51dde3366c02a..c0087e8105bc00ec6d82853d55a1c8a9773b5800 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -336,6 +336,7 @@ struct thread_data {
        union {
                unsigned int next_file;
                os_random_state_t next_file_state;
+               struct frand_state __next_file_state;
        };
        int error;
        int done;
@@ -359,9 +360,18 @@ struct thread_data {
 
        unsigned long rand_seeds[7];
 
-       os_random_state_t bsrange_state;
-       os_random_state_t verify_state;
-       os_random_state_t trim_state;
+       union {
+               os_random_state_t bsrange_state;
+               struct frand_state __bsrange_state;
+       };
+       union {
+               os_random_state_t verify_state;
+               struct frand_state __verify_state;
+       };
+       union {
+               os_random_state_t trim_state;
+               struct frand_state __trim_state;
+       };
 
        unsigned int verify_batch;
        unsigned int trim_batch;
@@ -417,8 +427,10 @@ struct thread_data {
        /*
         * State for random io, a bitmap of blocks done vs not done
         */
-       os_random_state_t random_state;
-       struct frand_state __random_state;
+       union {
+               os_random_state_t random_state;
+               struct frand_state __random_state;
+       };
 
        struct timeval start;   /* start of this loop */
        struct timeval epoch;   /* time job was started */
@@ -431,7 +443,10 @@ struct thread_data {
        /*
         * read/write mixed workload state
         */
-       os_random_state_t rwmix_state;
+       union {
+               os_random_state_t rwmix_state;
+               struct frand_state __rwmix_state;
+       };
        unsigned long rwmix_issues;
        enum fio_ddir rwmix_ddir;
        unsigned int ddir_seq_nr;
@@ -467,7 +482,10 @@ struct thread_data {
        /*
         * For generating file sizes
         */
-       os_random_state_t file_size_state;
+       union {
+               os_random_state_t file_size_state;
+               struct frand_state __file_size_state;
+       };
 
        /*
         * Error counts
diff --git a/init.c b/init.c
index 2ae93a026f2aad21025ea3eae8bfc1491646062b..b96350a66f09d64e3d39602f0717801ef92c9c37 100644 (file)
--- a/init.c
+++ b/init.c
@@ -463,7 +463,7 @@ static int exists_and_not_file(const char *filename)
        return 1;
 }
 
-void td_fill_rand_seeds(struct thread_data *td)
+static void td_fill_rand_seeds_os(struct thread_data *td)
 {
        os_random_seed(td->rand_seeds[0], &td->bsrange_state);
        os_random_seed(td->rand_seeds[1], &td->verify_state);
@@ -482,9 +482,37 @@ void td_fill_rand_seeds(struct thread_data *td)
                td->rand_seeds[4] = FIO_RANDSEED * td->thread_number;
 
        os_random_seed(td->rand_seeds[4], &td->random_state);
+}
+
+static void td_fill_rand_seeds_internal(struct thread_data *td)
+{
+       init_rand_seed(&td->__bsrange_state, td->rand_seeds[0]);
+       init_rand_seed(&td->__verify_state, td->rand_seeds[1]);
+       init_rand_seed(&td->__rwmix_state, td->rand_seeds[2]);
+
+       if (td->o.file_service_type == FIO_FSERVICE_RANDOM)
+               init_rand_seed(&td->__next_file_state, td->rand_seeds[3]);
+
+       init_rand_seed(&td->__file_size_state, td->rand_seeds[5]);
+       init_rand_seed(&td->__trim_state, td->rand_seeds[6]);
+
+       if (!td_random(td))
+               return;
+
+       if (td->o.rand_repeatable)
+               td->rand_seeds[4] = FIO_RANDSEED * td->thread_number;
+
        init_rand_seed(&td->__random_state, td->rand_seeds[4]);
 }
 
+void td_fill_rand_seeds(struct thread_data *td)
+{
+       if (td->o.use_os_rand)
+               td_fill_rand_seeds_os(td);
+       else
+               td_fill_rand_seeds_internal(td);
+}
+
 /*
  * Initialize the various random states we need (random io, block size ranges,
  * read/write mix, etc).
diff --git a/io_u.c b/io_u.c
index c672993414b480d33e5e4224ab84e727249e81e6..787f382e2c73db251690fa296da787913b49e957 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -346,20 +346,29 @@ static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u)
        const int ddir = io_u->ddir;
        unsigned int uninitialized_var(buflen);
        unsigned int minbs, maxbs;
-       long r;
+       long r, rand_max;
 
        assert(ddir_rw(ddir));
 
        minbs = td->o.min_bs[ddir];
        maxbs = td->o.max_bs[ddir];
 
+       if (td->o.use_os_rand)
+               rand_max = OS_RAND_MAX;
+       else
+               rand_max = FRAND_MAX;
+
        if (minbs == maxbs)
                buflen = minbs;
        else {
-               r = os_random_long(&td->bsrange_state);
+               if (td->o.use_os_rand)
+                       r = os_random_long(&td->bsrange_state);
+               else
+                       r = __rand(&td->__bsrange_state);
+
                if (!td->o.bssplit_nr[ddir]) {
                        buflen = 1 + (unsigned int) ((double) maxbs *
-                                       (r / (OS_RAND_MAX + 1.0)));
+                                       (r / (rand_max + 1.0)));
                        if (buflen < minbs)
                                buflen = minbs;
                } else {
@@ -371,7 +380,7 @@ static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u)
 
                                buflen = bsp->bs;
                                perc += bsp->perc;
-                               if (r <= ((OS_RAND_MAX / 100L) * perc))
+                               if (r <= ((rand_max / 100L) * perc))
                                        break;
                        }
                }
@@ -416,8 +425,14 @@ static inline enum fio_ddir get_rand_ddir(struct thread_data *td)
        unsigned int v;
        long r;
 
-       r = os_random_long(&td->rwmix_state);
-       v = 1 + (int) (100.0 * (r / (OS_RAND_MAX + 1.0)));
+       if (td->o.use_os_rand) {
+               r = os_random_long(&td->rwmix_state);
+               v = 1 + (int) (100.0 * (r / (OS_RAND_MAX + 1.0)));
+       } else {
+               r = __rand(&td->__rwmix_state);
+               v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+       }
+
        if (v <= td->o.rwmix[DDIR_READ])
                return DDIR_READ;
 
@@ -833,11 +848,19 @@ static struct fio_file *get_next_file_rand(struct thread_data *td,
        int fno;
 
        do {
-               long r = os_random_long(&td->next_file_state);
                int opened = 0;
+               long r;
+
+               if (td->o.use_os_rand) {
+                       r = os_random_long(&td->next_file_state);
+                       fno = (unsigned int) ((double) td->o.nr_files
+                               * (r / (OS_RAND_MAX + 1.0)));
+               } else {
+                       r = __rand(&td->__next_file_state);
+                       fno = (unsigned int) ((double) td->o.nr_files
+                               * (r / (FRAND_MAX + 1.0)));
+               }
 
-               fno = (unsigned int) ((double) td->o.nr_files
-                       * (r / (OS_RAND_MAX + 1.0)));
                f = td->files[fno];
                if (fio_file_done(f))
                        continue;
diff --git a/trim.c b/trim.c
index 3da1e749206dc02aaaf633ee25562f3b08c6ee59..a9b15d686606bee6856b3998e5b7104bc633ac18 100644 (file)
--- a/trim.c
+++ b/trim.c
@@ -75,10 +75,15 @@ int io_u_should_trim(struct thread_data *td, struct io_u *io_u)
        if (!td->o.trim_percentage)
                return 0;
 
-       r = os_random_long(&td->trim_state);
-       val = (OS_RAND_MAX / 100ULL);
-       val *= (unsigned long long) td->o.trim_percentage;
+       if (td->o.use_os_rand) {
+               r = os_random_long(&td->trim_state);
+               val = (OS_RAND_MAX / 100ULL);
+       } else {
+               r = __rand(&td->__trim_state);
+               val = (FRAND_MAX / 100ULL);
+       }
 
+       val *= (unsigned long long) td->o.trim_percentage;
        return r <= val;
 }
 #endif