Move fls.h in with the other lib helpers
[fio.git] / engines / solarisaio.c
CommitLineData
417f0068
JA
1/*
2 * Native Solaris async IO engine
3 *
4 */
5#include <stdio.h>
6#include <stdlib.h>
7#include <unistd.h>
8#include <errno.h>
9
10#include "../fio.h"
11
12#ifdef FIO_HAVE_SOLARISAIO
13
14#include <sys/asynch.h>
15
16struct solarisaio_data {
17 struct io_u **aio_events;
18 unsigned int nr;
5cf56c03 19 unsigned int max_depth;
417f0068
JA
20};
21
22static int fio_solarisaio_cancel(struct thread_data fio_unused *td,
23 struct io_u *io_u)
24{
25 return aiocancel(&io_u->resultp);
26}
27
28static int fio_solarisaio_prep(struct thread_data fio_unused *td,
29 struct io_u *io_u)
30{
31 io_u->resultp.aio_return = AIO_INPROGRESS;
32 return 0;
33}
34
35static int fio_solarisaio_getevents(struct thread_data *td, unsigned int min,
36 unsigned int max, struct timespec *t)
37{
38 struct solarisaio_data *sd = td->io_ops->data;
39 struct timeval tv;
40 unsigned int r;
41
42 r = 0;
43 do {
44 struct io_u *io_u;
45 aio_result_t *p;
46
47 if (!min || !t) {
48 tv.tv_sec = 0;
49 tv.tv_usec = 0;
50 } else {
51 tv.tv_sec = t->tv_sec;
52 tv.tv_usec = t->tv_nsec / 1000;
53 }
54
55 p = aiowait(&tv);
56 if (p) {
57 io_u = container_of(p, struct io_u, resultp);
58
59 sd->aio_events[r++] = io_u;
60 sd->nr--;
61
62 if (io_u->resultp.aio_return >= 0) {
63 io_u->resid = io_u->xfer_buflen
64 - io_u->resultp.aio_return;
65 io_u->error = 0;
66 } else
67 io_u->error = io_u->resultp.aio_return;
68 }
69 } while (r < min);
70
71 return r;
72}
73
74static struct io_u *fio_solarisaio_event(struct thread_data *td, int event)
75{
76 struct solarisaio_data *sd = td->io_ops->data;
77
78 return sd->aio_events[event];
79}
80
81static int fio_solarisaio_queue(struct thread_data fio_unused *td,
82 struct io_u *io_u)
83{
84 struct solarisaio_data *sd = td->io_ops->data;
85 struct fio_file *f = io_u->file;
86 off_t off;
87 int ret;
88
89 fio_ro_check(td, io_u);
90
91 if (io_u->ddir == DDIR_SYNC) {
92 if (sd->nr)
93 return FIO_Q_BUSY;
94 if (fsync(f->fd) < 0)
95 io_u->error = errno;
96
97 return FIO_Q_COMPLETED;
98 }
99
5cf56c03 100 if (sd->nr == sd->max_depth)
417f0068
JA
101 return FIO_Q_BUSY;
102
103 off = io_u->offset;
104 if (io_u->ddir == DDIR_READ)
105 ret = aioread(f->fd, io_u->xfer_buf, io_u->xfer_buflen, off,
106 SEEK_SET, &io_u->resultp);
107 else
108 ret = aiowrite(f->fd, io_u->xfer_buf, io_u->xfer_buflen, off,
109 SEEK_SET, &io_u->resultp);
110 if (ret) {
111 io_u->error = errno;
112 td_verror(td, io_u->error, "xfer");
113 return FIO_Q_COMPLETED;
114 }
115
116 sd->nr++;
117 return FIO_Q_QUEUED;
118}
119
120static void fio_solarisaio_cleanup(struct thread_data *td)
121{
122 struct solarisaio_data *sd = td->io_ops->data;
123
124 if (sd) {
125 free(sd->aio_events);
126 free(sd);
127 }
128}
129
130static int fio_solarisaio_init(struct thread_data *td)
131{
132 struct solarisaio_data *sd = malloc(sizeof(*sd));
5cf56c03
JA
133 unsigned int max_depth;
134
135 max_depth = td->o.iodepth;
136 if (max_depth > MAXASYNCHIO) {
137 max_depth = MAXASYNCHIO;
138 log_info("fio: lower depth to %d due to OS constraints\n",
139 max_depth);
140 }
417f0068
JA
141
142 memset(sd, 0, sizeof(*sd));
5cf56c03
JA
143 sd->aio_events = malloc(max_depth * sizeof(struct io_u *));
144 memset(sd->aio_events, 0, max_depth * sizeof(struct io_u *));
145 sd->max_depth = max_depth;
417f0068
JA
146
147 td->io_ops->data = sd;
148 return 0;
149}
150
151static struct ioengine_ops ioengine = {
152 .name = "solarisaio",
153 .version = FIO_IOOPS_VERSION,
154 .init = fio_solarisaio_init,
155 .prep = fio_solarisaio_prep,
156 .queue = fio_solarisaio_queue,
157 .cancel = fio_solarisaio_cancel,
158 .getevents = fio_solarisaio_getevents,
159 .event = fio_solarisaio_event,
160 .cleanup = fio_solarisaio_cleanup,
161 .open_file = generic_open_file,
162 .close_file = generic_close_file,
163};
164
165#else /* FIO_HAVE_SOLARISAIO */
166
167/*
168 * When we have a proper configure system in place, we simply wont build
169 * and install this io engine. For now install a crippled version that
170 * just complains and fails to load.
171 */
172static int fio_solarisaio_init(struct thread_data fio_unused *td)
173{
174 fprintf(stderr, "fio: solarisaio not available\n");
175 return 1;
176}
177
178static struct ioengine_ops ioengine = {
179 .name = "solarisaio",
180 .version = FIO_IOOPS_VERSION,
181 .init = fio_solarisaio_init,
182};
183
184#endif
185
186static void fio_init fio_solarisaio_register(void)
187{
188 register_ioengine(&ioengine);
189}
190
191static void fio_exit fio_solarisaio_unregister(void)
192{
193 unregister_ioengine(&ioengine);
194}