lib: os: mpsc_pbuf: Add usage tracking

Add API to fetch current buffer usage. Add option to track
maximum buffer usage and API to fetch that value.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2022-02-07 14:18:57 +01:00 committed by Anas Nashif
parent 87f8b090ab
commit 5c8cc1aa8f
2 changed files with 68 additions and 0 deletions

View file

@ -58,6 +58,9 @@ extern "C" {
*/
#define MPSC_PBUF_MODE_OVERWRITE BIT(1)
/** @brief Flag indicating that maximum buffer usage is tracked. */
#define MPSC_PBUF_MAX_UTILIZATION BIT(2)
/**@} */
/* Forward declaration */
@ -112,6 +115,9 @@ struct mpsc_pbuf_buffer {
/* Buffer size in 32 bit words. */
uint32_t size;
/* Store max buffer usage. */
uint32_t max_usage;
struct k_sem sem;
};
@ -237,6 +243,24 @@ void mpsc_pbuf_free(struct mpsc_pbuf_buffer *buffer,
*/
bool mpsc_pbuf_is_pending(struct mpsc_pbuf_buffer *buffer);
/** @brief Get current memory utilization.
*
* @param[in, out] buffer Buffer.
* @param[out] size Buffer size in bytes.
* @param[out] now Current buffer usage in bytes.
*/
void mpsc_pbuf_get_utilization(struct mpsc_pbuf_buffer *buffer,
uint32_t *size, uint32_t *now);
/** @brief Get maximum memory utilization.
*
* @param[in, out] buffer Buffer.
* @param[out] max Maximum buffer usage in bytes.
*
* retval 0 if utilization data collected successfully.
* retval -ENOTSUP if Collecting utilization data is not supported.
*/
int mpsc_pbuf_get_max_utilization(struct mpsc_pbuf_buffer *buffer, uint32_t *max);
/**
* @}
*/

View file

@ -35,6 +35,7 @@ void mpsc_pbuf_init(struct mpsc_pbuf_buffer *buffer,
buffer->notify_drop = cfg->notify_drop;
buffer->buf = cfg->buf;
buffer->size = cfg->size;
buffer->max_usage = 0;
buffer->flags = cfg->flags;
if (is_power_of_two(buffer->size)) {
@ -74,6 +75,26 @@ static inline bool available(struct mpsc_pbuf_buffer *buffer, uint32_t *res)
return true;
}
static inline uint32_t get_usage(struct mpsc_pbuf_buffer *buffer)
{
uint32_t f;
if (free_space(buffer, &f)) {
f += (buffer->rd_idx - 1);
}
return buffer->size - 1 - f;
}
static inline void max_utilization_update(struct mpsc_pbuf_buffer *buffer)
{
if (!(buffer->flags & MPSC_PBUF_MAX_UTILIZATION)) {
return;
}
buffer->max_usage = MAX(buffer->max_usage, get_usage(buffer));
}
static inline bool is_valid(union mpsc_pbuf_generic *item)
{
return item->hdr.valid;
@ -190,6 +211,7 @@ void mpsc_pbuf_put_word(struct mpsc_pbuf_buffer *buffer,
buffer->tmp_wr_idx = idx_inc(buffer,
buffer->tmp_wr_idx, 1);
buffer->wr_idx = idx_inc(buffer, buffer->wr_idx, 1);
max_utilization_update(buffer);
} else {
bool user_drop = buffer->flags & MPSC_PBUF_MODE_OVERWRITE;
@ -288,6 +310,7 @@ void mpsc_pbuf_commit(struct mpsc_pbuf_buffer *buffer,
item->hdr.valid = 1;
buffer->wr_idx = idx_inc(buffer, buffer->wr_idx, wlen);
max_utilization_update(buffer);
k_spin_unlock(&buffer->lock, key);
MPSC_PBUF_DBG(buffer, "committed %p ", item);
}
@ -320,6 +343,7 @@ void mpsc_pbuf_put_word_ext(struct mpsc_pbuf_buffer *buffer,
buffer->tmp_wr_idx =
idx_inc(buffer, buffer->tmp_wr_idx, l);
buffer->wr_idx = idx_inc(buffer, buffer->wr_idx, l);
max_utilization_update(buffer);
} else if (wrap) {
add_skip_item(buffer, free_wlen);
cont = true;
@ -363,6 +387,7 @@ void mpsc_pbuf_put_data(struct mpsc_pbuf_buffer *buffer, const uint32_t *data,
buffer->tmp_wr_idx =
idx_inc(buffer, buffer->tmp_wr_idx, wlen);
buffer->wr_idx = idx_inc(buffer, buffer->wr_idx, wlen);
max_utilization_update(buffer);
} else if (wrap) {
add_skip_item(buffer, free_wlen);
cont = true;
@ -460,3 +485,22 @@ bool mpsc_pbuf_is_pending(struct mpsc_pbuf_buffer *buffer)
return a ? true : false;
}
void mpsc_pbuf_get_utilization(struct mpsc_pbuf_buffer *buffer,
uint32_t *size, uint32_t *now)
{
/* One byte is left for full/empty distinction. */
*size = (buffer->size - 1) * sizeof(int);
*now = get_usage(buffer) * sizeof(int);
}
int mpsc_pbuf_get_max_utilization(struct mpsc_pbuf_buffer *buffer, uint32_t *max)
{
if (!(buffer->flags & MPSC_PBUF_MAX_UTILIZATION)) {
return -ENOTSUP;
}
*max = buffer->max_usage * sizeof(int);
return 0;
}