lib/pattern: fix formatting
[fio.git] / engines / null.c
CommitLineData
a94ea28b 1/*
da751ca9
JA
2 * null engine
3 *
4 * IO engine that doesn't do any real IO transfers, it just pretends to.
5 * The main purpose is to test fio itself.
a94ea28b 6 *
46a67478
DG
7 * It also can act as external C++ engine - compiled with:
8 *
cef0a835 9 * g++ -O2 -g -shared -rdynamic -fPIC -o cpp_null null.c \
c822572d 10 * -include ../config-host.h -DFIO_EXTERNAL_ENGINE
966fcbd4 11 *
12 * to test it execute:
13 *
14 * LD_LIBRARY_PATH=./engines ./fio examples/cpp_null.fio
46a67478 15 *
a94ea28b 16 */
a94ea28b 17#include <stdlib.h>
a94ea28b
JA
18#include <assert.h>
19
20#include "../fio.h"
a94ea28b 21
65afa5f2
JA
22struct null_data {
23 struct io_u **io_us;
24 int queued;
25 int events;
26};
27
966fcbd4 28static struct io_u *null_event(struct null_data *nd, int event)
65afa5f2 29{
65afa5f2
JA
30 return nd->io_us[event];
31}
32
966fcbd4 33static int null_getevents(struct null_data *nd, unsigned int min_events,
34 unsigned int fio_unused max,
35 const struct timespec fio_unused *t)
65afa5f2 36{
7401c088 37 int ret = 0;
966fcbd4 38
7401c088
JA
39 if (min_events) {
40 ret = nd->events;
41 nd->events = 0;
42 }
65afa5f2 43
65afa5f2
JA
44 return ret;
45}
46
56b6bc25
VF
47static void null_queued(struct thread_data *td, struct null_data *nd)
48{
49 struct timespec now;
50
51 if (!fio_fill_issue_time(td))
52 return;
53
54 fio_gettime(&now, NULL);
55
56 for (int i = 0; i < nd->queued; i++) {
57 struct io_u *io_u = nd->io_us[i];
58
59 memcpy(&io_u->issue_time, &now, sizeof(now));
60 io_u_queued(td, io_u);
61 }
62}
63
966fcbd4 64static int null_commit(struct thread_data *td, struct null_data *nd)
65afa5f2 65{
ed8bd849 66 if (!nd->events) {
56b6bc25
VF
67 null_queued(td, nd);
68
46a67478 69#ifndef FIO_EXTERNAL_ENGINE
838bc709 70 io_u_mark_submit(td, nd->queued);
46a67478 71#endif
ed8bd849
JA
72 nd->events = nd->queued;
73 nd->queued = 0;
74 }
75
65afa5f2
JA
76 return 0;
77}
78
2e4ef4fb
JA
79static enum fio_q_status null_queue(struct thread_data *td,
80 struct null_data *nd, struct io_u *io_u)
a94ea28b 81{
7101d9c2
JA
82 fio_ro_check(td, io_u);
83
65afa5f2
JA
84 if (td->io_ops->flags & FIO_SYNCIO)
85 return FIO_Q_COMPLETED;
ed8bd849
JA
86 if (nd->events)
87 return FIO_Q_BUSY;
65afa5f2
JA
88
89 nd->io_us[nd->queued++] = io_u;
90 return FIO_Q_QUEUED;
a94ea28b
JA
91}
92
966fcbd4 93static int null_open(struct null_data fio_unused *nd,
94 struct fio_file fio_unused *f)
b5af8293
JA
95{
96 return 0;
97}
98
966fcbd4 99static void null_cleanup(struct null_data *nd)
65afa5f2 100{
65afa5f2 101 if (nd) {
02a3d83f 102 free(nd->io_us);
65afa5f2 103 free(nd);
65afa5f2
JA
104 }
105}
106
7746976c 107static struct null_data *null_init(struct thread_data *td)
65afa5f2 108{
7746976c 109 struct null_data *nd = (struct null_data *) malloc(sizeof(*nd));
65afa5f2
JA
110
111 memset(nd, 0, sizeof(*nd));
112
2dc1bbeb 113 if (td->o.iodepth != 1) {
46a67478 114 nd->io_us = (struct io_u **) malloc(td->o.iodepth * sizeof(struct io_u *));
2dc1bbeb 115 memset(nd->io_us, 0, td->o.iodepth * sizeof(struct io_u *));
d54ae223 116 td->io_ops->flags |= FIO_ASYNCIO_SETS_ISSUE_TIME;
65afa5f2
JA
117 } else
118 td->io_ops->flags |= FIO_SYNCIO;
119
d54ae223 120 td_set_ioengine_flags(td);
7746976c 121 return nd;
65afa5f2
JA
122}
123
46a67478 124#ifndef __cplusplus
966fcbd4 125
126static struct io_u *fio_null_event(struct thread_data *td, int event)
127{
ca65714c 128 return null_event(td->io_ops_data, event);
966fcbd4 129}
130
131static int fio_null_getevents(struct thread_data *td, unsigned int min_events,
132 unsigned int max, const struct timespec *t)
133{
ca65714c 134 struct null_data *nd = td->io_ops_data;
966fcbd4 135 return null_getevents(nd, min_events, max, t);
136}
137
138static int fio_null_commit(struct thread_data *td)
139{
ca65714c 140 return null_commit(td, td->io_ops_data);
966fcbd4 141}
142
2e4ef4fb
JA
143static enum fio_q_status fio_null_queue(struct thread_data *td,
144 struct io_u *io_u)
966fcbd4 145{
ca65714c 146 return null_queue(td, td->io_ops_data, io_u);
966fcbd4 147}
148
149static int fio_null_open(struct thread_data *td, struct fio_file *f)
150{
ca65714c 151 return null_open(td->io_ops_data, f);
966fcbd4 152}
153
154static void fio_null_cleanup(struct thread_data *td)
155{
ca65714c 156 null_cleanup(td->io_ops_data);
966fcbd4 157}
158
159static int fio_null_init(struct thread_data *td)
160{
7746976c
TK
161 td->io_ops_data = null_init(td);
162 assert(td->io_ops_data);
163 return 0;
966fcbd4 164}
165
a94ea28b
JA
166static struct ioengine_ops ioengine = {
167 .name = "null",
168 .version = FIO_IOOPS_VERSION,
a94ea28b 169 .queue = fio_null_queue,
65afa5f2
JA
170 .commit = fio_null_commit,
171 .getevents = fio_null_getevents,
172 .event = fio_null_event,
173 .init = fio_null_init,
174 .cleanup = fio_null_cleanup,
b5af8293 175 .open_file = fio_null_open,
5c57c084 176 .flags = FIO_DISKLESSIO | FIO_FAKEIO,
a94ea28b
JA
177};
178
179static void fio_init fio_null_register(void)
180{
181 register_ioengine(&ioengine);
182}
183
184static void fio_exit fio_null_unregister(void)
185{
186 unregister_ioengine(&ioengine);
187}
46a67478
DG
188
189#else
190
191#ifdef FIO_EXTERNAL_ENGINE
966fcbd4 192
193struct NullData {
194 NullData(struct thread_data *td)
195 {
7746976c
TK
196 impl_ = null_init(td);
197 assert(impl_);
966fcbd4 198 }
199
200 ~NullData()
201 {
202 null_cleanup(impl_);
203 }
204
205 static NullData *get(struct thread_data *td)
206 {
207 return reinterpret_cast<NullData *>(td->io_ops_data);
208 }
209
210 io_u *fio_null_event(struct thread_data *, int event)
211 {
212 return null_event(impl_, event);
213 }
214
215 int fio_null_getevents(struct thread_data *, unsigned int min_events,
216 unsigned int max, const struct timespec *t)
217 {
218 return null_getevents(impl_, min_events, max, t);
219 }
220
221 int fio_null_commit(struct thread_data *td)
222 {
223 return null_commit(td, impl_);
224 }
225
cef0a835 226 fio_q_status fio_null_queue(struct thread_data *td, struct io_u *io_u)
966fcbd4 227 {
228 return null_queue(td, impl_, io_u);
229 }
230
231 int fio_null_open(struct thread_data *, struct fio_file *f)
232 {
233 return null_open(impl_, f);
234 }
235
7caf10f1 236private:
966fcbd4 237 struct null_data *impl_;
238};
239
46a67478 240extern "C" {
966fcbd4 241
242static struct io_u *fio_null_event(struct thread_data *td, int event)
243{
244 return NullData::get(td)->fio_null_event(td, event);
245}
246
247static int fio_null_getevents(struct thread_data *td, unsigned int min_events,
248 unsigned int max, const struct timespec *t)
249{
250 return NullData::get(td)->fio_null_getevents(td, min_events, max, t);
251}
252
253static int fio_null_commit(struct thread_data *td)
254{
255 return NullData::get(td)->fio_null_commit(td);
256}
257
cef0a835 258static fio_q_status fio_null_queue(struct thread_data *td, struct io_u *io_u)
966fcbd4 259{
260 return NullData::get(td)->fio_null_queue(td, io_u);
261}
262
263static int fio_null_open(struct thread_data *td, struct fio_file *f)
264{
265 return NullData::get(td)->fio_null_open(td, f);
266}
267
268static int fio_null_init(struct thread_data *td)
269{
270 td->io_ops_data = new NullData(td);
271 return 0;
272}
273
274static void fio_null_cleanup(struct thread_data *td)
275{
276 delete NullData::get(td);
277}
278
247f299a 279static struct ioengine_ops ioengine;
8d6ecac2
JA
280void get_ioengine(struct ioengine_ops **ioengine_ptr)
281{
247f299a
TK
282 *ioengine_ptr = &ioengine;
283
284 ioengine.name = "cpp_null";
285 ioengine.version = FIO_IOOPS_VERSION;
286 ioengine.queue = fio_null_queue;
287 ioengine.commit = fio_null_commit;
288 ioengine.getevents = fio_null_getevents;
289 ioengine.event = fio_null_event;
290 ioengine.init = fio_null_init;
291 ioengine.cleanup = fio_null_cleanup;
292 ioengine.open_file = fio_null_open;
293 ioengine.flags = FIO_DISKLESSIO | FIO_FAKEIO;
46a67478
DG
294}
295}
296#endif /* FIO_EXTERNAL_ENGINE */
297
298#endif /* __cplusplus */