LCOV - code coverage report
Current view: top level - /home/runner/zephyrproject/zephyr/lib/utils - ring_buffer.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 0.0 % 127 0
Test Date: 2026-03-12 12:01:18 Functions: 0.0 % 7 0
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0.0 % 62 0

             Branch data     Line data    Source code
       1                 :             : /* ring_buffer.c: Simple ring buffer API */
       2                 :             : 
       3                 :             : /*
       4                 :             :  * Copyright (c) 2015 Intel Corporation
       5                 :             :  *
       6                 :             :  * SPDX-License-Identifier: Apache-2.0
       7                 :             :  */
       8                 :             : 
       9                 :             : #include <zephyr/sys/ring_buffer.h>
      10                 :             : #include <string.h>
      11                 :             : 
      12                 :           0 : uint32_t ring_buf_area_claim(struct ring_buf *buf, struct ring_buf_index *ring,
      13                 :             :                              uint8_t **data, uint32_t size)
      14                 :             : {
      15                 :           0 :         ring_buf_idx_t head_offset, wrap_size;
      16                 :             : 
      17                 :           0 :         head_offset = ring->head - ring->base;
      18         [ #  # ]:           0 :         if (unlikely(head_offset >= buf->size)) {
      19                 :             :                 /* ring->base is not yet adjusted */
      20                 :           0 :                 head_offset -= buf->size;
      21                 :             :         }
      22                 :           0 :         wrap_size = buf->size - head_offset;
      23                 :           0 :         size = min(size, wrap_size);
      24                 :             : 
      25                 :           0 :         *data = &buf->buffer[head_offset];
      26                 :           0 :         ring->head += size;
      27                 :             : 
      28                 :           0 :         return size;
      29                 :             : }
      30                 :             : 
      31                 :           0 : int ring_buf_area_finish(struct ring_buf *buf, struct ring_buf_index *ring,
      32                 :             :                          uint32_t size)
      33                 :             : {
      34                 :           0 :         ring_buf_idx_t claimed_size, tail_offset;
      35                 :             : 
      36                 :           0 :         claimed_size = ring->head - ring->tail;
      37         [ #  # ]:           0 :         if (unlikely(size > claimed_size)) {
      38                 :             :                 return -EINVAL;
      39                 :             :         }
      40                 :             : 
      41                 :           0 :         ring->tail += size;
      42                 :           0 :         ring->head = ring->tail;
      43                 :             : 
      44                 :           0 :         tail_offset = ring->tail - ring->base;
      45         [ #  # ]:           0 :         if (unlikely(tail_offset >= buf->size)) {
      46                 :             :                 /* we wrapped: adjust ring->base */
      47                 :           0 :                 ring->base += buf->size;
      48                 :             :         }
      49                 :             : 
      50                 :             :         return 0;
      51                 :             : }
      52                 :             : 
      53                 :           0 : uint32_t ring_buf_put(struct ring_buf *buf, const uint8_t *data, uint32_t size)
      54                 :             : {
      55                 :           0 :         uint8_t *dst;
      56                 :           0 :         uint32_t partial_size;
      57                 :           0 :         uint32_t total_size = 0U;
      58                 :           0 :         int err;
      59                 :             : 
      60                 :           0 :         do {
      61                 :           0 :                 partial_size = ring_buf_put_claim(buf, &dst, size);
      62         [ #  # ]:           0 :                 if (partial_size == 0) {
      63                 :             :                         break;
      64                 :             :                 }
      65         [ #  # ]:           0 :                 memcpy(dst, data, partial_size);
      66                 :           0 :                 total_size += partial_size;
      67                 :           0 :                 size -= partial_size;
      68                 :           0 :                 data += partial_size;
      69         [ #  # ]:           0 :         } while (size != 0);
      70                 :             : 
      71                 :           0 :         err = ring_buf_put_finish(buf, total_size);
      72         [ #  # ]:           0 :         __ASSERT_NO_MSG(err == 0);
      73                 :           0 :         ARG_UNUSED(err);
      74                 :             : 
      75                 :           0 :         return total_size;
      76                 :             : }
      77                 :             : 
      78                 :           0 : uint32_t ring_buf_get(struct ring_buf *buf, uint8_t *data, uint32_t size)
      79                 :             : {
      80                 :           0 :         uint8_t *src;
      81                 :           0 :         uint32_t partial_size;
      82                 :           0 :         uint32_t total_size = 0U;
      83                 :           0 :         int err;
      84                 :             : 
      85                 :           0 :         do {
      86                 :           0 :                 partial_size = ring_buf_get_claim(buf, &src, size);
      87         [ #  # ]:           0 :                 if (partial_size == 0) {
      88                 :             :                         break;
      89                 :             :                 }
      90         [ #  # ]:           0 :                 if (data) {
      91                 :           0 :                         memcpy(data, src, partial_size);
      92                 :           0 :                         data += partial_size;
      93                 :             :                 }
      94                 :           0 :                 total_size += partial_size;
      95                 :           0 :                 size -= partial_size;
      96         [ #  # ]:           0 :         } while (size != 0);
      97                 :             : 
      98                 :           0 :         err = ring_buf_get_finish(buf, total_size);
      99         [ #  # ]:           0 :         __ASSERT_NO_MSG(err == 0);
     100                 :           0 :         ARG_UNUSED(err);
     101                 :             : 
     102                 :           0 :         return total_size;
     103                 :             : }
     104                 :             : 
     105                 :           0 : uint32_t ring_buf_peek(struct ring_buf *buf, uint8_t *data, uint32_t size)
     106                 :             : {
     107                 :           0 :         uint8_t *src;
     108                 :           0 :         uint32_t partial_size;
     109                 :           0 :         uint32_t total_size = 0U;
     110                 :           0 :         int err;
     111                 :             : 
     112                 :           0 :         do {
     113                 :           0 :                 partial_size = ring_buf_get_claim(buf, &src, size);
     114         [ #  # ]:           0 :                 if (partial_size == 0) {
     115                 :             :                         break;
     116                 :             :                 }
     117         [ #  # ]:           0 :                 __ASSERT_NO_MSG(data != NULL);
     118         [ #  # ]:           0 :                 memcpy(data, src, partial_size);
     119                 :           0 :                 data += partial_size;
     120                 :           0 :                 total_size += partial_size;
     121                 :           0 :                 size -= partial_size;
     122         [ #  # ]:           0 :         } while (size != 0);
     123                 :             : 
     124                 :             :         /* effectively unclaim total_size bytes */
     125                 :           0 :         err = ring_buf_get_finish(buf, 0);
     126         [ #  # ]:           0 :         __ASSERT_NO_MSG(err == 0);
     127                 :           0 :         ARG_UNUSED(err);
     128                 :             : 
     129                 :           0 :         return total_size;
     130                 :             : }
     131                 :             : 
     132                 :             : /**
     133                 :             :  * Internal data structure for a buffer header.
     134                 :             :  *
     135                 :             :  * We want all of this to fit in a single uint32_t. Every item stored in the
     136                 :             :  * ring buffer will be one of these headers plus any extra data supplied
     137                 :             :  */
     138                 :             : struct ring_element {
     139                 :             :         uint32_t  type   :16; /**< Application-specific */
     140                 :             :         uint32_t  length :8;  /**< length in 32-bit chunks */
     141                 :             :         uint32_t  value  :8;  /**< Room for small integral values */
     142                 :             : };
     143                 :             : 
     144                 :           0 : int ring_buf_item_put(struct ring_buf *buf, uint16_t type, uint8_t value,
     145                 :             :                       uint32_t *data32, uint8_t size32)
     146                 :             : {
     147                 :           0 :         uint8_t *dst, *data = (uint8_t *)data32;
     148                 :           0 :         struct ring_element *header;
     149                 :           0 :         uint32_t space, size, partial_size, total_size;
     150                 :           0 :         int err;
     151                 :             : 
     152                 :           0 :         space = ring_buf_space_get(buf);
     153                 :           0 :         size = size32 * 4;
     154         [ #  # ]:           0 :         if (size + sizeof(struct ring_element) > space) {
     155                 :             :                 return -EMSGSIZE;
     156                 :             :         }
     157                 :             : 
     158                 :           0 :         err = ring_buf_put_claim(buf, &dst, sizeof(struct ring_element));
     159         [ #  # ]:           0 :         __ASSERT_NO_MSG(err == sizeof(struct ring_element));
     160                 :             : 
     161                 :           0 :         header = (struct ring_element *)dst;
     162                 :           0 :         header->type = type;
     163                 :           0 :         header->length = size32;
     164                 :           0 :         header->value = value;
     165                 :           0 :         total_size = sizeof(struct ring_element);
     166                 :             : 
     167                 :           0 :         do {
     168                 :           0 :                 partial_size = ring_buf_put_claim(buf, &dst, size);
     169         [ #  # ]:           0 :                 if (partial_size == 0) {
     170                 :             :                         break;
     171                 :             :                 }
     172         [ #  # ]:           0 :                 memcpy(dst, data, partial_size);
     173                 :           0 :                 size -= partial_size;
     174                 :           0 :                 total_size += partial_size;
     175                 :           0 :                 data += partial_size;
     176         [ #  # ]:           0 :         } while (size != 0);
     177         [ #  # ]:           0 :         __ASSERT_NO_MSG(size == 0);
     178                 :             : 
     179                 :           0 :         err = ring_buf_put_finish(buf, total_size);
     180         [ #  # ]:           0 :         __ASSERT_NO_MSG(err == 0);
     181                 :             :         ARG_UNUSED(err);
     182                 :             : 
     183                 :             :         return 0;
     184                 :             : }
     185                 :             : 
     186                 :           0 : int ring_buf_item_get(struct ring_buf *buf, uint16_t *type, uint8_t *value,
     187                 :             :                       uint32_t *data32, uint8_t *size32)
     188                 :             : {
     189                 :           0 :         uint8_t *src, *data = (uint8_t *)data32;
     190                 :           0 :         struct ring_element *header;
     191                 :           0 :         uint32_t size, partial_size, total_size;
     192                 :           0 :         int err;
     193                 :             : 
     194         [ #  # ]:           0 :         if (ring_buf_is_empty(buf)) {
     195                 :             :                 return -EAGAIN;
     196                 :             :         }
     197                 :             : 
     198                 :           0 :         err = ring_buf_get_claim(buf, &src, sizeof(struct ring_element));
     199         [ #  # ]:           0 :         __ASSERT_NO_MSG(err == sizeof(struct ring_element));
     200                 :             : 
     201                 :           0 :         header = (struct ring_element *)src;
     202                 :             : 
     203   [ #  #  #  # ]:           0 :         if (data && (header->length > *size32)) {
     204                 :           0 :                 *size32 = header->length;
     205                 :           0 :                 ring_buf_get_finish(buf, 0);
     206                 :           0 :                 return -EMSGSIZE;
     207                 :             :         }
     208                 :             : 
     209                 :           0 :         *size32 = header->length;
     210                 :           0 :         *type = header->type;
     211                 :           0 :         *value = header->value;
     212                 :           0 :         total_size = sizeof(struct ring_element);
     213                 :             : 
     214                 :           0 :         size = *size32 * 4;
     215                 :             : 
     216                 :           0 :         do {
     217                 :           0 :                 partial_size = ring_buf_get_claim(buf, &src, size);
     218         [ #  # ]:           0 :                 if (partial_size == 0) {
     219                 :             :                         break;
     220                 :             :                 }
     221         [ #  # ]:           0 :                 if (data) {
     222                 :           0 :                         memcpy(data, src, partial_size);
     223                 :           0 :                         data += partial_size;
     224                 :             :                 }
     225                 :           0 :                 total_size += partial_size;
     226                 :           0 :                 size -= partial_size;
     227         [ #  # ]:           0 :         } while (size != 0);
     228                 :             : 
     229                 :           0 :         err = ring_buf_get_finish(buf, total_size);
     230         [ #  # ]:           0 :         __ASSERT_NO_MSG(err == 0);
     231                 :             :         ARG_UNUSED(err);
     232                 :             : 
     233                 :             :         return 0;
     234                 :             : }
        

Generated by: LCOV version 2.0-1