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 : 8970 : spdk_pipe_create(void *buf, uint32_t sz) 20 : : { 21 : : struct spdk_pipe *pipe; 22 : : 23 : 8970 : pipe = calloc(1, sizeof(*pipe)); 24 [ - + ]: 8970 : if (pipe == NULL) { 25 : 0 : return NULL; 26 : : } 27 : : 28 : 8970 : pipe->buf = buf; 29 : 8970 : pipe->sz = sz; 30 : : 31 : 8970 : return pipe; 32 : : } 33 : : 34 : : void 35 : 9435 : spdk_pipe_destroy(struct spdk_pipe *pipe) 36 : : { 37 : 9435 : free(pipe); 38 : 9435 : } 39 : : 40 : : int 41 : 96754215 : 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 : 96754215 : read = pipe->read; 48 : 96754215 : write = pipe->write; 49 : : 50 [ + + + + : 96754215 : if (pipe->full || requested_sz == 0) { + + ] 51 : 10 : iovs[0].iov_base = NULL; 52 : 10 : iovs[0].iov_len = 0; 53 : 10 : return 0; 54 : : } 55 : : 56 [ + + ]: 96754205 : if (read <= write) { 57 : 96754190 : sz = spdk_min(requested_sz, pipe->sz - write); 58 : : 59 : 96754190 : iovs[0].iov_base = pipe->buf + write; 60 : 96754190 : iovs[0].iov_len = sz; 61 : : 62 : 96754190 : requested_sz -= sz; 63 : : 64 [ + + ]: 96754190 : if (requested_sz > 0) { 65 : 94704474 : sz = spdk_min(requested_sz, read); 66 : : 67 [ + + ]: 94704474 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf; 68 : 94704474 : iovs[1].iov_len = sz; 69 : : } else { 70 : 2049716 : iovs[1].iov_base = NULL; 71 : 2049716 : iovs[1].iov_len = 0; 72 : : } 73 : : } else { 74 : 15 : sz = spdk_min(requested_sz, read - write); 75 : : 76 : 15 : iovs[0].iov_base = pipe->buf + write; 77 : 15 : iovs[0].iov_len = sz; 78 : 15 : iovs[1].iov_base = NULL; 79 : 15 : iovs[1].iov_len = 0; 80 : : } 81 : : 82 : 96754205 : return iovs[0].iov_len + iovs[1].iov_len; 83 : : } 84 : : 85 : : int 86 : 20433173 : 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 : 20433173 : read = pipe->read; 93 : 20433173 : write = pipe->write; 94 : : 95 [ + + - + : 20433173 : if (requested_sz > pipe->sz || pipe->full) { - + ] 96 : 5 : return -EINVAL; 97 : : } 98 : : 99 [ + + ]: 20433168 : if (read <= write) { 100 [ + + ]: 20433148 : if (requested_sz > (pipe->sz - write) + read) { 101 : 5 : return -EINVAL; 102 : : } 103 : : 104 : 20433143 : sz = spdk_min(requested_sz, pipe->sz - write); 105 : : 106 : 20433143 : write += sz; 107 [ + + ]: 20433143 : if (write == pipe->sz) { 108 : 3396275 : write = 0; 109 : : } 110 : 20433143 : requested_sz -= sz; 111 : : 112 [ + + ]: 20433143 : if (requested_sz > 0) { 113 : 3387658 : write = requested_sz; 114 : : } 115 : : } else { 116 [ + + ]: 20 : if (requested_sz > (read - write)) { 117 : 10 : return -EINVAL; 118 : : } 119 : : 120 : 10 : write += requested_sz; 121 : : } 122 : : 123 [ + + ]: 20433153 : if (read == write) { 124 : 2217428 : pipe->full = true; 125 : : } 126 : 20433153 : pipe->write = write; 127 : : 128 : 20433153 : return 0; 129 : : } 130 : : 131 : : uint32_t 132 : 174193504 : spdk_pipe_reader_bytes_available(struct spdk_pipe *pipe) 133 : : { 134 : : uint32_t read; 135 : : uint32_t write; 136 : : 137 : 174193504 : read = pipe->read; 138 : 174193504 : write = pipe->write; 139 : : 140 [ + + - + : 174193504 : if (read == write && !pipe->full) { + - ] 141 : 88703922 : return 0; 142 [ + + ]: 85489582 : } else if (read < write) { 143 : 59442303 : return write - read; 144 : : } else { 145 : 26047279 : return (pipe->sz - read) + write; 146 : : } 147 : : } 148 : : 149 : : int 150 : 106994244 : 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 : 106994244 : read = pipe->read; 157 : 106994244 : write = pipe->write; 158 : : 159 [ + + - + : 106994244 : if ((read == write && !pipe->full) || requested_sz == 0) { + + + + ] 160 : 9513399 : iovs[0].iov_base = NULL; 161 : 9513399 : iovs[0].iov_len = 0; 162 : 9513399 : iovs[1].iov_base = NULL; 163 : 9513399 : iovs[1].iov_len = 0; 164 [ + + ]: 97480845 : } else if (read < write) { 165 : 69762744 : sz = spdk_min(requested_sz, write - read); 166 : : 167 : 69762744 : iovs[0].iov_base = pipe->buf + read; 168 : 69762744 : iovs[0].iov_len = sz; 169 : 69762744 : iovs[1].iov_base = NULL; 170 : 69762744 : iovs[1].iov_len = 0; 171 : : } else { 172 : 27718101 : sz = spdk_min(requested_sz, pipe->sz - read); 173 : : 174 : 27718101 : iovs[0].iov_base = pipe->buf + read; 175 : 27718101 : iovs[0].iov_len = sz; 176 : : 177 : 27718101 : requested_sz -= sz; 178 : : 179 [ + + ]: 27718101 : if (requested_sz > 0) { 180 : 27712658 : sz = spdk_min(requested_sz, write); 181 [ + + ]: 27712658 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf; 182 : 27712658 : iovs[1].iov_len = sz; 183 : : } else { 184 : 5443 : iovs[1].iov_base = NULL; 185 : 5443 : iovs[1].iov_len = 0; 186 : : } 187 : : } 188 : : 189 : 106994244 : return iovs[0].iov_len + iovs[1].iov_len; 190 : : } 191 : : 192 : : int 193 : 97480840 : 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 : 97480840 : read = pipe->read; 200 : 97480840 : write = pipe->write; 201 : : 202 [ - + ]: 97480840 : if (requested_sz == 0) { 203 : 0 : return 0; 204 : : } 205 : : 206 [ + + ]: 97480840 : if (read < write) { 207 [ + + ]: 69762754 : if (requested_sz > (write - read)) { 208 : 10 : return -EINVAL; 209 : : } 210 : : 211 : 69762744 : read += requested_sz; 212 : : } else { 213 : 27718086 : sz = spdk_min(requested_sz, pipe->sz - read); 214 : : 215 : 27718086 : read += sz; 216 [ + + ]: 27718086 : if (read == pipe->sz) { 217 : 3396263 : read = 0; 218 : : } 219 : 27718086 : requested_sz -= sz; 220 : : 221 [ + + ]: 27718086 : if (requested_sz > 0) { 222 [ - + ]: 3360519 : if (requested_sz > write) { 223 : 0 : return -EINVAL; 224 : : } 225 : : 226 : 3360519 : read = requested_sz; 227 : : } 228 : : } 229 : : 230 : : /* We know we advanced at least one byte, so the pipe isn't full. */ 231 : 97480830 : pipe->full = false; 232 : 97480830 : pipe->read = read; 233 : : 234 : 97480830 : return 0; 235 : : }