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 : 10821 : spdk_pipe_create(void *buf, uint32_t sz) 20 : : { 21 : : struct spdk_pipe *pipe; 22 : : 23 : 10821 : pipe = calloc(1, sizeof(*pipe)); 24 [ - + ]: 10821 : if (pipe == NULL) { 25 : 0 : return NULL; 26 : : } 27 : : 28 : 10821 : pipe->buf = buf; 29 : 10821 : pipe->sz = sz; 30 : : 31 : 10821 : return pipe; 32 : : } 33 : : 34 : : void 35 : 11330 : spdk_pipe_destroy(struct spdk_pipe *pipe) 36 : : { 37 : 11330 : free(pipe); 38 : 11330 : } 39 : : 40 : : int 41 : 207057860 : 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 : 207057860 : read = pipe->read; 48 : 207057860 : write = pipe->write; 49 : : 50 [ + + + + : 207057860 : if (pipe->full || requested_sz == 0) { + + ] 51 : 8 : iovs[0].iov_base = NULL; 52 : 8 : iovs[0].iov_len = 0; 53 : 8 : return 0; 54 : : } 55 : : 56 [ + + ]: 207057852 : if (read <= write) { 57 : 207057840 : sz = spdk_min(requested_sz, pipe->sz - write); 58 : : 59 : 207057840 : iovs[0].iov_base = pipe->buf + write; 60 : 207057840 : iovs[0].iov_len = sz; 61 : : 62 : 207057840 : requested_sz -= sz; 63 : : 64 [ + + ]: 207057840 : if (requested_sz > 0) { 65 : 204811083 : sz = spdk_min(requested_sz, read); 66 : : 67 [ + + ]: 204811083 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf; 68 : 204811083 : iovs[1].iov_len = sz; 69 : : } else { 70 : 2246757 : iovs[1].iov_base = NULL; 71 : 2246757 : iovs[1].iov_len = 0; 72 : : } 73 : : } else { 74 : 12 : sz = spdk_min(requested_sz, read - write); 75 : : 76 : 12 : iovs[0].iov_base = pipe->buf + write; 77 : 12 : iovs[0].iov_len = sz; 78 : 12 : iovs[1].iov_base = NULL; 79 : 12 : iovs[1].iov_len = 0; 80 : : } 81 : : 82 : 207057852 : return iovs[0].iov_len + iovs[1].iov_len; 83 : : } 84 : : 85 : : int 86 : 26299045 : 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 : 26299045 : read = pipe->read; 93 : 26299045 : write = pipe->write; 94 : : 95 [ + + - + : 26299045 : if (requested_sz > pipe->sz || pipe->full) { - + ] 96 : 4 : return -EINVAL; 97 : : } 98 : : 99 [ + + ]: 26299041 : if (read <= write) { 100 [ + + ]: 26299025 : if (requested_sz > (pipe->sz - write) + read) { 101 : 4 : return -EINVAL; 102 : : } 103 : : 104 : 26299021 : sz = spdk_min(requested_sz, pipe->sz - write); 105 : : 106 : 26299021 : write += sz; 107 [ + + ]: 26299021 : if (write == pipe->sz) { 108 : 4375221 : write = 0; 109 : : } 110 : 26299021 : requested_sz -= sz; 111 : : 112 [ + + ]: 26299021 : if (requested_sz > 0) { 113 : 4359776 : write = requested_sz; 114 : : } 115 : : } else { 116 [ + + ]: 16 : if (requested_sz > (read - write)) { 117 : 8 : return -EINVAL; 118 : : } 119 : : 120 : 8 : write += requested_sz; 121 : : } 122 : : 123 [ + + ]: 26299029 : if (read == write) { 124 : 2888973 : pipe->full = true; 125 : : } 126 : 26299029 : pipe->write = write; 127 : : 128 : 26299029 : return 0; 129 : : } 130 : : 131 : : uint32_t 132 : 336775398 : spdk_pipe_reader_bytes_available(struct spdk_pipe *pipe) 133 : : { 134 : : uint32_t read; 135 : : uint32_t write; 136 : : 137 : 336775398 : read = pipe->read; 138 : 336775398 : write = pipe->write; 139 : : 140 [ + + - + : 336775398 : if (read == write && !pipe->full) { + - ] 141 : 209762661 : return 0; 142 [ + + ]: 127012737 : } else if (read < write) { 143 : 81432798 : return write - read; 144 : : } else { 145 : 45579939 : return (pipe->sz - read) + write; 146 : : } 147 : : } 148 : : 149 : : int 150 : 139379657 : 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 : 139379657 : read = pipe->read; 157 : 139379657 : write = pipe->write; 158 : : 159 [ + + - + : 139379657 : if ((read == write && !pipe->full) || requested_sz == 0) { + + + + ] 160 : 13823438 : iovs[0].iov_base = NULL; 161 : 13823438 : iovs[0].iov_len = 0; 162 : 13823438 : iovs[1].iov_base = NULL; 163 : 13823438 : iovs[1].iov_len = 0; 164 [ + + ]: 125556219 : } else if (read < write) { 165 : 86741252 : sz = spdk_min(requested_sz, write - read); 166 : : 167 : 86741252 : iovs[0].iov_base = pipe->buf + read; 168 : 86741252 : iovs[0].iov_len = sz; 169 : 86741252 : iovs[1].iov_base = NULL; 170 : 86741252 : iovs[1].iov_len = 0; 171 : : } else { 172 : 38814967 : sz = spdk_min(requested_sz, pipe->sz - read); 173 : : 174 : 38814967 : iovs[0].iov_base = pipe->buf + read; 175 : 38814967 : iovs[0].iov_len = sz; 176 : : 177 : 38814967 : requested_sz -= sz; 178 : : 179 [ + + ]: 38814967 : if (requested_sz > 0) { 180 : 38803235 : sz = spdk_min(requested_sz, write); 181 [ + + ]: 38803235 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf; 182 : 38803235 : iovs[1].iov_len = sz; 183 : : } else { 184 : 11732 : iovs[1].iov_base = NULL; 185 : 11732 : iovs[1].iov_len = 0; 186 : : } 187 : : } 188 : : 189 : 139379657 : return iovs[0].iov_len + iovs[1].iov_len; 190 : : } 191 : : 192 : : int 193 : 125556215 : 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 : 125556215 : read = pipe->read; 200 : 125556215 : write = pipe->write; 201 : : 202 [ - + ]: 125556215 : if (requested_sz == 0) { 203 : 0 : return 0; 204 : : } 205 : : 206 [ + + ]: 125556215 : if (read < write) { 207 [ + + ]: 86741260 : if (requested_sz > (write - read)) { 208 : 8 : return -EINVAL; 209 : : } 210 : : 211 : 86741252 : read += requested_sz; 212 : : } else { 213 : 38814955 : sz = spdk_min(requested_sz, pipe->sz - read); 214 : : 215 : 38814955 : read += sz; 216 [ + + ]: 38814955 : if (read == pipe->sz) { 217 : 4375210 : read = 0; 218 : : } 219 : 38814955 : requested_sz -= sz; 220 : : 221 [ + + ]: 38814955 : if (requested_sz > 0) { 222 [ - + ]: 4301374 : if (requested_sz > write) { 223 : 0 : return -EINVAL; 224 : : } 225 : : 226 : 4301374 : read = requested_sz; 227 : : } 228 : : } 229 : : 230 : : /* We know we advanced at least one byte, so the pipe isn't full. */ 231 : 125556207 : pipe->full = false; 232 : 125556207 : pipe->read = read; 233 : : 234 : 125556207 : return 0; 235 : : }