engines/io_uring: ensure sqe stores are ordered SQ ring tail update
[fio.git] / engines / skeleton_external.c
1 /*
2  * Skeleton for a sample external io engine
3  *
4  * Should be compiled with:
5  *
6  * gcc -Wall -O2 -g -shared -rdynamic -fPIC -o skeleton_external.o skeleton_external.c
7  * (also requires -D_GNU_SOURCE -DCONFIG_STRSEP on Linux)
8  *
9  */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <assert.h>
15
16 #include "../fio.h"
17 #include "../optgroup.h"
18
19 /*
20  * The core of the module is identical to the ones included with fio,
21  * read those. You cannot use register_ioengine() and unregister_ioengine()
22  * for external modules, they should be gotten through dlsym()
23  */
24
25 /*
26  * The io engine can define its own options within the io engine source.
27  * The option member must not be at offset 0, due to the way fio parses
28  * the given option. Just add a padding pointer unless the io engine has
29  * something usable.
30  */
31 struct fio_skeleton_options {
32         void *pad; /* avoid ->off1 of fio_option becomes 0 */
33         unsigned int dummy;
34 };
35
36 static struct fio_option options[] = {
37         {
38                 .name   = "dummy",
39                 .lname  = "ldummy",
40                 .type   = FIO_OPT_STR_SET,
41                 .off1   = offsetof(struct fio_skeleton_options, dummy),
42                 .help   = "Set dummy",
43                 .category = FIO_OPT_C_ENGINE, /* always use this */
44                 .group  = FIO_OPT_G_INVALID, /* this can be different */
45         },
46         {
47                 .name   = NULL,
48         },
49 };
50
51 /*
52  * The ->event() hook is called to match an event number with an io_u.
53  * After the core has called ->getevents() and it has returned eg 3,
54  * the ->event() hook must return the 3 events that have completed for
55  * subsequent calls to ->event() with [0-2]. Required.
56  */
57 static struct io_u *fio_skeleton_event(struct thread_data *td, int event)
58 {
59         return NULL;
60 }
61
62 /*
63  * The ->getevents() hook is used to reap completion events from an async
64  * io engine. It returns the number of completed events since the last call,
65  * which may then be retrieved by calling the ->event() hook with the event
66  * numbers. Required.
67  */
68 static int fio_skeleton_getevents(struct thread_data *td, unsigned int min,
69                                   unsigned int max, const struct timespec *t)
70 {
71         return 0;
72 }
73
74 /*
75  * The ->cancel() hook attempts to cancel the io_u. Only relevant for
76  * async io engines, and need not be supported.
77  */
78 static int fio_skeleton_cancel(struct thread_data *td, struct io_u *io_u)
79 {
80         return 0;
81 }
82
83 /*
84  * The ->queue() hook is responsible for initiating io on the io_u
85  * being passed in. If the io engine is a synchronous one, io may complete
86  * before ->queue() returns. Required.
87  *
88  * The io engine must transfer in the direction noted by io_u->ddir
89  * to the buffer pointed to by io_u->xfer_buf for as many bytes as
90  * io_u->xfer_buflen. Residual data count may be set in io_u->resid
91  * for a short read/write.
92  */
93 static enum fio_q_status fio_skeleton_queue(struct thread_data *td,
94                                             struct io_u *io_u)
95 {
96         /*
97          * Double sanity check to catch errant write on a readonly setup
98          */
99         fio_ro_check(td, io_u);
100
101         /*
102          * Could return FIO_Q_QUEUED for a queued request,
103          * FIO_Q_COMPLETED for a completed request, and FIO_Q_BUSY
104          * if we could queue no more at this point (you'd have to
105          * define ->commit() to handle that.
106          */
107         return FIO_Q_COMPLETED;
108 }
109
110 /*
111  * The ->prep() function is called for each io_u prior to being submitted
112  * with ->queue(). This hook allows the io engine to perform any
113  * preparatory actions on the io_u, before being submitted. Not required.
114  */
115 static int fio_skeleton_prep(struct thread_data *td, struct io_u *io_u)
116 {
117         return 0;
118 }
119
120 /*
121  * The init function is called once per thread/process, and should set up
122  * any structures that this io engine requires to keep track of io. Not
123  * required.
124  */
125 static int fio_skeleton_init(struct thread_data *td)
126 {
127         return 0;
128 }
129
130 /*
131  * This is paired with the ->init() function and is called when a thread is
132  * done doing io. Should tear down anything setup by the ->init() function.
133  * Not required.
134  */
135 static void fio_skeleton_cleanup(struct thread_data *td)
136 {
137 }
138
139 /*
140  * Hook for opening the given file. Unless the engine has special
141  * needs, it usually just provides generic_open_file() as the handler.
142  */
143 static int fio_skeleton_open(struct thread_data *td, struct fio_file *f)
144 {
145         return generic_open_file(td, f);
146 }
147
148 /*
149  * Hook for closing a file. See fio_skeleton_open().
150  */
151 static int fio_skeleton_close(struct thread_data *td, struct fio_file *f)
152 {
153         return generic_close_file(td, f);
154 }
155
156 /*
157  * Note that the structure is exported, so that fio can get it via
158  * dlsym(..., "ioengine"); for (and only for) external engines.
159  */
160 struct ioengine_ops ioengine = {
161         .name           = "engine_name",
162         .version        = FIO_IOOPS_VERSION,
163         .init           = fio_skeleton_init,
164         .prep           = fio_skeleton_prep,
165         .queue          = fio_skeleton_queue,
166         .cancel         = fio_skeleton_cancel,
167         .getevents      = fio_skeleton_getevents,
168         .event          = fio_skeleton_event,
169         .cleanup        = fio_skeleton_cleanup,
170         .open_file      = fio_skeleton_open,
171         .close_file     = fio_skeleton_close,
172         .options        = options,
173         .option_struct_size     = sizeof(struct fio_skeleton_options),
174 };