time_based: Avoid restarting main I/O loop
Previously, when fio had written a volume of I/O equal to the size
argument, it restarted the main do_io loop.
This patch allows time_based tests to be run for longer than one
cycle in the do_io main loop. This has a couple of advantages:
* The random number generator is not reset on each iteration
of the loop, so running longer will reach different locations.
* There is not a throughput-reducing point where all operations
must be reaped before new operations are submitted.
The implementation consists of two minor changes:
* In the do_io loop, a time_based test will not exit the loop for
reading or writing too much data.
* When reading or writing sequentially, the operations wrap around
to the beginning after reading the end within the
get_next_seq_block function.
Modified by Jens to properly restart when using a randommap
as well.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/io_u.c b/io_u.c
index ba67579..65a144d 100644
--- a/io_u.c
+++ b/io_u.c
@@ -237,13 +237,18 @@
static int get_next_rand_block(struct thread_data *td, struct fio_file *f,
enum fio_ddir ddir, unsigned long long *b)
{
- if (get_next_rand_offset(td, f, ddir, b)) {
- dprint(FD_IO, "%s: rand offset failed, last=%llu, size=%llu\n",
- f->file_name, f->last_pos, f->real_file_size);
- return 1;
+ if (!get_next_rand_offset(td, f, ddir, b))
+ return 0;
+
+ if (td->o.time_based) {
+ fio_file_reset(f);
+ if (!get_next_rand_offset(td, f, ddir, b))
+ return 0;
}
- return 0;
+ dprint(FD_IO, "%s: rand offset failed, last=%llu, size=%llu\n",
+ f->file_name, f->last_pos, f->real_file_size);
+ return 1;
}
static int get_next_seq_block(struct thread_data *td, struct fio_file *f,
@@ -251,6 +256,9 @@
{
assert(ddir_rw(ddir));
+ if (f->last_pos >= f->io_size && td->o.time_based)
+ f->last_pos = f->last_pos - f->io_size;
+
if (f->last_pos < f->real_file_size) {
unsigned long long pos;