LCOV - code coverage report
Current view: top level - lib/util - pipe.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 106 110 96.4 %
Date: 2024-07-10 09:24:46 Functions: 7 7 100.0 %

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

Generated by: LCOV version 1.15