Add more useful info to stats

Add total size, available size, and minimum ever available size
This commit is contained in:
upbeat27 2022-03-14 09:34:45 -07:00
parent 2a81abf0f4
commit 57f4d15718
2 changed files with 44 additions and 0 deletions

View File

@ -70,6 +70,9 @@ typedef struct lwmem_block {
* \brief Statistics structure
*/
typedef struct {
uint32_t mem_size_bytes; /*!< Total memory size of all regions combined */
uint32_t mem_available_bytes; /*!< Free memory available for allocation */
uint32_t minimum_ever_mem_available_bytes; /*!< Minimum amount of total free memory there has been in the heap since the system booted. */
uint32_t nr_alloc; /*!< Number of all allocated blocks in single instance */
uint32_t nr_free; /*!< Number of frees in the LwMEM instance */
} lwmem_stats_t;
@ -110,6 +113,9 @@ uint8_t lwmem_realloc_s_ex(lwmem_t* lw, const lwmem_region_t* region, void**
void lwmem_free_ex(lwmem_t* lw, void* const ptr);
void lwmem_free_s_ex(lwmem_t* lw, void** const ptr);
size_t lwmem_get_size_ex(lwmem_t* lw, void* ptr);
#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__
void lwmem_get_stats_ex(lwmem_t* lw, lwmem_stats_t* stats);
#endif
/**
* \note This is a wrapper for \ref lwmem_assignmem_ex function.
@ -197,6 +203,13 @@ lwmem_region_t regions[] = {
*/
#define lwmem_get_size(ptr) lwmem_get_size(NULL, (ptr))
/**
* \note This is a wrapper for \ref lwmem_get_stats_ex function.
* It operates in default LwMEM instance
* \param[in] ptr: Pointer to lwmem_stats_t to store result
*/
#define lwmem_get_stats(stats) lwmem_get_stats_ex(NULL, (stats))
#if defined(LWMEM_DEV) && !__DOXYGEN__
unsigned char lwmem_debug_create_regions(lwmem_region_t** regs_out, size_t count, size_t size);
void lwmem_debug_save_state(void);

View File

@ -148,8 +148,14 @@
/* Statistics part */
#if LWMEM_CFG_ENABLE_STATS
#define LWMEM_INC_STATS(field) (++(field))
#define LWMEM_UPDATE_MIN_FREE(lw) do { \
if (lw->mem_available_bytes < lw->stats.minimum_ever_mem_available_bytes) { \
lw->stats.minimum_ever_mem_available_bytes = lw->mem_available_bytes; \
} \
} while (0)
#else
#define LWMEM_INC_STATS(field)
#define LWMEM_UPDATE_MIN_FREE(lw, current_free)
#endif /* LWMEM_CFG_ENABLE_STATS */
/**
@ -411,6 +417,7 @@ prv_alloc(lwmem_t* const lw, const lwmem_region_t* region, const size_t size) {
prv_split_too_big_block(lw, curr, final_size); /* Split block if it is too big */
LWMEM_BLOCK_SET_ALLOC(curr); /* Set block as allocated */
LWMEM_UPDATE_MIN_FREE(lw);
LWMEM_INC_STATS(lw->stats.nr_alloc);
return retval;
@ -560,6 +567,7 @@ prv_realloc(lwmem_t* const lw, const lwmem_region_t* region, void* const ptr, co
* and remove next free from list of free blocks
*/
lw->mem_available_bytes -= prev->next->size; /* For now decrease effective available bytes */
LWMEM_UPDATE_MIN_FREE(lw);
block->size = block_size + prev->next->size;/* Increase effective size of new block */
prev->next = prev->next->next; /* Set next to next's next, effectively remove expanded block from free list */
@ -590,6 +598,7 @@ prv_realloc(lwmem_t* const lw, const lwmem_region_t* region, void* const ptr, co
LWMEM_MEMMOVE(new_data_ptr, old_data_ptr, block_size);
lw->mem_available_bytes -= prev->size;/* For now decrease effective available bytes */
LWMEM_UPDATE_MIN_FREE(lw);
prev->size += block_size; /* Increase size of input block size */
prevprev->next = prev->next; /* Remove prev from free list as it is now being used for allocation together with existing block */
block = prev; /* Move block pointer to previous one */
@ -626,6 +635,7 @@ prv_realloc(lwmem_t* const lw, const lwmem_region_t* region, void* const ptr, co
LWMEM_MEMMOVE(new_data_ptr, old_data_ptr, block_size); /* Copy old buffer size to new location */
lw->mem_available_bytes -= prev->size + prev->next->size; /* Decrease effective available bytes for free blocks before and after input block */
LWMEM_UPDATE_MIN_FREE(lw);
prev->size += block_size + prev->next->size;/* Increase size of new block by size of 2 free blocks */
prevprev->next = prev->next->next; /* Remove free block before current one and block after current one from linked list (remove 2) */
block = prev; /* Previous block is now current */
@ -781,6 +791,10 @@ lwmem_assignmem_ex(lwmem_t* lw, const lwmem_region_t* regions) {
/* Copy default state of start block */
LWMEM_MEMCPY(&lwmem_default.start_block_first_use, &lwmem_default.start_block, sizeof(lwmem_default.start_block));
#endif /* defined(LWMEM_DEV) */
#if LWMEM_CFG_ENABLE_STATS
lw->stats.mem_size_bytes = lw->mem_available_bytes;
lw->stats.minimum_ever_mem_available_bytes = lw->mem_available_bytes;
#endif
return lw->mem_regions_count; /* Return number of regions used by manager */
}
@ -983,6 +997,23 @@ lwmem_get_size_ex(lwmem_t* lw, void* ptr) {
return len;
}
/**
* \brief Get statistics of a LwMEM instance
* \param[in] lw: LwMEM instance. Set to `NULL` to use default instance.
* Instance must be the same as used during allocation procedure
* \param[in] stats: Pointer to lwmem_stats_t to store result
*/
void
lwmem_get_stats_ex(lwmem_t* lw, lwmem_stats_t* stats) {
if (stats != NULL) {
lw = LWMEM_GET_LW(lw);
LWMEM_PROTECT(lw);
*stats = lw->stats;
stats->mem_available_bytes = lw->mem_available_bytes;
LWMEM_UNPROTECT(lw);
}
}
/* Part of library used ONLY for LWMEM_DEV purposes */
/* To validate and test library */