Streamline thread_data data direction setting and checking
authorJens Axboe <jens.axboe@oracle.com>
Fri, 23 Feb 2007 08:26:09 +0000 (09:26 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Fri, 23 Feb 2007 08:26:09 +0000 (09:26 +0100)
Currently it's a mess of ->ddir, ->iomix and ->sequential. Add
a TD_DDIR_* for each of these, so we can store them as one value.

A prerequisite for the next parsing cleanup.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
engines/mmap.c
engines/net.c
eta.c
filesetup.c
fio.c
fio.h
init.c
io_u.c
log.c
stat.c
time.c

index d4299143ecccb02cc17c43147a09b8e873dea086..bd59b28a6cf99f0900f978d175cbb68c336dfa00 100644 (file)
@@ -47,7 +47,7 @@ static int fio_mmapio_init(struct thread_data *td)
        struct fio_file *f;
        int i;
 
        struct fio_file *f;
        int i;
 
-       if (td->ddir == DDIR_READ && !td_rw(td))
+       if (!td_write(td))
                return 0;
 
        /*
                return 0;
 
        /*
index 55b2128e8b3f8c1fdc26fea9a0c331762a81e7be..60a68778b18458d9c49a758833911e779f2b7f99 100644 (file)
@@ -223,7 +223,7 @@ static int fio_netio_setup(struct thread_data *td)
                return 1;
        }
 
                return 1;
        }
 
-       if (td->iomix) {
+       if (td_rw(td)) {
                log_err("fio: network connections must be read OR write\n");
                return 1;
        }
                log_err("fio: network connections must be read OR write\n");
                return 1;
        }
@@ -241,7 +241,7 @@ static int fio_netio_setup(struct thread_data *td)
        strcpy(host, buf);
        port = atoi(sep);
 
        strcpy(host, buf);
        port = atoi(sep);
 
-       if (td->ddir == DDIR_READ) {
+       if (td_read(td)) {
                send_to_net(td) = 0;
                ret = fio_netio_setup_listen(td, port);
        } else {
                send_to_net(td) = 0;
                ret = fio_netio_setup_listen(td, port);
        } else {
diff --git a/eta.c b/eta.c
index 8e17d20ea745fcb59d14d57c53c87abbd9b88fce..960bf4d1b9f0e53e2a1515541ae3174e7a17e87a 100644 (file)
--- a/eta.c
+++ b/eta.c
@@ -26,20 +26,20 @@ static void check_str_update(struct thread_data *td)
                        break;
                case TD_RUNNING:
                        if (td_rw(td)) {
                        break;
                case TD_RUNNING:
                        if (td_rw(td)) {
-                               if (td->sequential)
-                                       c = 'M';
-                               else
+                               if (td_random(td))
                                        c = 'm';
                                        c = 'm';
-                       } else if (td_read(td)) {
-                               if (td->sequential)
-                                       c = 'R';
                                else
                                else
+                                       c = 'M';
+                       } else if (td_read(td)) {
+                               if (td_random(td))
                                        c = 'r';
                                        c = 'r';
-                       } else {
-                               if (td->sequential)
-                                       c = 'W';
                                else
                                else
+                                       c = 'R';
+                       } else {
+                               if (td_random(td))
                                        c = 'w';
                                        c = 'w';
+                               else
+                                       c = 'W';
                        }
                        break;
                case TD_VERIFYING:
                        }
                        break;
                case TD_VERIFYING:
index 11138b7a5cddc662f0b872819ecc812d40361196..356580e74c1276ccde5af550116e3bfd6813321b 100644 (file)
@@ -113,8 +113,7 @@ static int create_files(struct thread_data *td)
                for_each_file(td, f, i) {
                        int file_there = !file_ok(td, f);
 
                for_each_file(td, f, i) {
                        int file_there = !file_ok(td, f);
 
-                       if (file_there && td->ddir == DDIR_WRITE &&
-                           !td->overwrite) {
+                       if (file_there && td_write(td) && !td->overwrite) {
                                unlink(f->file_name);
                                file_there = 0;
                        }
                                unlink(f->file_name);
                                file_there = 0;
                        }
@@ -279,7 +278,7 @@ static int __setup_file_mmap(struct thread_data *td, struct fio_file *f)
        if (td->invalidate_cache && file_invalidate_cache(td, f))
                return 1;
 
        if (td->invalidate_cache && file_invalidate_cache(td, f))
                return 1;
 
-       if (td->sequential) {
+       if (!td_random(td)) {
                if (madvise(f->mmap, f->file_size, MADV_SEQUENTIAL) < 0) {
                        td_verror(td, errno, "madvise");
                        return 1;
                if (madvise(f->mmap, f->file_size, MADV_SEQUENTIAL) < 0) {
                        td_verror(td, errno, "madvise");
                        return 1;
@@ -313,7 +312,7 @@ static int __setup_file_plain(struct thread_data *td, struct fio_file *f)
        if (td->invalidate_cache && file_invalidate_cache(td, f))
                return 1;
 
        if (td->invalidate_cache && file_invalidate_cache(td, f))
                return 1;
 
-       if (td->sequential) {
+       if (!td_random(td)) {
                if (fadvise(f->fd, f->file_offset, f->file_size, POSIX_FADV_SEQUENTIAL) < 0) {
                        td_verror(td, errno, "fadvise");
                        return 1;
                if (fadvise(f->fd, f->file_offset, f->file_size, POSIX_FADV_SEQUENTIAL) < 0) {
                        td_verror(td, errno, "fadvise");
                        return 1;
diff --git a/fio.c b/fio.c
index 920639395cbda1101ba57c36b7cc421f6a3d4f27..58e03f9a6b94687011d720235decc238ffaf106b 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -98,7 +98,6 @@ static int check_min_rate(struct thread_data *td, struct timeval *now)
 {
        unsigned long spent;
        unsigned long rate;
 {
        unsigned long spent;
        unsigned long rate;
-       int ddir = td->ddir;
 
        /*
         * allow a 2 second settle period in the beginning
 
        /*
         * allow a 2 second settle period in the beginning
@@ -110,18 +109,30 @@ static int check_min_rate(struct thread_data *td, struct timeval *now)
         * if rate blocks is set, sample is running
         */
        if (td->rate_bytes) {
         * if rate blocks is set, sample is running
         */
        if (td->rate_bytes) {
+               unsigned long long bytes = 0;
+
                spent = mtime_since(&td->lastrate, now);
                if (spent < td->ratecycle)
                        return 0;
 
                spent = mtime_since(&td->lastrate, now);
                if (spent < td->ratecycle)
                        return 0;
 
-               rate = (td->this_io_bytes[ddir] - td->rate_bytes) / spent;
-               if (rate < td->ratemin) {
-                       fprintf(f_out, "%s: min rate %u not met, got %luKiB/sec\n", td->name, td->ratemin, rate);
+               if (td_read(td))
+                       bytes += td->this_io_bytes[DDIR_READ];
+               if (td_write(td))
+                       bytes += td->this_io_bytes[DDIR_WRITE];
+
+               if (bytes < td->rate_bytes) {
+                       fprintf(f_out, "%s: min rate %u not met\n", td->name, td->ratemin);
                        return 1;
                        return 1;
+               } else {
+                       rate = (bytes - td->rate_bytes) / spent;
+                       if (rate < td->ratemin || bytes < td->rate_bytes) {
+                               fprintf(f_out, "%s: min rate %u not met, got %luKiB/sec\n", td->name, td->ratemin, rate);
+                               return 1;
+                       }
                }
                }
+               td->rate_bytes = bytes;
        }
 
        }
 
-       td->rate_bytes = td->this_io_bytes[ddir];
        memcpy(&td->lastrate, now, sizeof(*now));
        return 0;
 }
        memcpy(&td->lastrate, now, sizeof(*now));
        return 0;
 }
