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 : 15307 : spdk_pipe_create(void *buf, uint32_t sz)
20 : : {
21 : 7 : struct spdk_pipe *pipe;
22 : :
23 : 15307 : pipe = calloc(1, sizeof(*pipe));
24 [ + + ]: 15307 : if (pipe == NULL) {
25 : 0 : return NULL;
26 : : }
27 : :
28 [ + - + - ]: 15307 : pipe->buf = buf;
29 [ + - + - ]: 15307 : pipe->sz = sz;
30 : :
31 : 15307 : return pipe;
32 : 4267 : }
33 : :
34 : : void
35 : 15878 : spdk_pipe_destroy(struct spdk_pipe *pipe)
36 : : {
37 : 15878 : free(pipe);
38 : 15878 : }
39 : :
40 : : int
41 : 216849407 : 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 [ + - + - ]: 216849407 : read = pipe->read;
48 [ + - + - ]: 216849407 : write = pipe->write;
49 : :
50 [ + + + + : 216849407 : if (pipe->full || requested_sz == 0) {
+ + + + +
+ ]
51 [ + - + - : 124 : iovs[0].iov_base = NULL;
+ - ]
52 [ + - + - : 12 : iovs[0].iov_len = 0;
+ - ]
53 : 12 : return 0;
54 : : }
55 : :
56 [ + + ]: 216849395 : if (read <= write) {
57 [ + - + - : 216849377 : sz = spdk_min(requested_sz, pipe->sz - write);
+ + + - +
- ]
58 : :
59 [ + - + - : 216849377 : iovs[0].iov_base = pipe->buf + write;
+ - + - +
- + - ]
60 [ + - + - : 216849377 : iovs[0].iov_len = sz;
+ - ]
61 : :
62 : 216849377 : requested_sz -= sz;
63 : :
64 [ + + ]: 216849377 : if (requested_sz > 0) {
65 [ - + ]: 214415337 : sz = spdk_min(requested_sz, read);
66 : :
67 [ + + - + : 214415337 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf;
- + + - +
- + - ]
68 [ + - + - : 214415337 : iovs[1].iov_len = sz;
+ - ]
69 : 272351 : } else {
70 [ + - + - : 2434040 : iovs[1].iov_base = NULL;
+ - ]
71 [ + - + - : 2434040 : iovs[1].iov_len = 0;
+ - ]
72 : : }
73 : 311439 : } 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 [ + - + - : 216849395 : return iovs[0].iov_len + iovs[1].iov_len;
+ - + - +
- + - ]
83 : 311444 : }
84 : :
85 : : int
86 : 23823792 : 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 [ + - + - ]: 23823792 : read = pipe->read;
93 [ + - + - ]: 23823792 : write = pipe->write;
94 : :
95 [ + + + + : 23823792 : if (requested_sz > pipe->sz || pipe->full) {
+ + + - +
- + - -
+ ]
96 : 6 : return -EINVAL;
97 : : }
98 : :
99 [ + + ]: 23823786 : if (read <= write) {
100 [ + + + - : 23823762 : if (requested_sz > (pipe->sz - write) + read) {
+ + ]
101 : 6 : return -EINVAL;
102 : : }
103 : :
104 [ + - + - : 23823756 : sz = spdk_min(requested_sz, pipe->sz - write);
+ + - + -
+ ]
105 : :
106 : 23823756 : write += sz;
107 [ + + + - : 23823756 : if (write == pipe->sz) {
+ + ]
108 : 4476862 : write = 0;
109 : 3 : }
110 : 23823756 : requested_sz -= sz;
111 : :
112 [ + + ]: 23823756 : if (requested_sz > 0) {
113 : 4463396 : write = requested_sz;
114 : 1 : }
115 : 45534 : } else {
116 [ + + ]: 24 : if (requested_sz > (read - write)) {
117 : 12 : return -EINVAL;
118 : : }
119 : :
120 : 12 : write += requested_sz;
121 : : }
122 : :
123 [ + + ]: 23823768 : if (read == write) {
124 [ + - + - ]: 3056665 : pipe->full = true;
125 : 3 : }
126 [ + - + - ]: 23823768 : pipe->write = write;
127 : :
128 : 23823768 : return 0;
129 : 45540 : }
130 : :
131 : : uint32_t
132 : 354353078 : spdk_pipe_reader_bytes_available(struct spdk_pipe *pipe)
133 : : {
134 : 3 : uint32_t read;
135 : 3 : uint32_t write;
136 : :
137 [ + - + - ]: 354353078 : read = pipe->read;
138 [ + - + - ]: 354353078 : write = pipe->write;
139 : :
140 [ + + + + : 354353078 : if (read == write && !pipe->full) {
+ - + - -
+ ]
141 : 213890843 : return 0;
142 [ + + ]: 140462235 : } else if (read < write) {
143 : 91705813 : return write - read;
144 : : } else {
145 [ - + - + ]: 48756422 : return (pipe->sz - read) + write;
146 : : }
147 : 117196 : }
148 : :
149 : : int
150 : 146860497 : 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 [ + - + - ]: 146860497 : read = pipe->read;
157 [ + - + - ]: 146860497 : write = pipe->write;
158 : :
159 [ + + + + : 146860497 : if ((read == write && !pipe->full) || requested_sz == 0) {
+ + + + +
+ ]
160 [ + - + - : 11065273 : iovs[0].iov_base = NULL;
+ - ]
161 [ + - + - : 11065273 : iovs[0].iov_len = 0;
+ - ]
162 [ + - + - : 11065273 : iovs[1].iov_base = NULL;
+ - ]
163 [ + - + - : 11065273 : iovs[1].iov_len = 0;
+ - ]
164 [ + + ]: 135817967 : } else if (read < write) {
165 [ + + ]: 93668205 : sz = spdk_min(requested_sz, write - read);
166 : :
167 [ + - + - : 93668205 : iovs[0].iov_base = pipe->buf + read;
+ - + - +
- + - ]
168 [ + - + - : 93668205 : iovs[0].iov_len = sz;
+ - ]
169 [ + - + - : 93668205 : iovs[1].iov_base = NULL;
+ - ]
170 [ + - + - : 93668205 : iovs[1].iov_len = 0;
+ - ]
171 : 117211 : } else {
172 [ + - + - : 42127019 : sz = spdk_min(requested_sz, pipe->sz - read);
+ + + - +
- ]
173 : :
174 [ + - + - : 42127019 : iovs[0].iov_base = pipe->buf + read;
+ - + - +
- + - ]
175 [ + - + - : 42127019 : iovs[0].iov_len = sz;
+ - ]
176 : :
177 : 42127019 : requested_sz -= sz;
178 : :
179 [ + + ]: 42127019 : if (requested_sz > 0) {
180 [ - + ]: 42117685 : sz = spdk_min(requested_sz, write);
181 [ + + - + : 42117685 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf;
- + + - +
- + - ]
182 [ + - + - : 42117685 : iovs[1].iov_len = sz;
+ - ]
183 : 4 : } else {
184 [ + - + - : 9334 : iovs[1].iov_base = NULL;
+ - ]
185 [ + - + - : 9334 : iovs[1].iov_len = 0;
+ - ]
186 : : }
187 : : }
188 : :
189 [ + - + - : 146860497 : return iovs[0].iov_len + iovs[1].iov_len;
+ - + - +
- + - ]
190 : 12 : }
191 : :
192 : : int
193 : 135795206 : 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 [ + - + - ]: 135795206 : read = pipe->read;
200 [ + - + - ]: 135795206 : write = pipe->write;
201 : :
202 [ + + ]: 135795206 : if (requested_sz == 0) {
203 : 0 : return 0;
204 : : }
205 : :
206 [ + + ]: 135795206 : if (read < write) {
207 [ + + ]: 93668205 : if (requested_sz > (write - read)) {
208 : 12 : return -EINVAL;
209 : : }
210 : :
211 : 93668193 : read += requested_sz;
212 : 117199 : } else {
213 [ + - + - : 42127001 : sz = spdk_min(requested_sz, pipe->sz - read);
+ + + - +
- ]
214 : :
215 : 42127001 : read += sz;
216 [ + + + - : 42127001 : if (read == pipe->sz) {
+ + ]
217 : 4476853 : read = 0;
218 : 2 : }
219 : 42127001 : requested_sz -= sz;
220 : :
221 [ + + ]: 42127001 : if (requested_sz > 0) {
222 [ - + ]: 4388238 : if (requested_sz > write) {
223 : 0 : return -EINVAL;
224 : : }
225 : :
226 : 4388238 : read = requested_sz;
227 : 2 : }
228 : : }
229 : :
230 : : /* We know we advanced at least one byte, so the pipe isn't full. */
231 [ + - + - ]: 135795194 : pipe->full = false;
232 [ + - + - ]: 135795194 : pipe->read = read;
233 : :
234 : 135795194 : return 0;
235 : 117204 : }
|