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 : 10481 : spdk_pipe_create(void *buf, uint32_t sz) 20 : : { 21 : : struct spdk_pipe *pipe; 22 : : 23 : 10481 : pipe = calloc(1, sizeof(*pipe)); 24 [ - + ]: 10481 : if (pipe == NULL) { 25 : 0 : return NULL; 26 : : } 27 : : 28 : 10481 : pipe->buf = buf; 29 : 10481 : pipe->sz = sz; 30 : : 31 : 10481 : return pipe; 32 : : } 33 : : 34 : : void 35 : 10988 : spdk_pipe_destroy(struct spdk_pipe *pipe) 36 : : { 37 : 10988 : free(pipe); 38 : 10988 : } 39 : : 40 : : int 41 : 206086115 : 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 : 206086115 : read = pipe->read; 48 : 206086115 : write = pipe->write; 49 : : 50 [ + + + + : 206086115 : 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 [ + + ]: 206086107 : if (read <= write) { 57 : 206086095 : sz = spdk_min(requested_sz, pipe->sz - write); 58 : : 59 : 206086095 : iovs[0].iov_base = pipe->buf + write; 60 : 206086095 : iovs[0].iov_len = sz; 61 : : 62 : 206086095 : requested_sz -= sz; 63 : : 64 [ + + ]: 206086095 : if (requested_sz > 0) { 65 : 203628316 : sz = spdk_min(requested_sz, read); 66 : : 67 [ + + ]: 203628316 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf; 68 : 203628316 : iovs[1].iov_len = sz; 69 : : } else { 70 : 2457779 : iovs[1].iov_base = NULL; 71 : 2457779 : 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 : 206086107 : return iovs[0].iov_len + iovs[1].iov_len; 83 : : } 84 : : 85 : : int 86 : 22366494 : 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 : 22366494 : read = pipe->read; 93 : 22366494 : write = pipe->write; 94 : : 95 [ + + - + : 22366494 : if (requested_sz > pipe->sz || pipe->full) { - + ] 96 : 4 : return -EINVAL; 97 : : } 98 : : 99 [ + + ]: 22366490 : if (read <= write) { 100 [ + + ]: 22366474 : if (requested_sz > (pipe->sz - write) + read) { 101 : 4 : return -EINVAL; 102 : : } 103 : : 104 : 22366470 : sz = spdk_min(requested_sz, pipe->sz - write); 105 : : 106 : 22366470 : write += sz; 107 [ + + ]: 22366470 : if (write == pipe->sz) { 108 : 4039790 : write = 0; 109 : : } 110 : 22366470 : requested_sz -= sz; 111 : : 112 [ + + ]: 22366470 : if (requested_sz > 0) { 113 : 4027891 : 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 [ + + ]: 22366478 : if (read == write) { 124 : 2725627 : pipe->full = true; 125 : : } 126 : 22366478 : pipe->write = write; 127 : : 128 : 22366478 : return 0; 129 : : } 130 : : 131 : : uint32_t 132 : 332556420 : spdk_pipe_reader_bytes_available(struct spdk_pipe *pipe) 133 : : { 134 : : uint32_t read; 135 : : uint32_t write; 136 : : 137 : 332556420 : read = pipe->read; 138 : 332556420 : write = pipe->write; 139 : : 140 [ + + - + : 332556420 : if (read == write && !pipe->full) { + - ] 141 : 207523102 : return 0; 142 [ + + ]: 125033318 : } else if (read < write) { 143 : 79918034 : return write - read; 144 : : } else { 145 : 45115284 : return (pipe->sz - read) + write; 146 : : } 147 : : } 148 : : 149 : : int 150 : 130506753 : 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 : 130506753 : read = pipe->read; 157 : 130506753 : write = pipe->write; 158 : : 159 [ + + - + : 130506753 : if ((read == write && !pipe->full) || requested_sz == 0) { + + + + ] 160 : 10479308 : iovs[0].iov_base = NULL; 161 : 10479308 : iovs[0].iov_len = 0; 162 : 10479308 : iovs[1].iov_base = NULL; 163 : 10479308 : iovs[1].iov_len = 0; 164 [ + + ]: 120027445 : } else if (read < write) { 165 : 81919822 : sz = spdk_min(requested_sz, write - read); 166 : : 167 : 81919822 : iovs[0].iov_base = pipe->buf + read; 168 : 81919822 : iovs[0].iov_len = sz; 169 : 81919822 : iovs[1].iov_base = NULL; 170 : 81919822 : iovs[1].iov_len = 0; 171 : : } else { 172 : 38107623 : sz = spdk_min(requested_sz, pipe->sz - read); 173 : : 174 : 38107623 : iovs[0].iov_base = pipe->buf + read; 175 : 38107623 : iovs[0].iov_len = sz; 176 : : 177 : 38107623 : requested_sz -= sz; 178 : : 179 [ + + ]: 38107623 : if (requested_sz > 0) { 180 : 38098854 : sz = spdk_min(requested_sz, write); 181 [ + + ]: 38098854 : iovs[1].iov_base = (sz == 0) ? NULL : pipe->buf; 182 : 38098854 : iovs[1].iov_len = sz; 183 : : } else { 184 : 8769 : iovs[1].iov_base = NULL; 185 : 8769 : iovs[1].iov_len = 0; 186 : : } 187 : : } 188 : : 189 : 130506753 : return iovs[0].iov_len + iovs[1].iov_len; 190 : : } 191 : : 192 : : int 193 : 120027441 : 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 : 120027441 : read = pipe->read; 200 : 120027441 : write = pipe->write; 201 : : 202 [ - + ]: 120027441 : if (requested_sz == 0) { 203 : 0 : return 0; 204 : : } 205 : : 206 [ + + ]: 120027441 : if (read < write) { 207 [ + + ]: 81919830 : if (requested_sz > (write - read)) { 208 : 8 : return -EINVAL; 209 : : } 210 : : 211 : 81919822 : read += requested_sz; 212 : : } else { 213 : 38107611 : sz = spdk_min(requested_sz, pipe->sz - read); 214 : : 215 : 38107611 : read += sz; 216 [ + + ]: 38107611 : if (read == pipe->sz) { 217 : 4039782 : read = 0; 218 : : } 219 : 38107611 : requested_sz -= sz; 220 : : 221 [ + + ]: 38107611 : if (requested_sz > 0) { 222 [ - + ]: 3948853 : if (requested_sz > write) { 223 : 0 : return -EINVAL; 224 : : } 225 : : 226 : 3948853 : read = requested_sz; 227 : : } 228 : : } 229 : : 230 : : /* We know we advanced at least one byte, so the pipe isn't full. */ 231 : 120027433 : pipe->full = false; 232 : 120027433 : pipe->read = read; 233 : : 234 : 120027433 : return 0; 235 : : }