Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2016, Citrix Systems, Inc.
3 : : *
4 : : * All rights reserved.
5 : : *
6 : : * Redistribution and use in source and binary forms, with or without
7 : : * modification, are permitted provided that the following conditions are met:
8 : : *
9 : : * 1. Redistributions of source code must retain the above copyright
10 : : * notice, this list of conditions and the following disclaimer.
11 : : * 2. Redistributions in binary form must reproduce the above copyright
12 : : * notice, this list of conditions and the following disclaimer in the
13 : : * documentation and/or other materials provided with the distribution.
14 : : * 3. Neither the name of the copyright holder nor the names of its
15 : : * contributors may be used to endorse or promote products derived from
16 : : * this software without specific prior written permission.
17 : : *
18 : : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 : : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 : : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 : : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22 : : * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 : : * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 : : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 : : * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 : : * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 : : * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 : : * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 : : */
30 : :
31 : : #ifndef __IO_OPTIMIZE_H__
32 : : #define __IO_OPTIMIZE_H__
33 : :
34 : : #include "debug.h"
35 : : #include <libaio.h>
36 : : #include <sys/uio.h>
37 : :
38 : : struct opio;
39 : :
40 : : struct opio_list {
41 : : struct opio *head;
42 : : struct opio *tail;
43 : : };
44 : :
45 : : #define UIO_FASTIOV 8
46 : :
47 : : struct opio {
48 : : struct iovec iov[UIO_FASTIOV];
49 : : struct iocb orig_iocb;
50 : : struct iocb *iocb;
51 : : struct io_event event;
52 : : struct opio *head;
53 : : struct opio *next;
54 : : struct opio_list list;
55 : : };
56 : :
57 : : struct opioctx {
58 : : int num_opios;
59 : : int free_opio_cnt;
60 : : struct opio *opios;
61 : : struct opio **free_opios;
62 : : struct iocb **iocb_queue;
63 : : struct io_event *event_queue;
64 : : };
65 : :
66 : : int opio_init(struct opioctx *ctx, int num_iocbs);
67 : : void opio_free(struct opioctx *ctx);
68 : : int io_merge(struct opioctx *ctx, struct iocb **queue, int num);
69 : : int io_split(struct opioctx *ctx, struct io_event *events, int num);
70 : : int io_expand_iocbs(struct opioctx *ctx, struct iocb **queue, int idx, int num);
71 : :
72 : : static inline size_t
73 : 0 : iocb_nbytes(const struct iocb* io)
74 : : {
75 [ # # # # : 0 : switch(io->aio_lio_opcode) {
# ]
76 : : case IO_CMD_PREAD: /* fall-through */
77 : : case IO_CMD_PWRITE:
78 : 0 : return io->u.c.nbytes;
79 : :
80 : : case IO_CMD_FSYNC:
81 : : case IO_CMD_FDSYNC: /* fall-through */
82 : : case IO_CMD_NOOP: /* fall-through */
83 : : return 0;
84 : :
85 : : case IO_CMD_POLL:
86 : : /* result is not an amount */
87 : 0 : ASSERT(0);
88 : :
89 : : case IO_CMD_PREADV: /* fall-through */
90 : : case IO_CMD_PWRITEV:
91 : : {
92 : : size_t sum = 0, i;
93 [ # # ]: 0 : for(i=0; i<io->u.v.nr; i++) {
94 [ # # ]: 0 : ASSERT(io->u.v.vec[i].iov_len > 0);
95 : 0 : sum += io->u.v.vec[i].iov_len;
96 : : }
97 : : return sum;
98 : : }
99 : : default:
100 : 0 : ASSERT(0);
101 : : }
102 : : }
103 : :
104 : : static inline long long
105 : 0 : iocb_offset(const struct iocb* io)
106 : : {
107 [ # # # ]: 0 : switch(io->aio_lio_opcode) {
108 : : case IO_CMD_PREAD: /* fall-through */
109 : : case IO_CMD_PWRITE:
110 : 0 : return io->u.c.offset;
111 : :
112 : : case IO_CMD_PREADV: /* fall-through */
113 : : case IO_CMD_PWRITEV:
114 : 0 : return io->u.v.offset;
115 : :
116 : : default:
117 : : /* no offset in other commands */
118 : 0 : ASSERT(0);
119 : : }
120 : : }
121 : :
122 : 0 : static inline void* iocb_buf(const struct iocb *io)
123 : : {
124 [ # # ]: 0 : ASSERT(io->aio_lio_opcode == IO_CMD_PREAD
125 : : || io->aio_lio_opcode == IO_CMD_PWRITE);
126 : 0 : return io->u.c.buf;
127 : : }
128 : :
129 : 0 : static inline const char* iocb_opcode(const struct iocb* io)
130 : : {
131 [ # # # # : 0 : switch(io->aio_lio_opcode) {
# # # #
# ]
132 : : case IO_CMD_PREAD:
133 : : return "read";
134 : : case IO_CMD_PWRITE:
135 : 0 : return "write";
136 : : case IO_CMD_FSYNC:
137 : 0 : return "fsync";
138 : : case IO_CMD_FDSYNC:
139 : 0 : return "fdsync";
140 : : case IO_CMD_POLL:
141 : 0 : return "poll";
142 : : case IO_CMD_NOOP:
143 : 0 : return "noop";
144 : : case IO_CMD_PREADV:
145 : 0 : return "preadv";
146 : : case IO_CMD_PWRITEV:
147 : 0 : return "pwritev";
148 : : default:
149 : 0 : ASSERT(0);
150 : : }
151 : : }
152 : :
153 : : static inline int iocb_vectorized(io_iocb_cmd_t op)
154 : : {
155 [ # # # ]: 0 : switch (op) {
[ # # # ]
[ # # # ]
[ # # # ]
[ # # # ]
[ # # # ]
[ # # # ]
[ # # # ]
156 : : case IO_CMD_PREAD:
157 : : return IO_CMD_PREADV;
158 : : case IO_CMD_PWRITE:
159 : : return IO_CMD_PWRITEV;
160 : : default:
161 : 0 : return op;
162 : : }
163 : : }
164 : :
165 : : #endif
|