LCOV - code coverage report
Current view: top level - zephyr/sys - mpsc_pbuf.h Coverage Total Hit
Test: new.info Lines: 73.0 % 37 27
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2021 Nordic Semiconductor ASA
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : #ifndef ZEPHYR_INCLUDE_SYS_MPSC_PBUF_H_
       7              : #define ZEPHYR_INCLUDE_SYS_MPSC_PBUF_H_
       8              : 
       9              : #include <zephyr/kernel.h>
      10              : #include <zephyr/sys/mpsc_packet.h>
      11              : #include <string.h>
      12              : #include <stdint.h>
      13              : #include <stdbool.h>
      14              : 
      15              : #ifdef __cplusplus
      16              : extern "C" {
      17              : #endif
      18              : 
      19              : /**
      20              :  * @brief Multi producer, single consumer packet buffer API
      21              :  * @defgroup mpsc_buf MPSC (Multi producer, single consumer) packet buffer API
      22              :  * @ingroup datastructure_apis
      23              :  * @{
      24              :  */
      25              : 
      26              : /*
      27              :  * Multi producer, single consumer packet buffer allows to allocate variable
      28              :  * length consecutive space for storing a packet. When space is allocated
      29              :  * it can be filled by the user (except for the first 2 bits) and when packet
      30              :  * is ready it is committed. It is allowed to allocate another packet before
      31              :  * committing the previous one.
      32              :  *
      33              :  * If buffer is full and packet cannot be allocated then null is returned unless
      34              :  * overwrite mode is selected. In that mode, oldest entry are dropped (user is
      35              :  * notified) until allocation succeeds. It can happen that candidate for
      36              :  * dropping is currently being claimed. In that case, it is omitted and next
      37              :  * packet is dropped and claimed packet is marked as invalid when freeing.
      38              :  *
      39              :  * Reading packets is performed in two steps. First packet is claimed. Claiming
      40              :  * returns pointer to the packet within the buffer. Packet is freed when no
      41              :  * longer in use.
      42              :  */
      43              : 
      44              : /**@defgroup MPSC_PBUF_FLAGS MPSC packet buffer flags
      45              :  * @{
      46              :  */
      47              : 
      48              : /** @brief Flag indicating that buffer size is power of 2.
      49              :  *
      50              :  * When buffer size is power of 2 then optimizations are applied.
      51              :  */
      52            1 : #define MPSC_PBUF_SIZE_POW2 BIT(0)
      53              : 
      54              : /** @brief Flag indicating buffer full policy.
      55              :  *
      56              :  * If flag is set then when allocating from a full buffer oldest packets are
      57              :  * dropped. When flag is not set then allocation returns null.
      58              :  */
      59            1 : #define MPSC_PBUF_MODE_OVERWRITE BIT(1)
      60              : 
      61              : /** @brief Flag indicating that maximum buffer usage is tracked. */
      62            1 : #define MPSC_PBUF_MAX_UTILIZATION BIT(2)
      63              : 
      64              : /** @brief Flag indicated that buffer is currently full. */
      65            1 : #define MPSC_PBUF_FULL BIT(3)
      66              : 
      67              : /**@} */
      68              : 
      69              : /* Forward declaration */
      70              : struct mpsc_pbuf_buffer;
      71              : 
      72              : /** @brief Callback prototype for getting length of a packet.
      73              :  *
      74              :  * @param packet User packet.
      75              :  *
      76              :  * @return Size of the packet in 32 bit words.
      77              :  */
      78            1 : typedef uint32_t (*mpsc_pbuf_get_wlen)(const union mpsc_pbuf_generic *packet);
      79              : 
      80              : /** @brief Callback called when packet is dropped.
      81              :  *
      82              :  * @param buffer Packet buffer.
      83              :  *
      84              :  * @param packet Packet that is being dropped.
      85              :  */
      86            1 : typedef void (*mpsc_pbuf_notify_drop)(const struct mpsc_pbuf_buffer *buffer,
      87              :                                       const union mpsc_pbuf_generic *packet);
      88              : 
      89              : /** @brief MPSC packet buffer structure. */
      90            1 : struct mpsc_pbuf_buffer {
      91              :         /** Temporary write index. */
      92            1 :         uint32_t tmp_wr_idx;
      93              : 
      94              :         /** Write index. */
      95            1 :         uint32_t wr_idx;
      96              : 
      97              :         /** Temporary read index. */
      98            1 :         uint32_t tmp_rd_idx;
      99              : 
     100              :         /** Read index. */
     101            1 :         uint32_t rd_idx;
     102              : 
     103              :         /** Flags. */
     104            1 :         uint32_t flags;
     105              : 
     106              :         /** Lock. */
     107            1 :         struct k_spinlock lock;
     108              : 
     109              :         /** User callback called whenever packet is dropped.
     110              :          *
     111              :          * May be NULL if unneeded.
     112              :          */
     113            1 :         mpsc_pbuf_notify_drop notify_drop;
     114              : 
     115              :         /** Callback for getting packet length. */
     116            1 :         mpsc_pbuf_get_wlen get_wlen;
     117              : 
     118              :         /* Buffer. */
     119            0 :         uint32_t *buf;
     120              : 
     121              :         /* Buffer size in 32 bit words. */
     122            0 :         uint32_t size;
     123              : 
     124              :         /* Store max buffer usage. */
     125            0 :         uint32_t max_usage;
     126              : 
     127            0 :         struct k_sem sem;
     128              : };
     129              : 
     130              : /** @brief MPSC packet buffer configuration. */
     131            1 : struct mpsc_pbuf_buffer_config {
     132              :         /* Pointer to a memory used for storing packets. */
     133            0 :         uint32_t *buf;
     134              : 
     135              :         /* Buffer size in 32 bit words. */
     136            0 :         uint32_t size;
     137              : 
     138              :         /* Callbacks. */
     139            0 :         mpsc_pbuf_notify_drop notify_drop;
     140            0 :         mpsc_pbuf_get_wlen get_wlen;
     141              : 
     142              :         /* Configuration flags. */
     143            0 :         uint32_t flags;
     144              : };
     145              : 
     146              : /** @brief Initialize a packet buffer.
     147              :  *
     148              :  * @param buffer Buffer.
     149              :  *
     150              :  * @param config Configuration.
     151              :  */
     152            1 : void mpsc_pbuf_init(struct mpsc_pbuf_buffer *buffer,
     153              :                     const struct mpsc_pbuf_buffer_config *config);
     154              : 
     155              : /** @brief Allocate a packet.
     156              :  *
     157              :  * If a buffer is configured to overwrite mode then if there is no space to
     158              :  * allocate a new buffer, oldest packets are dropped. Otherwise allocation
     159              :  * fails and null pointer is returned.
     160              :  *
     161              :  * @param buffer Buffer.
     162              :  *
     163              :  * @param wlen Number of words to allocate.
     164              :  *
     165              :  * @param timeout Timeout. If called from thread context it will pend for given
     166              :  * timeout if packet cannot be allocated before dropping the oldest or
     167              :  * returning null.
     168              :  *
     169              :  * @return Pointer to the allocated space or null if it cannot be allocated.
     170              :  */
     171            1 : union mpsc_pbuf_generic *mpsc_pbuf_alloc(struct mpsc_pbuf_buffer *buffer,
     172              :                                          size_t wlen, k_timeout_t timeout);
     173              : 
     174              : /** @brief Commit a packet.
     175              :  *
     176              :  * @param buffer Buffer.
     177              :  *
     178              :  * @param packet Pointer to a packet allocated by @ref mpsc_pbuf_alloc.
     179              :  */
     180            1 : void mpsc_pbuf_commit(struct mpsc_pbuf_buffer *buffer,
     181              :                         union mpsc_pbuf_generic *packet);
     182              : 
     183              : /** @brief Put single word packet into a buffer.
     184              :  *
     185              :  * Function is optimized for storing a packet which fit into a single word.
     186              :  * Note that 2 bits of that word is used by the buffer.
     187              :  *
     188              :  * @param buffer Buffer.
     189              :  *
     190              :  * @param word Packet content consisting of MPSC_PBUF_HDR with valid bit set
     191              :  * and data on remaining bits.
     192              :  */
     193            1 : void mpsc_pbuf_put_word(struct mpsc_pbuf_buffer *buffer,
     194              :                         const union mpsc_pbuf_generic word);
     195              : 
     196              : /** @brief Put a packet consisting of a word and a pointer.
     197              :  *  *
     198              :  * Function is optimized for storing packet consisting of a word and a pointer.
     199              :  * Note that 2 bits of a first word is used by the buffer.
     200              :  *
     201              :  * @param buffer Buffer.
     202              :  *
     203              :  * @param word First word of a packet consisting of MPSC_PBUF_HDR with valid
     204              :  * bit set and data on remaining bits.
     205              :  *
     206              :  * @param data User data.
     207              :  */
     208            1 : void mpsc_pbuf_put_word_ext(struct mpsc_pbuf_buffer *buffer,
     209              :                             const union mpsc_pbuf_generic word,
     210              :                             const void *data);
     211              : 
     212              : /** @brief Put a packet into a buffer.
     213              :  *
     214              :  * Copy data into a buffer.
     215              :  * Note that 2 bits of a first word is used by the buffer.
     216              :  *
     217              :  * @param buffer Buffer.
     218              :  *
     219              :  * @param data First word of data must contain MPSC_PBUF_HDR with valid bit set.
     220              :  *
     221              :  * @param wlen Packet size in words.
     222              :  */
     223            1 : void mpsc_pbuf_put_data(struct mpsc_pbuf_buffer *buffer,
     224              :                         const uint32_t *data, size_t wlen);
     225              : 
     226              : /** @brief Claim the first pending packet.
     227              :  *
     228              :  * @param buffer Buffer.
     229              :  *
     230              :  * @return Pointer to the claimed packet or null if none available.
     231              :  */
     232            1 : const union mpsc_pbuf_generic *mpsc_pbuf_claim(struct mpsc_pbuf_buffer *buffer);
     233              : 
     234              : /** @brief Free a packet.
     235              :  *
     236              :  * @param buffer Buffer.
     237              :  *
     238              :  * @param packet Packet.
     239              :  */
     240            1 : void mpsc_pbuf_free(struct mpsc_pbuf_buffer *buffer,
     241              :                     const union mpsc_pbuf_generic *packet);
     242              : 
     243              : /** @brief Check if there are any message pending.
     244              :  *
     245              :  * @param buffer Buffer.
     246              :  *
     247              :  * @retval true if pending.
     248              :  * @retval false if no message is pending.
     249              :  */
     250            1 : bool mpsc_pbuf_is_pending(struct mpsc_pbuf_buffer *buffer);
     251              : 
     252              : /** @brief Get current memory utilization.
     253              :  *
     254              :  * @param[in, out] buffer Buffer.
     255              :  * @param[out]     size   Buffer size in bytes.
     256              :  * @param[out]     now    Current buffer usage in bytes.
     257              :  */
     258            1 : void mpsc_pbuf_get_utilization(struct mpsc_pbuf_buffer *buffer,
     259              :                                uint32_t *size, uint32_t *now);
     260              : 
     261              : /** @brief Get maximum memory utilization.
     262              :  *
     263              :  * @param[in, out] buffer Buffer.
     264              :  * @param[out]     max    Maximum buffer usage in bytes.
     265              :  *
     266              :  * retval 0 if utilization data collected successfully.
     267              :  * retval -ENOTSUP if Collecting utilization data is not supported.
     268              :  */
     269            1 : int mpsc_pbuf_get_max_utilization(struct mpsc_pbuf_buffer *buffer, uint32_t *max);
     270              : /**
     271              :  * @}
     272              :  */
     273              : 
     274              : #ifdef __cplusplus
     275              : }
     276              : #endif
     277              : 
     278              : #endif /* ZEPHYR_INCLUDE_SYS_MPSC_PBUF_H_ */
        

Generated by: LCOV version 2.0-1