Add time_based option
authorJens Axboe <jens.axboe@oracle.com>
Tue, 17 Apr 2007 18:14:42 +0000 (20:14 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Tue, 17 Apr 2007 18:14:42 +0000 (20:14 +0200)
This allows fio to keep running, even if the workload has completed.
It will simply restart the workload over and over, for as long as the
runtime setting allows.

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

diff --git a/HOWTO b/HOWTO
index 2cc62b2221c6654fad9b577c445f7e89553e5d3c..5fdc1f79773cefea0b3ba6196408155c0b44bdcd 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -477,6 +477,11 @@ runtime=int        Tell fio to terminate processing after the specified number
                a specified job will run, so this parameter is handy to
                cap the total runtime to a given time.
 
                a specified job will run, so this parameter is handy to
                cap the total runtime to a given time.
 
+time_based     If set, fio will run for the duration of the runtime
+               specified even if the file(s) are completey read or
+               written. It will simply loop over the same workload
+               as many times as the runtime allows.
+
 invalidate=bool        Invalidate the buffer/page cache parts for this file prior
                to starting io. Defaults to true.
 
 invalidate=bool        Invalidate the buffer/page cache parts for this file prior
                to starting io. Defaults to true.
 
diff --git a/eta.c b/eta.c
index 31028dd840976e4d1137824c1101269351ec7b2a..39241c5aaf5a529dee695e86ef09c5c17d1efb15 100644 (file)
--- a/eta.c
+++ b/eta.c
@@ -118,13 +118,19 @@ static int thread_eta(struct thread_data *td, unsigned long elapsed)
                bytes_total /= (td->o.zone_skip / td->o.zone_size);
 
        if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING) {
                bytes_total /= (td->o.zone_skip / td->o.zone_size);
 
        if (td->runstate == TD_RUNNING || td->runstate == TD_VERIFYING) {
-               double perc;
+               double perc, perc_t;
 
                bytes_done = td->io_bytes[DDIR_READ] + td->io_bytes[DDIR_WRITE];
                perc = (double) bytes_done / (double) bytes_total;
                if (perc > 1.0)
                        perc = 1.0;
 
 
                bytes_done = td->io_bytes[DDIR_READ] + td->io_bytes[DDIR_WRITE];
                perc = (double) bytes_done / (double) bytes_total;
                if (perc > 1.0)
                        perc = 1.0;
 
+               if (td->o.time_based) {
+                       perc_t = (double) elapsed / (double) td->o.timeout;
+                       if (perc_t < perc)
+                               perc = perc_t;
+               }
+
                eta_sec = (unsigned long) (elapsed * (1.0 / perc)) - elapsed;
 
                if (td->o.timeout && eta_sec > (td->o.timeout - elapsed))
                eta_sec = (unsigned long) (elapsed * (1.0 / perc)) - elapsed;
 
                if (td->o.timeout && eta_sec > (td->o.timeout - elapsed))
diff --git a/fio.c b/fio.c
index d85f956f7c552a7e78b5fc18fdec1e6f9a17f372..6f4fddae8f0cbcbdc28cc96dcbd7e722b3b07997 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -751,6 +751,7 @@ static void *thread_main(void *data)
        unsigned long long runtime[2];
        struct thread_data *td = data;
        unsigned long elapsed;
        unsigned long long runtime[2];
        struct thread_data *td = data;
        unsigned long elapsed;
+       struct timeval t;
        int clear_state;
 
        if (!td->o.use_thread)
        int clear_state;
 
        if (!td->o.use_thread)
@@ -824,7 +825,7 @@ static void *thread_main(void *data)
 
        runtime[0] = runtime[1] = 0;
        clear_state = 0;
 
        runtime[0] = runtime[1] = 0;
        clear_state = 0;
-       while (td->o.loops--) {
+       while (td->o.time_based || td->o.loops--) {
                fio_gettime(&td->start, NULL);
                memcpy(&td->ts.stat_sample_time, &td->start, sizeof(td->start));
 
                fio_gettime(&td->start, NULL);
                memcpy(&td->ts.stat_sample_time, &td->start, sizeof(td->start));
 
@@ -860,6 +861,10 @@ static void *thread_main(void *data)
                if (td->error || td->terminate)
                        break;
 
                if (td->error || td->terminate)
                        break;
 
+               fio_gettime(&t, NULL);
+               if (runtime_exceeded(td, &t))
+                       break;
+
                if (td->o.verify == VERIFY_NONE)
                        continue;
 
                if (td->o.verify == VERIFY_NONE)
                        continue;
 
diff --git a/fio.h b/fio.h
index 9490edc11e1a2ea924f1dea3bf75f2d9e36d0fdf..92264d998752900730db96bb870af2b591b4afe3 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -413,6 +413,7 @@ struct thread_options {
        unsigned int group_reporting;
        unsigned int fadvise_hint;
        unsigned int zero_buffers;
        unsigned int group_reporting;
        unsigned int fadvise_hint;
        unsigned int zero_buffers;
+       unsigned int time_based;
 
        char *read_iolog_file;
        char *write_iolog_file;
 
        char *read_iolog_file;
        char *write_iolog_file;
diff --git a/init.c b/init.c
index 09bbce4c597ea6ca5aae939fe05482c069636cbd..b5f9abcef122f618f546540380f546d1f21db6af 100644 (file)
--- a/init.c
+++ b/init.c
@@ -274,6 +274,11 @@ static int fixup_options(struct thread_data *td)
                return 1;
        }
 
                return 1;
        }
 
+       if (!o->timeout && o->time_based) {
+               log_err("fio: time_based requires a runtime/timeout setting\n");
+               o->time_based = 0;
+       }
+
        return 0;
 }
 
        return 0;
 }
 
index 754eb81fccfe1a14f6949f30d07475ea09acc834..7a81880a200e03f3e10c3637045a94aa3bcafb37 100644 (file)
--- a/options.c
+++ b/options.c
@@ -477,6 +477,12 @@ static struct fio_option options[] = {
                .help   = "Stop workload when this amount of time has passed",
                .def    = "0",
        },
                .help   = "Stop workload when this amount of time has passed",
                .def    = "0",
        },
+       {
+               .name   = "time_based",
+               .type   = FIO_OPT_STR_SET,
+               .off1   = td_var_offset(time_based),
+               .help   = "Keep running until runtime/timeout is met",
+       },
        {
                .name   = "mem",
                .alias  = "iomem",
        {
                .name   = "mem",
                .alias  = "iomem",