diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index b28639a9440..4bfa02d77c7 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -5017,6 +5018,33 @@ static inline uint32_t k_mem_slab_num_free_get(struct k_mem_slab *slab) return slab->num_blocks - slab->num_used; } +/** + * @brief Get the memory stats for a memory slab + * + * This routine gets the runtime memory usage stats for the slab @a slab. + * + * @param slab Address of the memory slab + * @param stats Pointer to memory into which to copy memory usage statistics + * + * @retval 0 Success + * @retval -EINVAL Any parameter points to NULL + */ + +int k_mem_slab_runtime_stats_get(struct k_mem_slab *slab, struct sys_memory_stats *stats); + +/** + * @brief Reset the maximum memory usage for a slab + * + * This routine resets the maximum memory usage for the slab @a slab to its + * current usage. + * + * @param slab Address of the memory slab + * + * @retval 0 Success + * @retval -EINVAL Memory slab is NULL + */ +int k_mem_slab_runtime_stats_reset_max(struct k_mem_slab *slab); + /** @} */ /** diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index 6752dddf8d9..28f5c471bd8 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -170,3 +170,41 @@ void k_mem_slab_free(struct k_mem_slab *slab, void **mem) k_spin_unlock(&slab->lock, key); } + +int k_mem_slab_runtime_stats_get(struct k_mem_slab *slab, struct sys_memory_stats *stats) +{ + if ((slab == NULL) || (stats == NULL)) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&slab->lock); + + stats->allocated_bytes = slab->num_used * slab->block_size; + stats->free_bytes = (slab->num_blocks - slab->num_used) * slab->block_size; +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION + stats->max_allocated_bytes = slab->max_used * slab->block_size; +#else + stats->max_allocated_bytes = 0; +#endif + + k_spin_unlock(&slab->lock, key); + + return 0; +} + +#ifdef CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION +int k_mem_slab_runtime_stats_reset_max(struct k_mem_slab *slab) +{ + if (slab == NULL) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&slab->lock); + + slab->max_used = slab->num_used; + + k_spin_unlock(&slab->lock, key); + + return 0; +} +#endif