@@ -458,7 +469,7 @@ requeue:
                 */
                usec = utime_since(&s, &comp_time);
 
                 */
                usec = utime_since(&s, &comp_time);
 
-               rate_throttle(td, usec, bytes_done, td->ddir);
+               rate_throttle(td, usec, bytes_done);
 
                if (check_min_rate(td, &comp_time)) {
                        if (exitall_on_terminate)
 
                if (check_min_rate(td, &comp_time)) {
                        if (exitall_on_terminate)
@@ -736,10 +747,11 @@ static void *thread_main(void *data)
                else
                        do_io(td);
 
                else
                        do_io(td);
 
-               runtime[td->ddir] += utime_since_now(&td->start);
-               if (td_rw(td) && td->io_bytes[td->ddir ^ 1])
-                       runtime[td->ddir ^ 1] = runtime[td->ddir];
-
+               if (td_read(td) && td->io_bytes[DDIR_READ])
+                       runtime[DDIR_READ] += utime_since_now(&td->start);
+               if (td_write(td) && td->io_bytes[DDIR_WRITE])
+                       runtime[DDIR_WRITE] += utime_since_now(&td->start);
+               
                if (td->error || td->terminate)
                        break;
 
                if (td->error || td->terminate)
                        break;
 
diff --git a/fio.h b/fio.h
index 8c46b3f905b2d9eb5b320ca96d05e2b8117b8e8d..8880ea61e7a518c02bc33840f9b0f8571a0c6b76 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -28,6 +28,13 @@ enum fio_ddir {
        DDIR_SYNC,
 };
 
        DDIR_SYNC,
 };
 
+enum td_ddir {
+       TD_DDIR_READ    = 1 << 0,
+       TD_DDIR_WRITE   = 1 << 1,
+       TD_DDIR_RAND    = 1 << 2,
+       TD_DDIR_RW      = TD_DDIR_READ | TD_DDIR_WRITE,
+};
+
 /*
  * Use for maintaining statistics
  */
 /*
  * Use for maintaining statistics
  */
@@ -290,12 +297,10 @@ struct thread_data {
        size_t orig_buffer_size;
        volatile int terminate;
        volatile int runstate;
        size_t orig_buffer_size;
        volatile int terminate;
        volatile int runstate;
-       enum fio_ddir ddir;
-       unsigned int iomix;
+       enum td_ddir td_ddir;
        unsigned int ioprio;
        unsigned int last_was_sync;
 
        unsigned int ioprio;
        unsigned int last_was_sync;
 
-       unsigned int sequential;
        unsigned int odirect;
        unsigned int invalidate_cache;
        unsigned int create_serialize;
        unsigned int odirect;
        unsigned int invalidate_cache;
        unsigned int create_serialize;
@@ -482,9 +487,10 @@ extern unsigned long long mlock_size;
 
 extern struct thread_data *threads;
 
 
 extern struct thread_data *threads;
 
-#define td_read(td)            ((td)->ddir == DDIR_READ)
-#define td_write(td)           ((td)->ddir == DDIR_WRITE)
-#define td_rw(td)              ((td)->iomix != 0)
+#define td_read(td)            ((td)->td_ddir & TD_DDIR_READ)
+#define td_write(td)           ((td)->td_ddir & TD_DDIR_WRITE)
+#define td_rw(td)              (((td)->td_ddir & TD_DDIR_RW) == TD_DDIR_RW)
+#define td_random(td)          ((td)->td_ddir & TD_DDIR_RAND)
 
 #define BLOCKS_PER_MAP         (8 * sizeof(long))
 #define TO_MAP_BLOCK(td, f, b) ((b) - ((f)->file_offset / (td)->rw_min_bs))
 
 #define BLOCKS_PER_MAP         (8 * sizeof(long))
 #define TO_MAP_BLOCK(td, f, b) ((b) - ((f)->file_offset / (td)->rw_min_bs))
@@ -588,7 +594,7 @@ extern unsigned long time_since_now(struct timeval *);
 extern unsigned long mtime_since_genesis(void);
 extern void __usec_sleep(unsigned int);
 extern void usec_sleep(struct thread_data *, unsigned long);
 extern unsigned long mtime_since_genesis(void);
 extern void __usec_sleep(unsigned int);
 extern void usec_sleep(struct thread_data *, unsigned long);
-extern void rate_throttle(struct thread_data *, unsigned long, unsigned int, int);
+extern void rate_throttle(struct thread_data *, unsigned long, unsigned int);
 extern void fill_start_time(struct timeval *);
 extern void fio_gettime(struct timeval *, void *);
 extern void set_genesis_time(void);
 extern void fill_start_time(struct timeval *);
 extern void fio_gettime(struct timeval *, void *);
 extern void set_genesis_time(void);
diff --git a/init.c b/init.c
index 01e615f92e90e1f37864e591279f037c8ddba55c..9ed99d797feace5c46cba7e2141450633174bbe0 100644 (file)
--- a/init.c
+++ b/init.c
@@ -618,7 +618,7 @@ static void fixup_options(struct thread_data *td)
        /*
         * only really works for sequential io for now, and with 1 file
         */
        /*
         * only really works for sequential io for now, and with 1 file
         */
-       if (td->zone_size && !td->sequential && td->nr_files == 1)
+       if (td->zone_size && td_random(td) && td->nr_files == 1)
                td->zone_size = 0;
 
        /*
                td->zone_size = 0;
 
        /*
@@ -695,10 +695,10 @@ static char *to_kmg(unsigned int val)
  */
 static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
 {
  */
 static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
 {
-       const char *ddir_str[] = { "read", "write", "randread", "randwrite",
-                                  "rw", NULL, "randrw" };
+       const char *ddir_str[] = { NULL, "read", "write", "rw", NULL,
+                                  "randread", "randwrite", "randrw" };
        struct stat sb;
        struct stat sb;
-       int numjobs, ddir, i;
+       int numjobs, i;
        struct fio_file *f;
 
        /*
        struct fio_file *f;
 
        /*
@@ -795,8 +795,6 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
        if (!td->name)
                td->name = strdup(jobname);
 
        if (!td->name)
                td->name = strdup(jobname);
 
-       ddir = td->ddir + (!td->sequential << 1) + (td->iomix << 2);
-
        if (!terse_output) {
                if (!job_add_num) {
                        if (td->io_ops->flags & FIO_CPUIO)
        if (!terse_output) {
                if (!job_add_num) {
                        if (td->io_ops->flags & FIO_CPUIO)
@@ -809,7 +807,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
                                c3 = to_kmg(td->min_bs[DDIR_WRITE]);
                                c4 = to_kmg(td->max_bs[DDIR_WRITE]);
 
                                c3 = to_kmg(td->min_bs[DDIR_WRITE]);
                                c4 = to_kmg(td->max_bs[DDIR_WRITE]);
 
-                               fprintf(f_out, "%s: (g=%d): rw=%s, bs=%s-%s/%s-%s, ioengine=%s, iodepth=%u\n", td->name, td->groupid, ddir_str[ddir], c1, c2, c3, c4, td->io_ops->name, td->iodepth);
+                               fprintf(f_out, "%s: (g=%d): rw=%s, bs=%s-%s/%s-%s, ioengine=%s, iodepth=%u\n", td->name, td->groupid, ddir_str[td->td_ddir], c1, c2, c3, c4, td->io_ops->name, td->iodepth);
 
                                free(c1);
                                free(c2);
 
                                free(c1);
                                free(c2);
@@ -874,9 +872,11 @@ int init_random_state(struct thread_data *td)
        os_random_seed(seeds[0], &td->bsrange_state);
        os_random_seed(seeds[1], &td->verify_state);
        os_random_seed(seeds[2], &td->rwmix_state);
        os_random_seed(seeds[0], &td->bsrange_state);
        os_random_seed(seeds[1], &td->verify_state);
        os_random_seed(seeds[2], &td->rwmix_state);
-       os_random_seed(seeds[3], &td->next_file_state);
 
 
-       if (td->sequential)
+       if (td->file_service_type == FIO_FSERVICE_RANDOM)
+               os_random_seed(seeds[3], &td->next_file_state);
+
+       if (!td_random(td))
                return 0;
 
        if (td->rand_repeatable)
                return 0;
 
        if (td->rand_repeatable)
@@ -931,30 +931,22 @@ static int str_rw_cb(void *data, const char *mem)
        struct thread_data *td = data;
 
        if (!strncmp(mem, "read", 4) || !strncmp(mem, "0", 1)) {
        struct thread_data *td = data;
 
        if (!strncmp(mem, "read", 4) || !strncmp(mem, "0", 1)) {
-               td->ddir = DDIR_READ;
-               td->sequential = 1;
+               td->td_ddir = TD_DDIR_READ;
                return 0;
        } else if (!strncmp(mem, "randread", 8)) {
                return 0;
        } else if (!strncmp(mem, "randread", 8)) {
-               td->ddir = DDIR_READ;
-               td->sequential = 0;
+               td->td_ddir = TD_DDIR_READ | TD_DDIR_RAND;
                return 0;
        } else if (!strncmp(mem, "write", 5) || !strncmp(mem, "1", 1)) {
                return 0;
        } else if (!strncmp(mem, "write", 5) || !strncmp(mem, "1", 1)) {
-               td->ddir = DDIR_WRITE;
-               td->sequential = 1;
+               td->td_ddir = TD_DDIR_WRITE;
                return 0;
        } else if (!strncmp(mem, "randwrite", 9)) {
                return 0;
        } else if (!strncmp(mem, "randwrite", 9)) {
-               td->ddir = DDIR_WRITE;
-               td->sequential = 0;
+               td->td_ddir = TD_DDIR_WRITE | TD_DDIR_RAND;
                return 0;
        } else if (!strncmp(mem, "rw", 2)) {
                return 0;
        } else if (!strncmp(mem, "rw", 2)) {
-               td->ddir = DDIR_READ;
-               td->iomix = 1;
-               td->sequential = 1;
+               td->td_ddir = TD_DDIR_RW;
                return 0;
        } else if (!strncmp(mem, "randrw", 6)) {
                return 0;
        } else if (!strncmp(mem, "randrw", 6)) {
-               td->ddir = DDIR_READ;
-               td->iomix = 1;
-               td->sequential = 0;
+               td->td_ddir = TD_DDIR_RW | TD_DDIR_RAND;
                return 0;
        }
 
                return 0;
        }
 
diff --git a/io_u.c b/io_u.c
index 6fb754e7f44701cbfddc628abe4f7164eeccd1aa..48d407605738bc335ce7e9be2cf96f61a8c88979 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -106,7 +106,7 @@ static int get_next_offset(struct thread_data *td, struct fio_file *f,
        unsigned long long b, rb;
        long r;
 
        unsigned long long b, rb;
        long r;
 
-       if (!td->sequential) {
+       if (td_random(td)) {
                unsigned long long max_blocks = f->file_size / td->min_bs[ddir];
                int loops = 5;
 
                unsigned long long max_blocks = f->file_size / td->min_bs[ddir];
                int loops = 5;
 
@@ -253,7 +253,7 @@ static int fill_io_u(struct thread_data *td, struct fio_file *f,
        /*
         * mark entry before potentially trimming io_u
         */
        /*
         * mark entry before potentially trimming io_u
         */
-       if (!td->read_iolog && !td->sequential && !td->norandommap)
+       if (!td->read_iolog && td_random(td) && !td->norandommap)
                mark_random_map(td, f, io_u);
 
        /*
                mark_random_map(td, f, io_u);
 
        /*
diff --git a/log.c b/log.c
index dd63c3891b67c65d6fd2903b8bfab0d349a246cb..513128d69b273bf1a3c0e21194b4dfa93aa2c5d7 100644 (file)
--- a/log.c
+++ b/log.c
@@ -56,7 +56,7 @@ void log_io_piece(struct thread_data *td, struct io_u *io_u)
         * be laid out with the block scattered as written. it's faster to
         * read them in in that order again, so don't sort
         */
         * be laid out with the block scattered as written. it's faster to
         * read them in in that order again, so don't sort
         */
-       if (td->sequential || !td->overwrite) {
+       if (!td_random(td) || !td->overwrite) {
                list_add_tail(&ipo->list, &td->io_hist_list);
                return;
        }
                list_add_tail(&ipo->list, &td->io_hist_list);
                return;
        }
@@ -137,11 +137,11 @@ static int init_iolog_read(struct thread_data *td)
        if (!reads && !writes)
                return 1;
        else if (reads && !writes)
        if (!reads && !writes)
                return 1;
        else if (reads && !writes)
-               td->ddir = DDIR_READ;
+               td->td_ddir = TD_DDIR_READ;
        else if (!reads && writes)
        else if (!reads && writes)
-               td->ddir = DDIR_READ;
+               td->td_ddir = TD_DDIR_READ;
        else
        else
-               td->iomix = 1;
+               td->td_ddir = TD_DDIR_RW;
 
        return 0;
 }
 
        return 0;
 }
diff --git a/stat.c b/stat.c
index 352ba48f4447cf77068b77bae7247ceec8dfa166..34b2b6a5d0ece0024c93b2590b65f4085d6d0593 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -454,9 +454,10 @@ static void show_thread_status(struct thread_data *td,
        else
                fprintf(f_out, "%s: (groupid=%d): err=%2d (%s): pid=%d\n",td->name, td->groupid, td->error, td->verror, td->pid);
 
        else
                fprintf(f_out, "%s: (groupid=%d): err=%2d (%s): pid=%d\n",td->name, td->groupid, td->error, td->verror, td->pid);
 
-       show_ddir_status(td, rs, td->ddir);
-       if (td->io_bytes[td->ddir ^ 1])
-               show_ddir_status(td, rs, td->ddir ^ 1);
+       if (td_read(td))
+               show_ddir_status(td, rs, DDIR_READ);
+       if (td_write(td))
+               show_ddir_status(td, rs, DDIR_WRITE);
 
        runtime = mtime_since(&td->epoch, &td->end_time);
        if (runtime) {
 
        runtime = mtime_since(&td->epoch, &td->end_time);
        if (runtime) {
diff --git a/time.c b/time.c
index 11ee0e07b94a5030cf79817fda5ce8609320bf81..4bf68a998f8ee43bff9c81eef6ed68127801fc17 100644 (file)
--- a/time.c
+++ b/time.c
@@ -109,14 +109,14 @@ void usec_sleep(struct thread_data *td, unsigned long usec)
 }
 
 void rate_throttle(struct thread_data *td, unsigned long time_spent,
 }
 
 void rate_throttle(struct thread_data *td, unsigned long time_spent,
-                  unsigned int bytes, int ddir)
+                  unsigned int bytes)
 {
        unsigned long usec_cycle;
 
        if (!td->rate)
                return;
 
 {
        unsigned long usec_cycle;
 
        if (!td->rate)
                return;
 
-       usec_cycle = td->rate_usec_cycle * (bytes / td->min_bs[ddir]);
+       usec_cycle = td->rate_usec_cycle * (bytes / td->rw_min_bs);
 
        if (time_spent < usec_cycle) {
                unsigned long s = usec_cycle - time_spent;
 
        if (time_spent < usec_cycle) {
                unsigned long s = usec_cycle - time_spent;