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 : 14857 : spdk_pipe_create(void *buf, uint32_t sz)
20 : : {
21 : 7 : struct spdk_pipe *pipe;
22 : :
23 : 14857 : pipe = calloc(1, sizeof(*pipe));
24 [ + + ]: 14857 : if (pipe == NULL) {
25 : 0 : return NULL;
26 : : }
27 : :
28 [ + - + - ]: 14857 : pipe->buf = buf;
29 [ + - + - ]: 14857 : pipe->sz = sz;
30 : :
31 : 14857 : return pipe;
32 : 4027 : }
33 : :
34 : : void
35 : 15428 : spdk_pipe_destroy(struct spdk_pipe *pipe)
36 : : {
37 : 15428 : free(pipe);
38 : 15428 : }
39 : :
40 : : int
41 : 211225078 : 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 [ + - + - ]: 211225078 : read = pipe->read;
48 [ + - + - ]: 211225078 : write = pipe->write;
49 : :
50 [ + + + + : 211225078 : if (pipe->full || requested_sz == 0) {
+ + + + +
+ ]
51 [ + - + - : 54 : iovs[0].iov_base = NULL;
+ - ]
52 [ + - + - : 12 : iovs[0].iov_len = 0;
+ - ]
53 : 12 : return 0;
54 : : }
55 : :
56 [ + + ]: 211225024 : if (read <= write) {
57 [ + - + - : 211225006 : sz = spdk_min(requested_sz, pipe->sz - write);
+ + + - +
- ]
58 : :
59 [ + - + - : 211225006 : iovs[0].iov_base = pipe->buf + write;
+ - + - +
- + - ]
60 [ + - + - : 211225006 : iovs[0].iov_len = sz;
+ - ]
61 : :
62 : 211225006 : requested_sz -= sz;
63 : :
64 [ + + ]: 211225006 : if (requested_sz > 0) {
65 [ - + ]: 208763211 : sz = spdk_min(requested_sz, read);
66 : :
67 [ + + - + : 208763211 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf;
- + + - +
- + - ]
68 [ + - + - : 208763211 : iovs[1].iov_len = sz;
+ - ]
69 : 249815 : } else {
70 [ + - + - : 2461795 : iovs[1].iov_base = NULL;
+ - ]
71 [ + - + - : 2461795 : iovs[1].iov_len = 0;
+ - ]
72 : : }
73 : 286950 : } 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 [ + - + - : 211225024 : return iovs[0].iov_len + iovs[1].iov_len;
+ - + - +
- + - ]
83 : 286955 : }
84 : :
85 : : int
86 : 22841653 : 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 [ + - + - ]: 22841653 : read = pipe->read;
93 [ + - + - ]: 22841653 : write = pipe->write;
94 : :
95 [ + + + + : 22841653 : if (requested_sz > pipe->sz || pipe->full) {
+ + + - +
- + - +
+ ]
96 : 10 : return -EINVAL;
97 : : }
98 : :
99 [ + + ]: 22841643 : if (read <= write) {
100 [ + + + - : 22841619 : if (requested_sz > (pipe->sz - write) + read) {
+ + ]
101 : 6 : return -EINVAL;
102 : : }
103 : :
104 [ + - + - : 22841613 : sz = spdk_min(requested_sz, pipe->sz - write);
+ + - + -
+ ]
105 : :
106 : 22841613 : write += sz;
107 [ + + + - : 22841613 : if (write == pipe->sz) {
+ + ]
108 : 4273342 : write = 0;
109 : 3 : }
110 : 22841613 : requested_sz -= sz;
111 : :
112 [ + + ]: 22841613 : if (requested_sz > 0) {
113 : 4256725 : write = requested_sz;
114 : 1 : }
115 : 43016 : } else {
116 [ + + ]: 24 : if (requested_sz > (read - write)) {
117 : 12 : return -EINVAL;
118 : : }
119 : :
120 : 12 : write += requested_sz;
121 : : }
122 : :
123 [ + + ]: 22841625 : if (read == write) {
124 [ + - + - ]: 2954690 : pipe->full = true;
125 : 3 : }
126 [ + - + - ]: 22841625 : pipe->write = write;
127 : :
128 : 22841625 : return 0;
129 : 43022 : }
130 : :
131 : : uint32_t
132 : 340627087 : spdk_pipe_reader_bytes_available(struct spdk_pipe *pipe)
133 : : {
134 : 3 : uint32_t read;
135 : 3 : uint32_t write;
136 : :
137 [ + - + - ]: 340627087 : read = pipe->read;
138 [ + - + - ]: 340627087 : write = pipe->write;
139 : :
140 [ + + + + : 340627087 : if (read == write && !pipe->full) {
+ - + - +
+ ]
141 : 212749514 : return 0;
142 [ + + ]: 127877573 : } else if (read < write) {
143 : 80856747 : return write - read;
144 : : } else {
145 [ - + - + ]: 47020826 : return (pipe->sz - read) + write;
146 : : }
147 : 109501 : }
148 : :
149 : : int
150 : 132897626 : 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 [ + - + - ]: 132897626 : read = pipe->read;
157 [ + - + - ]: 132897626 : write = pipe->write;
158 : :
159 [ + + + + : 132897626 : if ((read == write && !pipe->full) || requested_sz == 0) {
+ + + + +
+ ]
160 [ + - + - : 10551455 : iovs[0].iov_base = NULL;
+ - ]
161 [ + - + - : 10551455 : iovs[0].iov_len = 0;
+ - ]
162 [ + - + - : 10551455 : iovs[1].iov_base = NULL;
+ - ]
163 [ + - + - : 10551455 : iovs[1].iov_len = 0;
+ - ]
164 [ + + ]: 122367665 : } else if (read < write) {
165 [ + + ]: 82516236 : sz = spdk_min(requested_sz, write - read);
166 : :
167 [ + - + - : 82516236 : iovs[0].iov_base = pipe->buf + read;
+ - + - +
- + - ]
168 [ + - + - : 82516236 : iovs[0].iov_len = sz;
+ - ]
169 [ + - + - : 82516236 : iovs[1].iov_base = NULL;
+ - ]
170 [ + - + - : 82516236 : iovs[1].iov_len = 0;
+ - ]
171 : 109516 : } else {
172 [ + - + - : 39829935 : sz = spdk_min(requested_sz, pipe->sz - read);
+ + + - +
- ]
173 : :
174 [ + - + - : 39829935 : iovs[0].iov_base = pipe->buf + read;
+ - + - +
- + - ]
175 [ + - + - : 39829935 : iovs[0].iov_len = sz;
+ - ]
176 : :
177 : 39829935 : requested_sz -= sz;
178 : :
179 [ + + ]: 39829935 : if (requested_sz > 0) {
180 [ - + ]: 39819551 : sz = spdk_min(requested_sz, write);
181 [ + + - + : 39819551 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf;
- + + - +
- + - ]
182 [ + - + - : 39819551 : iovs[1].iov_len = sz;
+ - ]
183 : 4 : } else {
184 [ + - + - : 10384 : iovs[1].iov_base = NULL;
+ - ]
185 [ + - + - : 10384 : iovs[1].iov_len = 0;
+ - ]
186 : : }
187 : : }
188 : :
189 [ + - + - : 132897626 : return iovs[0].iov_len + iovs[1].iov_len;
+ - + - +
- + - ]
190 : 12 : }
191 : :
192 : : int
193 : 122346154 : 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 [ + - + - ]: 122346154 : read = pipe->read;
200 [ + - + - ]: 122346154 : write = pipe->write;
201 : :
202 [ + + ]: 122346154 : if (requested_sz == 0) {
203 : 0 : return 0;
204 : : }
205 : :
206 [ + + ]: 122346154 : if (read < write) {
207 [ + + ]: 82516237 : if (requested_sz > (write - read)) {
208 : 12 : return -EINVAL;
209 : : }
210 : :
211 : 82516225 : read += requested_sz;
212 : 109505 : } else {
213 [ + - + - : 39829917 : sz = spdk_min(requested_sz, pipe->sz - read);
+ + + - +
- ]
214 : :
215 : 39829917 : read += sz;
216 [ + + + - : 39829917 : if (read == pipe->sz) {
+ + ]
217 : 4273332 : read = 0;
218 : 2 : }
219 : 39829917 : requested_sz -= sz;
220 : :
221 [ + + ]: 39829917 : if (requested_sz > 0) {
222 [ - + ]: 4190176 : if (requested_sz > write) {
223 : 0 : return -EINVAL;
224 : : }
225 : :
226 : 4190176 : read = requested_sz;
227 : 2 : }
228 : : }
229 : :
230 : : /* We know we advanced at least one byte, so the pipe isn't full. */
231 [ + - + - ]: 122346142 : pipe->full = false;
232 [ + - + - ]: 122346142 : pipe->read = read;
233 : :
234 : 122346142 : return 0;
235 : 109510 : }
|