LCOV - code coverage report
Current view: top level - zephyr/sys - mpsc_pbuf.h Hit Total Coverage
Test: new.info Lines: 27 37 73.0 %
Date: 2024-12-22 00:14:23

          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 1.14