summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2005-12-07 08:56:28 +0100
committerJens Axboe <axboe@suse.de>2005-12-07 08:56:28 +0100
commitd58fafc4560ae4e82b15b4b139674054c2f71554 (patch)
treed7ef342a608df707c11260f424e6fdadca02c429
parentbd84df5f937dd97ac9bac6754a8dd6297d41b14d (diff)
[PATCH] fio: fixup ->io_prep to not require 'read' and implement timeout
-rw-r--r--fio-io.c59
-rw-r--r--fio.c6
-rw-r--r--fio.h2
3 files changed, 54 insertions, 13 deletions
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 <unistd.h>
#include <errno.h>
#include <assert.h>
+#include <time.h>
#include <sys/mman.h>
#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);