From 413dd459a7710ba421061e840dd9ac3161c70f20 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 23 Feb 2007 09:26:09 +0100 Subject: [PATCH] Streamline thread_data data direction setting and checking 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 --- engines/mmap.c | 2 +- engines/net.c | 4 ++-- eta.c | 18 +++++++++--------- filesetup.c | 7 +++---- fio.c | 32 ++++++++++++++++++++++---------- fio.h | 20 +++++++++++++------- init.c | 38 +++++++++++++++----------------------- io_u.c | 4 ++-- log.c | 8 ++++---- stat.c | 7 ++++--- time.c | 4 ++-- 11 files changed, 77 insertions(+), 67 deletions(-) diff --git a/engines/mmap.c b/engines/mmap.c index d4299143..bd59b28a 100644 --- a/engines/mmap.c +++ b/engines/mmap.c @@ -47,7 +47,7 @@ static int fio_mmapio_init(struct thread_data *td) struct fio_file *f; int i; - if (td->ddir == DDIR_READ && !td_rw(td)) + if (!td_write(td)) return 0; /* diff --git a/engines/net.c b/engines/net.c index 55b2128e..60a68778 100644 --- a/engines/net.c +++ b/engines/net.c @@ -223,7 +223,7 @@ static int fio_netio_setup(struct thread_data *td) return 1; } - if (td->iomix) { + if (td_rw(td)) { 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); - if (td->ddir == DDIR_READ) { + if (td_read(td)) { send_to_net(td) = 0; ret = fio_netio_setup_listen(td, port); } else { diff --git a/eta.c b/eta.c index 8e17d20e..960bf4d1 100644 --- 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)) { - if (td->sequential) - c = 'M'; - else + if (td_random(td)) c = 'm'; - } else if (td_read(td)) { - if (td->sequential) - c = 'R'; else + c = 'M'; + } else if (td_read(td)) { + if (td_random(td)) c = 'r'; - } else { - if (td->sequential) - c = 'W'; else + c = 'R'; + } else { + if (td_random(td)) c = 'w'; + else + c = 'W'; } break; case TD_VERIFYING: diff --git a/filesetup.c b/filesetup.c index 11138b7a..356580e7 100644 --- a/filesetup.c +++ b/filesetup.c @@ -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); - if (file_there && td->ddir == DDIR_WRITE && - !td->overwrite) { + if (file_there && td_write(td) && !td->overwrite) { 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->sequential) { + if (!td_random(td)) { 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->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; diff --git a/fio.c b/fio.c index 92063939..58e03f9a 100644 --- 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; - int ddir = td->ddir; /* * 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) { + unsigned long long bytes = 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; + } 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; } @@ -458,7 +469,7 @@ requeue: */ 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) @@ -736,10 +747,11 @@ static void *thread_main(void *data) 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; diff --git a/fio.h b/fio.h index 8c46b3f9..8880ea61 100644 --- a/fio.h +++ b/fio.h @@ -28,6 +28,13 @@ enum fio_ddir { 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 */ @@ -290,12 +297,10 @@ struct thread_data { 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 sequential; 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; -#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)) @@ -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 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); diff --git a/init.c b/init.c index 01e615f9..9ed99d79 100644 --- 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 */ - 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; /* @@ -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) { - 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; - int numjobs, ddir, i; + int numjobs, i; 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); - ddir = td->ddir + (!td->sequential << 1) + (td->iomix << 2); - 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]); - 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); @@ -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[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) @@ -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)) { - td->ddir = DDIR_READ; - td->sequential = 1; + td->td_ddir = TD_DDIR_READ; 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)) { - td->ddir = DDIR_WRITE; - td->sequential = 1; + td->td_ddir = TD_DDIR_WRITE; 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)) { - td->ddir = DDIR_READ; - td->iomix = 1; - td->sequential = 1; + td->td_ddir = TD_DDIR_RW; 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; } diff --git a/io_u.c b/io_u.c index 6fb754e7..48d40760 100644 --- 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; - if (!td->sequential) { + if (td_random(td)) { 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 */ - if (!td->read_iolog && !td->sequential && !td->norandommap) + if (!td->read_iolog && td_random(td) && !td->norandommap) mark_random_map(td, f, io_u); /* diff --git a/log.c b/log.c index dd63c389..513128d6 100644 --- 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 */ - if (td->sequential || !td->overwrite) { + if (!td_random(td) || !td->overwrite) { 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) - td->ddir = DDIR_READ; + td->td_ddir = TD_DDIR_READ; else if (!reads && writes) - td->ddir = DDIR_READ; + td->td_ddir = TD_DDIR_READ; else - td->iomix = 1; + td->td_ddir = TD_DDIR_RW; return 0; } diff --git a/stat.c b/stat.c index 352ba48f..34b2b6a5 100644 --- 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); - 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) { diff --git a/time.c b/time.c index 11ee0e07..4bf68a99 100644 --- 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, - unsigned int bytes, int ddir) + unsigned int bytes) { 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; -- 2.25.1