Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2019 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/pipe.h"
7 : : #include "spdk/util.h"
8 : :
9 : : struct spdk_pipe {
10 : : uint8_t *buf;
11 : : uint32_t sz;
12 : :
13 : : uint32_t write;
14 : : uint32_t read;
15 : : bool full;
16 : : };
17 : :
18 : : struct spdk_pipe *
19 : 13766 : spdk_pipe_create(void *buf, uint32_t sz)
20 : : {
21 : : struct spdk_pipe *pipe;
22 : :
23 : 13766 : pipe = calloc(1, sizeof(*pipe));
24 [ + + ]: 13766 : if (pipe == NULL) {
25 : 0 : return NULL;
26 : : }
27 : :
28 [ + - + - ]: 13766 : pipe->buf = buf;
29 [ + - + - ]: 13766 : pipe->sz = sz;
30 : :
31 : 13766 : return pipe;
32 : 3956 : }
33 : :
34 : : void
35 : 14278 : spdk_pipe_destroy(struct spdk_pipe *pipe)
36 : : {
37 : 14278 : free(pipe);
38 : 14278 : }
39 : :
40 : : int
41 : 219895183 : spdk_pipe_writer_get_buffer(struct spdk_pipe *pipe, uint32_t requested_sz, struct iovec *iovs)
42 : : {
43 : : uint32_t sz;
44 : : uint32_t read;
45 : : uint32_t write;
46 : :
47 [ + - + - ]: 219895183 : read = pipe->read;
48 [ + - + - ]: 219895183 : write = pipe->write;
49 : :
50 [ + + + + : 219895183 : if (pipe->full || requested_sz == 0) {
+ + + + +
+ ]
51 [ # # # # : 118 : iovs[0].iov_base = NULL;
# # ]
52 [ # # # # : 6 : iovs[0].iov_len = 0;
# # ]
53 : 6 : return 0;
54 : : }
55 : :
56 [ + + ]: 219895177 : if (read <= write) {
57 [ + - + - : 219895168 : sz = spdk_min(requested_sz, pipe->sz - write);
+ + + - +
- ]
58 : :
59 [ + - + - : 219895168 : iovs[0].iov_base = pipe->buf + write;
+ - + - +
- + - ]
60 [ + - + - : 219895102 : iovs[0].iov_len = sz;
+ - ]
61 : :
62 : 219895102 : requested_sz -= sz;
63 : :
64 [ + + ]: 219895102 : if (requested_sz > 0) {
65 [ - + ]: 217359137 : sz = spdk_min(requested_sz, read);
66 : :
67 [ + + - + : 217359137 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf;
- + + - +
- + - ]
68 [ + - + - : 217359137 : iovs[1].iov_len = sz;
+ - ]
69 : 263682 : } else {
70 [ + - + - : 2535965 : iovs[1].iov_base = NULL;
+ - ]
71 [ + - + - : 2535965 : iovs[1].iov_len = 0;
+ - ]
72 : : }
73 : 303605 : } else {
74 [ # # ]: 9 : sz = spdk_min(requested_sz, read - write);
75 : :
76 [ # # # # : 9 : iovs[0].iov_base = pipe->buf + write;
# # # # #
# # # ]
77 [ # # # # : 9 : iovs[0].iov_len = sz;
# # ]
78 [ # # # # : 9 : iovs[1].iov_base = NULL;
# # ]
79 [ # # # # : 9 : iovs[1].iov_len = 0;
# # ]
80 : : }
81 : :
82 [ + - + - : 219895111 : return iovs[0].iov_len + iovs[1].iov_len;
+ - + - +
- + - ]
83 : 303605 : }
84 : :
85 : : int
86 : 23748851 : spdk_pipe_writer_advance(struct spdk_pipe *pipe, uint32_t requested_sz)
87 : : {
88 : : uint32_t sz;
89 : : uint32_t read;
90 : : uint32_t write;
91 : :
92 [ + - + - ]: 23748851 : read = pipe->read;
93 [ + - + - ]: 23748851 : write = pipe->write;
94 : :
95 [ + + + + : 23748851 : if (requested_sz > pipe->sz || pipe->full) {
+ + + - +
- + - -
+ ]
96 : 3 : return -EINVAL;
97 : : }
98 : :
99 [ + + ]: 23748848 : if (read <= write) {
100 [ + + + - : 23748836 : if (requested_sz > (pipe->sz - write) + read) {
- + ]
101 : 3 : return -EINVAL;
102 : : }
103 : :
104 [ + - + - : 23748833 : sz = spdk_min(requested_sz, pipe->sz - write);
+ - # # #
# ]
105 : :
106 : 23748833 : write += sz;
107 [ + + + - : 23748833 : if (write == pipe->sz) {
+ - ]
108 : 4247454 : write = 0;
109 : 0 : }
110 : 23748833 : requested_sz -= sz;
111 : :
112 [ + + ]: 23748833 : if (requested_sz > 0) {
113 : 4235694 : write = requested_sz;
114 : 0 : }
115 : 42300 : } else {
116 [ + + ]: 12 : if (requested_sz > (read - write)) {
117 : 6 : return -EINVAL;
118 : : }
119 : :
120 : 6 : write += requested_sz;
121 : : }
122 : :
123 [ + + ]: 23748839 : if (read == write) {
124 [ # # # # ]: 2904409 : pipe->full = true;
125 : 0 : }
126 [ + - + - ]: 23748839 : pipe->write = write;
127 : :
128 : 23748839 : return 0;
129 : 42300 : }
130 : :
131 : : uint32_t
132 : 349271400 : spdk_pipe_reader_bytes_available(struct spdk_pipe *pipe)
133 : : {
134 : : uint32_t read;
135 : : uint32_t write;
136 : :
137 [ + - + - ]: 349271400 : read = pipe->read;
138 [ + - + - ]: 349271400 : write = pipe->write;
139 : :
140 [ + + + + : 349271400 : if (read == write && !pipe->full) {
+ - + - -
+ ]
141 : 219873131 : return 0;
142 [ + + ]: 129398269 : } else if (read < write) {
143 : 82461114 : return write - read;
144 : : } else {
145 [ # # # # ]: 46937155 : return (pipe->sz - read) + write;
146 : : }
147 : 107091 : }
148 : :
149 : : int
150 : 135932984 : spdk_pipe_reader_get_buffer(struct spdk_pipe *pipe, uint32_t requested_sz, struct iovec *iovs)
151 : : {
152 : : uint32_t sz;
153 : : uint32_t read;
154 : : uint32_t write;
155 : :
156 [ + - + - ]: 135932984 : read = pipe->read;
157 [ + - + - ]: 135932984 : write = pipe->write;
158 : :
159 [ + + + + : 135932984 : if ((read == write && !pipe->full) || requested_sz == 0) {
+ + + + +
+ ]
160 [ + - + - : 11163792 : iovs[0].iov_base = NULL;
+ - ]
161 [ + - + - : 11163792 : iovs[0].iov_len = 0;
+ - ]
162 [ + - + - : 11163792 : iovs[1].iov_base = NULL;
+ - ]
163 [ + - + - : 11163792 : iovs[1].iov_len = 0;
+ - ]
164 [ + + ]: 124790319 : } else if (read < write) {
165 [ - + ]: 84995374 : sz = spdk_min(requested_sz, write - read);
166 : :
167 [ + - + - : 84995374 : iovs[0].iov_base = pipe->buf + read;
+ - + - +
- + - ]
168 [ + - + - : 84995374 : iovs[0].iov_len = sz;
+ - ]
169 [ + - + - : 84995374 : iovs[1].iov_base = NULL;
+ - ]
170 [ + - + - : 84995374 : iovs[1].iov_len = 0;
+ - ]
171 : 107095 : } else {
172 [ # # # # : 39773818 : sz = spdk_min(requested_sz, pipe->sz - read);
# # # # #
# ]
173 : :
174 [ # # # # : 39773818 : iovs[0].iov_base = pipe->buf + read;
# # # # #
# # # ]
175 [ # # # # : 39773818 : iovs[0].iov_len = sz;
# # ]
176 : :
177 : 39773818 : requested_sz -= sz;
178 : :
179 [ + + ]: 39773818 : if (requested_sz > 0) {
180 [ # # ]: 39767679 : sz = spdk_min(requested_sz, write);
181 [ + + # # : 39767679 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf;
# # # # #
# # # ]
182 [ # # # # : 39767679 : iovs[1].iov_len = sz;
# # ]
183 : 0 : } else {
184 [ # # # # : 6139 : iovs[1].iov_base = NULL;
# # ]
185 [ # # # # : 6139 : iovs[1].iov_len = 0;
# # ]
186 : : }
187 : : }
188 : :
189 [ + - + - : 135932984 : return iovs[0].iov_len + iovs[1].iov_len;
+ - + - +
- + - ]
190 : : }
191 : :
192 : : int
193 : 124769184 : spdk_pipe_reader_advance(struct spdk_pipe *pipe, uint32_t requested_sz)
194 : : {
195 : : uint32_t sz;
196 : : uint32_t read;
197 : : uint32_t write;
198 : :
199 [ + - + - ]: 124769184 : read = pipe->read;
200 [ + - + - ]: 124769184 : write = pipe->write;
201 : :
202 [ + + ]: 124769184 : if (requested_sz == 0) {
203 : 0 : return 0;
204 : : }
205 : :
206 [ + + ]: 124769184 : if (read < write) {
207 [ + + ]: 84995375 : if (requested_sz > (write - read)) {
208 : 6 : return -EINVAL;
209 : : }
210 : :
211 : 84995369 : read += requested_sz;
212 : 107090 : } else {
213 [ # # # # : 39773809 : sz = spdk_min(requested_sz, pipe->sz - read);
# # # # #
# ]
214 : :
215 : 39773809 : read += sz;
216 [ + + # # : 39773809 : if (read == pipe->sz) {
# # ]
217 : 4247443 : read = 0;
218 : 0 : }
219 : 39773809 : requested_sz -= sz;
220 : :
221 [ + + ]: 39773809 : if (requested_sz > 0) {
222 [ - + ]: 4180408 : if (requested_sz > write) {
223 : 0 : return -EINVAL;
224 : : }
225 : :
226 : 4180408 : read = requested_sz;
227 : 0 : }
228 : : }
229 : :
230 : : /* We know we advanced at least one byte, so the pipe isn't full. */
231 [ + - + - ]: 124769178 : pipe->full = false;
232 [ + - + - ]: 124769178 : pipe->read = read;
233 : :
234 : 124769178 : return 0;
235 : 107090 : }
|