From: Jens Axboe Date: Wed, 7 Dec 2005 07:56:28 +0000 (+0100) Subject: [PATCH] fio: fixup ->io_prep to not require 'read' and implement timeout X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=d58fafc4560ae4e82b15b4b139674054c2f71554;p=disktools.git [PATCH] fio: fixup ->io_prep to not require 'read' and implement timeout --- diff --git a/fio-io.c b/fio-io.c index 3792a9b..fc8dc83 100644 --- a/fio-io.c +++ b/fio-io.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "fio.h" #include "os.h" @@ -27,15 +28,45 @@ static int fio_io_sync(struct thread_data *td) return fsync(td->fd); } +static int fill_timespec(struct timespec *ts) +{ +#ifdef _POSIX_TIMERS + if (!clock_gettime(CLOCK_MONOTONIC, ts)) + return 0; + + perror("clock_gettime"); +#endif + return 1; +} + +static unsigned long long ts_utime_since_now(struct timespec *t) +{ + long long sec, nsec; + struct timespec now; + + if (fill_timespec(&now)) + return 0; + + sec = now.tv_sec - t->tv_sec; + nsec = now.tv_nsec - t->tv_nsec; + if (sec > 0 && nsec < 0) { + sec--; + nsec += 1000000000; + } + + sec *= 1000000; + nsec /= 1000; + return sec + nsec; +} + struct libaio_data { io_context_t aio_ctx; struct io_event *aio_events; }; -static int fio_libaio_io_prep(struct thread_data *td, struct io_u *io_u, - int read) +static int fio_libaio_io_prep(struct thread_data *td, struct io_u *io_u) { - if (read) + if (io_u->ddir == DDIR_READ) io_prep_pread(&io_u->iocb, td->fd, io_u->buf, io_u->buflen, io_u->offset); else io_prep_pwrite(&io_u->iocb, td->fd, io_u->buf, io_u->buflen, io_u->offset); @@ -161,8 +192,7 @@ static int fio_posixaio_cancel(struct thread_data *td, struct io_u *io_u) return 1; } -static int fio_posixaio_prep(struct thread_data *td, struct io_u *io_u, - int read) +static int fio_posixaio_prep(struct thread_data *td, struct io_u *io_u) { struct aiocb *aiocb = &io_u->aiocb; @@ -180,7 +210,11 @@ static int fio_posixaio_getevents(struct thread_data *td, int min, int max, { struct posixaio_data *pd = td->io_data; struct list_head *entry; - int r; + struct timespec start; + int r, have_timeout = 0; + + if (t && !fill_timespec(&start)) + have_timeout = 1; r = 0; restart: @@ -211,6 +245,14 @@ restart: if (r >= min) return r; + if (have_timeout) { + unsigned long long usec; + + usec = (t->tv_sec * 1000000) + (t->tv_nsec / 1000); + if (ts_utime_since_now(&start) > usec) + return r; + } + /* * hrmpf, we need to wait for more. we should use aio_suspend, for * now just sleep a little and recheck status of busy-and-not-seen @@ -308,8 +350,7 @@ static struct io_u *fio_syncio_event(struct thread_data *td, int event) return sd->last_io_u; } -static int fio_syncio_prep(struct thread_data *td, struct io_u *io_u, - int read) +static int fio_syncio_prep(struct thread_data *td, struct io_u *io_u) { if (td->cur_off != io_u->offset) { if (lseek(td->fd, io_u->offset, SEEK_SET) == -1) { @@ -331,7 +372,7 @@ static int fio_syncio_queue(struct thread_data *td, struct io_u *io_u) else ret = write(td->fd, io_u->buf, io_u->buflen); - if (ret != io_u->buflen) { + if ((unsigned int) ret != io_u->buflen) { if (ret > 0) { io_u->resid = io_u->buflen - ret; io_u->error = ENODATA; diff --git a/fio.c b/fio.c index cc5a9da..7d186b0 100644 --- a/fio.c +++ b/fio.c @@ -580,14 +580,14 @@ static struct io_u *__get_io_u(struct thread_data *td) static int td_io_prep(struct thread_data *td, struct io_u *io_u, int read) { - if (td->io_prep && td->io_prep(td, io_u, read)) - return 1; - if (read) io_u->ddir = DDIR_READ; else io_u->ddir = DDIR_WRITE; + if (td->io_prep && td->io_prep(td, io_u)) + return 1; + return 0; } diff --git a/fio.h b/fio.h index ff8e78e..6fad449 100644 --- a/fio.h +++ b/fio.h @@ -148,7 +148,7 @@ struct thread_data { void *io_data; char io_engine_name[16]; - int (*io_prep)(struct thread_data *, struct io_u *, int); + int (*io_prep)(struct thread_data *, struct io_u *); int (*io_queue)(struct thread_data *, struct io_u *); int (*io_getevents)(struct thread_data *, int, int, struct timespec *); struct io_u *(*io_event)(struct thread_data *, int);