[PATCH] syslet engine: use pread instead lseek+read
[fio.git] / engines / mmap.c
CommitLineData
2866c82d
JA
1/*
2 * regular read/write sync io engine
3 *
4 */
5#include <stdio.h>
6#include <stdlib.h>
7#include <unistd.h>
8#include <errno.h>
9#include <assert.h>
10#include <sys/mman.h>
5f350952
JA
11
12#include "../fio.h"
13#include "../os.h"
2866c82d
JA
14
15struct mmapio_data {
16 struct io_u *last_io_u;
17};
18
19static int fio_mmapio_getevents(struct thread_data *td, int fio_unused min,
20 int max, struct timespec fio_unused *t)
21{
22 assert(max <= 1);
23
24 /*
25 * we can only have one finished io_u for sync io, since the depth
26 * is always 1
27 */
28 if (list_empty(&td->io_u_busylist))
29 return 0;
30
31 return 1;
32}
33
34static struct io_u *fio_mmapio_event(struct thread_data *td, int event)
35{
36 struct mmapio_data *sd = td->io_ops->data;
37
38 assert(event == 0);
39
40 return sd->last_io_u;
41}
42
43
44static int fio_mmapio_queue(struct thread_data *td, struct io_u *io_u)
45{
53cdc686
JA
46 struct fio_file *f = io_u->file;
47 unsigned long long real_off = io_u->offset - f->file_offset;
2866c82d
JA
48 struct mmapio_data *sd = td->io_ops->data;
49
50 if (io_u->ddir == DDIR_READ)
cec6b55d 51 memcpy(io_u->xfer_buf, f->mmap + real_off, io_u->xfer_buflen);
87dc1ab1 52 else if (io_u->ddir == DDIR_WRITE)
cec6b55d 53 memcpy(f->mmap + real_off, io_u->xfer_buf, io_u->xfer_buflen);
b907a5b5
JA
54 else if (io_u->ddir == DDIR_SYNC) {
55 if (msync(f->mmap, f->file_size, MS_SYNC))
56 io_u->error = errno;
57 }
2866c82d
JA
58
59 /*
60 * not really direct, but should drop the pages from the cache
61 */
b907a5b5 62 if (td->odirect && io_u->ddir != DDIR_SYNC) {
cec6b55d 63 if (msync(f->mmap + real_off, io_u->xfer_buflen, MS_SYNC) < 0)
2866c82d 64 io_u->error = errno;
cec6b55d 65 if (madvise(f->mmap + real_off, io_u->xfer_buflen, MADV_DONTNEED) < 0)
2866c82d
JA
66 io_u->error = errno;
67 }
68
69 if (!io_u->error)
70 sd->last_io_u = io_u;
95bcd815
JA
71 else
72 td_verror(td, io_u->error);
2866c82d
JA
73
74 return io_u->error;
75}
76
2866c82d
JA
77static void fio_mmapio_cleanup(struct thread_data *td)
78{
79 if (td->io_ops->data) {
80 free(td->io_ops->data);
81 td->io_ops->data = NULL;
82 }
83}
84
85static int fio_mmapio_init(struct thread_data *td)
86{
87 struct mmapio_data *sd = malloc(sizeof(*sd));
88
89 sd->last_io_u = NULL;
90 td->io_ops->data = sd;
91 return 0;
92}
93
5f350952 94static struct ioengine_ops ioengine = {
2866c82d
JA
95 .name = "mmap",
96 .version = FIO_IOOPS_VERSION,
97 .init = fio_mmapio_init,
98 .queue = fio_mmapio_queue,
99 .getevents = fio_mmapio_getevents,
100 .event = fio_mmapio_event,
101 .cleanup = fio_mmapio_cleanup,
d9257bea 102 .flags = FIO_SYNCIO | FIO_MMAPIO,
2866c82d 103};
5f350952
JA
104
105static void fio_init fio_mmapio_register(void)
106{
107 register_ioengine(&ioengine);
108}
109
110static void fio_exit fio_mmapio_unregister(void)
111{
112 unregister_ioengine(&ioengine);
113}