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 : 13895 : spdk_pipe_create(void *buf, uint32_t sz)
20 : : {
21 : 7 : struct spdk_pipe *pipe;
22 : :
23 : 13895 : pipe = calloc(1, sizeof(*pipe));
24 [ + + ]: 13895 : if (pipe == NULL) {
25 : 0 : return NULL;
26 : : }
27 : :
28 [ + - + - ]: 13895 : pipe->buf = buf;
29 [ + - + - ]: 13895 : pipe->sz = sz;
30 : :
31 : 13895 : return pipe;
32 : 4043 : }
33 : :
34 : : void
35 : 14466 : spdk_pipe_destroy(struct spdk_pipe *pipe)
36 : : {
37 : 14466 : free(pipe);
38 : 14466 : }
39 : :
40 : : int
41 : 215381528 : spdk_pipe_writer_get_buffer(struct spdk_pipe *pipe, uint32_t requested_sz, struct iovec *iovs)
42 : : {
43 : 13 : uint32_t sz;
44 : 13 : uint32_t read;
45 : 13 : uint32_t write;
46 : :
47 [ + - + - ]: 215381528 : read = pipe->read;
48 [ + - + - ]: 215381528 : write = pipe->write;
49 : :
50 [ + + + + : 215381528 : if (pipe->full || requested_sz == 0) {
+ + + + +
+ ]
51 [ + - + - : 20 : iovs[0].iov_base = NULL;
+ - ]
52 [ + - + - : 12 : iovs[0].iov_len = 0;
+ - ]
53 : 12 : return 0;
54 : : }
55 : :
56 [ + + ]: 215381516 : if (read <= write) {
57 [ + - + - : 215381498 : sz = spdk_min(requested_sz, pipe->sz - write);
+ + + - +
- ]
58 : :
59 [ + - + - : 215381498 : iovs[0].iov_base = pipe->buf + write;
+ - + - +
- + - ]
60 [ + - + - : 215381488 : iovs[0].iov_len = sz;
+ - ]
61 : :
62 : 215381488 : requested_sz -= sz;
63 : :
64 [ + + ]: 215381488 : if (requested_sz > 0) {
65 [ - + ]: 212948080 : sz = spdk_min(requested_sz, read);
66 : :
67 [ + + - + : 212948080 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf;
- + + - +
- + - ]
68 [ + - + - : 212948080 : iovs[1].iov_len = sz;
+ - ]
69 : 260451 : } else {
70 [ + - + - : 2433408 : iovs[1].iov_base = NULL;
+ - ]
71 [ + - + - : 2433408 : iovs[1].iov_len = 0;
+ - ]
72 : : }
73 : 298678 : } else {
74 [ + + ]: 18 : sz = spdk_min(requested_sz, read - write);
75 : :
76 [ + - + - : 18 : iovs[0].iov_base = pipe->buf + write;
+ - + - +
- + - ]
77 [ + - + - : 18 : iovs[0].iov_len = sz;
+ - ]
78 [ + - + - : 18 : iovs[1].iov_base = NULL;
+ - ]
79 [ + - + - : 18 : iovs[1].iov_len = 0;
+ - ]
80 : : }
81 : :
82 [ + - + - : 215381506 : return iovs[0].iov_len + iovs[1].iov_len;
+ - + - +
- + - ]
83 : 298683 : }
84 : :
85 : : int
86 : 23274324 : spdk_pipe_writer_advance(struct spdk_pipe *pipe, uint32_t requested_sz)
87 : : {
88 : 11 : uint32_t sz;
89 : 11 : uint32_t read;
90 : 11 : uint32_t write;
91 : :
92 [ + - + - ]: 23274324 : read = pipe->read;
93 [ + - + - ]: 23274324 : write = pipe->write;
94 : :
95 [ + + + + : 23274324 : if (requested_sz > pipe->sz || pipe->full) {
+ + + - +
- + - -
+ ]
96 : 6 : return -EINVAL;
97 : : }
98 : :
99 [ + + ]: 23274318 : if (read <= write) {
100 [ + + + - : 23274294 : if (requested_sz > (pipe->sz - write) + read) {
+ + ]
101 : 6 : return -EINVAL;
102 : : }
103 : :
104 [ + - + - : 23274288 : sz = spdk_min(requested_sz, pipe->sz - write);
+ + - + -
+ ]
105 : :
106 : 23274288 : write += sz;
107 [ + + + - : 23274288 : if (write == pipe->sz) {
+ + ]
108 : 4244898 : write = 0;
109 : 3 : }
110 : 23274288 : requested_sz -= sz;
111 : :
112 [ + + ]: 23274288 : if (requested_sz > 0) {
113 : 4235609 : write = requested_sz;
114 : 1 : }
115 : 43163 : } else {
116 [ + + ]: 24 : if (requested_sz > (read - write)) {
117 : 12 : return -EINVAL;
118 : : }
119 : :
120 : 12 : write += requested_sz;
121 : : }
122 : :
123 [ + + ]: 23274300 : if (read == write) {
124 [ + - + - ]: 2924598 : pipe->full = true;
125 : 3 : }
126 [ + - + - ]: 23274300 : pipe->write = write;
127 : :
128 : 23274300 : return 0;
129 : 43169 : }
130 : :
131 : : uint32_t
132 : 340236212 : spdk_pipe_reader_bytes_available(struct spdk_pipe *pipe)
133 : : {
134 : 3 : uint32_t read;
135 : 3 : uint32_t write;
136 : :
137 [ + - + - ]: 340236212 : read = pipe->read;
138 [ + - + - ]: 340236212 : write = pipe->write;
139 : :
140 [ + + + + : 340236212 : if (read == write && !pipe->full) {
+ - + - -
+ ]
141 : 213383036 : return 0;
142 [ + + ]: 126853176 : } else if (read < write) {
143 : 80732421 : return write - read;
144 : : } else {
145 [ - + - + ]: 46120755 : return (pipe->sz - read) + write;
146 : : }
147 : 110830 : }
148 : :
149 : : int
150 : 132656971 : spdk_pipe_reader_get_buffer(struct spdk_pipe *pipe, uint32_t requested_sz, struct iovec *iovs)
151 : : {
152 : 12 : uint32_t sz;
153 : 12 : uint32_t read;
154 : 12 : uint32_t write;
155 : :
156 [ + - + - ]: 132656971 : read = pipe->read;
157 [ + - + - ]: 132656971 : write = pipe->write;
158 : :
159 [ + + + + : 132656971 : if ((read == write && !pipe->full) || requested_sz == 0) {
+ + + + +
+ ]
160 [ + - + - : 10929357 : iovs[0].iov_base = NULL;
+ - ]
161 [ + - + - : 10929357 : iovs[0].iov_len = 0;
+ - ]
162 [ + - + - : 10929357 : iovs[1].iov_base = NULL;
+ - ]
163 [ + - + - : 10929357 : iovs[1].iov_len = 0;
+ - ]
164 [ + + ]: 121749163 : } else if (read < write) {
165 [ + + ]: 82702795 : sz = spdk_min(requested_sz, write - read);
166 : :
167 [ + - + - : 82702795 : iovs[0].iov_base = pipe->buf + read;
+ - + - +
- + - ]
168 [ + - + - : 82702795 : iovs[0].iov_len = sz;
+ - ]
169 [ + - + - : 82702795 : iovs[1].iov_base = NULL;
+ - ]
170 [ + - + - : 82702795 : iovs[1].iov_len = 0;
+ - ]
171 : 110855 : } else {
172 [ + - + - : 39024819 : sz = spdk_min(requested_sz, pipe->sz - read);
+ + + - +
- ]
173 : :
174 [ + - + - : 39024819 : iovs[0].iov_base = pipe->buf + read;
+ - + - +
- + - ]
175 [ + - + - : 39024819 : iovs[0].iov_len = sz;
+ - ]
176 : :
177 : 39024819 : requested_sz -= sz;
178 : :
179 [ + + ]: 39024819 : if (requested_sz > 0) {
180 [ - + ]: 39018572 : sz = spdk_min(requested_sz, write);
181 [ + + - + : 39018572 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf;
- + + - +
- + - ]
182 [ + - + - : 39018572 : iovs[1].iov_len = sz;
+ - ]
183 : 4 : } else {
184 [ + - + - : 6247 : iovs[1].iov_base = NULL;
+ - ]
185 [ + - + - : 6247 : iovs[1].iov_len = 0;
+ - ]
186 : : }
187 : : }
188 : :
189 [ + - + - : 132656971 : return iovs[0].iov_len + iovs[1].iov_len;
+ - + - +
- + - ]
190 : 12 : }
191 : :
192 : : int
193 : 121727586 : spdk_pipe_reader_advance(struct spdk_pipe *pipe, uint32_t requested_sz)
194 : : {
195 : 9 : uint32_t sz;
196 : 9 : uint32_t read;
197 : 9 : uint32_t write;
198 : :
199 [ + - + - ]: 121727586 : read = pipe->read;
200 [ + - + - ]: 121727586 : write = pipe->write;
201 : :
202 [ + + ]: 121727586 : if (requested_sz == 0) {
203 : 0 : return 0;
204 : : }
205 : :
206 [ + + ]: 121727586 : if (read < write) {
207 [ + + ]: 82702785 : if (requested_sz > (write - read)) {
208 : 12 : return -EINVAL;
209 : : }
210 : :
211 : 82702773 : read += requested_sz;
212 : 110833 : } else {
213 [ + - + - : 39024801 : sz = spdk_min(requested_sz, pipe->sz - read);
+ + + - +
- ]
214 : :
215 : 39024801 : read += sz;
216 [ + + + - : 39024801 : if (read == pipe->sz) {
+ + ]
217 : 4244886 : read = 0;
218 : 2 : }
219 : 39024801 : requested_sz -= sz;
220 : :
221 [ + + ]: 39024801 : if (requested_sz > 0) {
222 [ - + ]: 4183184 : if (requested_sz > write) {
223 : 0 : return -EINVAL;
224 : : }
225 : :
226 : 4183184 : read = requested_sz;
227 : 2 : }
228 : : }
229 : :
230 : : /* We know we advanced at least one byte, so the pipe isn't full. */
231 [ + - + - ]: 121727574 : pipe->full = false;
232 [ + - + - ]: 121727574 : pipe->read = read;
233 : :
234 : 121727574 : return 0;
235 : 110838 : }
|