#include <unistd.h>
#include <errno.h>
#include <assert.h>
+#include <time.h>
#include <sys/mman.h>
#include "fio.h"
#include "os.h"
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);
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;
{
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:
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
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) {
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;
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);