server: make the setsockopt() error output a bit more informative
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index ba3f7ca00fcd1db4f657f5dcf7321fc8c9f7ca0e..d80ef983c15972e4dbafc00fb68319826f16b3f2 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -12,6 +12,7 @@
 #include "lib/rand.h"
 #include "lib/axmap.h"
 #include "err.h"
+#include "lib/pow2.h"
 
 struct io_completion_data {
        int nr;                         /* input */
@@ -88,18 +89,20 @@ static int __get_next_rand_offset(struct thread_data *td, struct fio_file *f,
 {
        uint64_t r;
 
-       if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE) {
-               uint64_t lastb;
+       if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE ||
+           td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64) {
+               uint64_t frand_max, lastb;
 
                lastb = last_block(td, f, ddir);
                if (!lastb)
                        return 1;
 
+               frand_max = rand_max(&td->random_state);
                r = __rand(&td->random_state);
 
                dprint(FD_RANDOM, "off rand %llu\n", (unsigned long long) r);
 
-               *b = lastb * (r / ((uint64_t) FRAND_MAX + 1.0));
+               *b = lastb * (r / ((uint64_t) frand_max + 1.0));
        } else {
                uint64_t off = 0;
 
@@ -194,7 +197,8 @@ static inline int should_sort_io(struct thread_data *td)
                return 0;
        if (td->runstate != TD_VERIFYING)
                return 0;
-       if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE)
+       if (td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE ||
+           td->o.random_generator == FIO_RAND_GEN_TAUSWORTHE64)
                return 0;
 
        return 1;
@@ -202,14 +206,16 @@ static inline int should_sort_io(struct thread_data *td)
 
 static int should_do_random(struct thread_data *td, enum fio_ddir ddir)
 {
+       uint64_t frand_max;
        unsigned int v;
        unsigned long r;
 
        if (td->o.perc_rand[ddir] == 100)
                return 1;
 
+       frand_max = rand_max(&td->seq_rand_state[ddir]);
        r = __rand(&td->seq_rand_state[ddir]);
-       v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+       v = 1 + (int) (100.0 * (r / (frand_max + 1.0)));
 
        return v <= td->o.perc_rand[ddir];
 }
@@ -438,6 +444,7 @@ static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u,
        int ddir = io_u->ddir;
        unsigned int buflen = 0;
        unsigned int minbs, maxbs;
+       uint64_t frand_max;
        unsigned long r;
 
        assert(ddir_rw(ddir));
@@ -457,12 +464,13 @@ static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u,
        if (!io_u_fits(td, io_u, minbs))
                return 0;
 
+       frand_max = rand_max(&td->bsrange_state);
        do {
                r = __rand(&td->bsrange_state);
 
                if (!td->o.bssplit_nr[ddir]) {
                        buflen = 1 + (unsigned int) ((double) maxbs *
-                                       (r / (FRAND_MAX + 1.0)));
+                                       (r / (frand_max + 1.0)));
                        if (buflen < minbs)
                                buflen = minbs;
                } else {
@@ -474,7 +482,7 @@ static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u,
 
                                buflen = bsp->bs;
                                perc += bsp->perc;
-                               if ((r <= ((FRAND_MAX / 100L) * perc)) &&
+                               if ((r <= ((frand_max / 100L) * perc)) &&
                                    io_u_fits(td, io_u, buflen))
                                        break;
                        }
@@ -485,7 +493,7 @@ static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u,
                                ~(td->o.verify_interval - 1);
 
                if (!td->o.bs_unaligned && is_power_of_2(minbs))
-                       buflen = (buflen + minbs - 1) & ~(minbs - 1);
+                       buflen &= ~(minbs - 1);
 
        } while (!io_u_fits(td, io_u, buflen));
 
@@ -520,11 +528,12 @@ static void set_rwmix_bytes(struct thread_data *td)
 
 static inline enum fio_ddir get_rand_ddir(struct thread_data *td)
 {
+       uint64_t frand_max = rand_max(&td->rwmix_state);
        unsigned int v;
        unsigned long r;
 
        r = __rand(&td->rwmix_state);
-       v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+       v = 1 + (int) (100.0 * (r / (frand_max + 1.0)));
 
        if (v <= td->o.rwmix[DDIR_READ])
                return DDIR_READ;
@@ -991,6 +1000,7 @@ static struct fio_file *get_next_file_rand(struct thread_data *td,
                                           enum fio_file_flags goodf,
                                           enum fio_file_flags badf)
 {
+       uint64_t frand_max = rand_max(&td->next_file_state);
        struct fio_file *f;
        int fno;
 
@@ -1000,7 +1010,7 @@ static struct fio_file *get_next_file_rand(struct thread_data *td,
 
                r = __rand(&td->next_file_state);
                fno = (unsigned int) ((double) td->o.nr_files
-                               * (r / (FRAND_MAX + 1.0)));
+                               * (r / (frand_max + 1.0)));
 
                f = td->files[fno];
                if (fio_file_done(f))
@@ -1594,6 +1604,9 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,
        const int no_reduce = !gtod_reduce(td);
        unsigned long lusec = 0;
 
+       if (td->parent)
+               td = td->parent;
+
        if (no_reduce)
                lusec = utime_since(&io_u->issue_time, &icd->time);
 
@@ -1623,9 +1636,6 @@ static void account_io_completion(struct thread_data *td, struct io_u *io_u,
                io_u_mark_latency(td, lusec);
        }
 
-       if (td->parent)
-               td = td->parent;
-
        if (!td->o.disable_bw)
                add_bw_sample(td, idx, bytes, &icd->time);
 
@@ -1881,6 +1891,10 @@ void io_u_queued(struct thread_data *td, struct io_u *io_u)
                unsigned long slat_time;
 
                slat_time = utime_since(&io_u->start_time, &io_u->issue_time);
+
+               if (td->parent)
+                       td = td->parent;
+
                add_slat_sample(td, io_u->ddir, slat_time, io_u->xfer_buflen,
                                io_u->offset);
        }
@@ -1891,16 +1905,20 @@ void io_u_queued(struct thread_data *td, struct io_u *io_u)
  */
 static struct frand_state *get_buf_state(struct thread_data *td)
 {
+       uint64_t frand_max;
        unsigned int v;
        unsigned long r;
 
        if (!td->o.dedupe_percentage)
                return &td->buf_state;
-       else if (td->o.dedupe_percentage == 100)
-               return &td->buf_state_prev;
+       else if (td->o.dedupe_percentage == 100) {
+               frand_copy(&td->buf_state_prev, &td->buf_state);
+               return &td->buf_state;
+       }
 
+       frand_max = rand_max(&td->dedupe_state);
        r = __rand(&td->dedupe_state);
-       v = 1 + (int) (100.0 * (r / (FRAND_MAX + 1.0)));
+       v = 1 + (int) (100.0 * (r / (frand_max + 1.0)));
 
        if (v <= td->o.dedupe_percentage)
                return &td->buf_state_prev;
@@ -1910,7 +1928,9 @@ static struct frand_state *get_buf_state(struct thread_data *td)
 
 static void save_buf_state(struct thread_data *td, struct frand_state *rs)
 {
-       if (rs == &td->buf_state)
+       if (td->o.dedupe_percentage == 100)
+               frand_copy(rs, &td->buf_state_prev);
+       else if (rs == &td->buf_state)
                frand_copy(&td->buf_state_prev, rs);
 }