add option to disable realloc and free

This commit is contained in:
Tilen M 2024-10-06 13:20:40 +02:00
parent 05942ae576
commit 54ff6c1aee
5 changed files with 48 additions and 15 deletions

View File

@ -3,6 +3,7 @@
## Develop ## Develop
- Rework library CMake with removed INTERFACE type - Rework library CMake with removed INTERFACE type
- Add `LWMEM_CFG_SUPPORT_REALLOC_AND_FREE` to disable realloc and free functions
## v2.1.0 ## v2.1.0

View File

@ -110,11 +110,13 @@ typedef struct {
size_t lwmem_assignmem_ex(lwmem_t* lwobj, const lwmem_region_t* regions); size_t lwmem_assignmem_ex(lwmem_t* lwobj, const lwmem_region_t* regions);
void* lwmem_malloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t size); void* lwmem_malloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t size);
void* lwmem_calloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t nitems, const size_t size); void* lwmem_calloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t nitems, const size_t size);
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__
void* lwmem_realloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, void* const ptr, const size_t size); void* lwmem_realloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, void* const ptr, const size_t size);
uint8_t lwmem_realloc_s_ex(lwmem_t* lwobj, const lwmem_region_t* region, void** const ptr, const size_t size); uint8_t lwmem_realloc_s_ex(lwmem_t* lwobj, const lwmem_region_t* region, void** const ptr, const size_t size);
void lwmem_free_ex(lwmem_t* lwobj, void* const ptr); void lwmem_free_ex(lwmem_t* lwobj, void* const ptr);
void lwmem_free_s_ex(lwmem_t* lwobj, void** const ptr); void lwmem_free_s_ex(lwmem_t* lwobj, void** const ptr);
size_t lwmem_get_size_ex(lwmem_t* lwobj, void* ptr); size_t lwmem_get_size_ex(lwmem_t* lwobj, void* ptr);
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__ */
#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ #if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__
void lwmem_get_stats_ex(lwmem_t* lwobj, lwmem_stats_t* stats); void lwmem_get_stats_ex(lwmem_t* lwobj, lwmem_stats_t* stats);
#endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */ #endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */
@ -157,6 +159,8 @@ lwmem_region_t regions[] = {
*/ */
#define lwmem_calloc(nitems, size) lwmem_calloc_ex(NULL, NULL, (nitems), (size)) #define lwmem_calloc(nitems, size) lwmem_calloc_ex(NULL, NULL, (nitems), (size))
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__
/** /**
* \note This is a wrapper for \ref lwmem_realloc_ex function. * \note This is a wrapper for \ref lwmem_realloc_ex function.
* It operates in default LwMEM instance and uses first available region for memory operations * It operates in default LwMEM instance and uses first available region for memory operations
@ -205,6 +209,10 @@ lwmem_region_t regions[] = {
*/ */
#define lwmem_get_size(ptr) lwmem_get_size_ex(NULL, (ptr)) #define lwmem_get_size(ptr) lwmem_get_size_ex(NULL, (ptr))
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__ */
#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__
/** /**
* \note This is a wrapper for \ref lwmem_get_stats_ex function. * \note This is a wrapper for \ref lwmem_get_stats_ex function.
* It operates in default LwMEM instance * It operates in default LwMEM instance
@ -212,6 +220,8 @@ lwmem_region_t regions[] = {
*/ */
#define lwmem_get_stats(stats) lwmem_get_stats_ex(NULL, (stats)) #define lwmem_get_stats(stats) lwmem_get_stats_ex(NULL, (stats))
#endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */
#if defined(LWMEM_DEV) && !__DOXYGEN__ #if defined(LWMEM_DEV) && !__DOXYGEN__
unsigned char lwmem_debug_create_regions(lwmem_region_t** regs_out, size_t count, size_t size); unsigned char lwmem_debug_create_regions(lwmem_region_t** regs_out, size_t count, size_t size);
void lwmem_debug_save_state(void); void lwmem_debug_save_state(void);

View File

@ -93,6 +93,7 @@ class LwmemLight {
return lwmem_calloc_ex(&m_lw, nullptr, nitems, size); return lwmem_calloc_ex(&m_lw, nullptr, nitems, size);
} }
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__
/** /**
* \brief Reallocate block of memory * \brief Reallocate block of memory
* \param ptr: Pointer to previously allocated memory block * \param ptr: Pointer to previously allocated memory block
@ -114,6 +115,7 @@ class LwmemLight {
free(void* ptr) { free(void* ptr) {
lwmem_free_ex(&m_lw, ptr); lwmem_free_ex(&m_lw, ptr);
} }
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__ */
private: private:
/* Delete unused constructors */ /* Delete unused constructors */

View File

@ -85,6 +85,21 @@ extern "C" {
#define LWMEM_CFG_ALIGN_NUM ((size_t)4) #define LWMEM_CFG_ALIGN_NUM ((size_t)4)
#endif #endif
/**
* \brief Enables `1` or disables `0` full memory management support.
*
* When enabled, library supports allocation, reallocation and freeing of the memory.
* When disabled, library only supports allocation, which is useful for
* power up memory initialization only.
*
* \note When disabled, \ref lwmem_get_size_ex is also not available,
* as it is assumed that user won't frequently ask for size of
* previously allocated block if realloc isn't being used
*/
#ifndef LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#define LWMEM_CFG_SUPPORT_REALLOC_AND_FREE 1
#endif
/** /**
* \brief Enables `1` or disables `0` memory cleanup on free operation (or realloc). * \brief Enables `1` or disables `0` memory cleanup on free operation (or realloc).
* *

View File

@ -435,6 +435,8 @@ prv_alloc(lwmem_t* const lwobj, const lwmem_region_t* region, const size_t size)
return retval; return retval;
} }
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
/** /**
* \brief Free input pointer * \brief Free input pointer
* \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
@ -653,15 +655,12 @@ prv_realloc(lwmem_t* const lwobj, const lwmem_region_t* region, void* const ptr,
*/ */
LWMEM_MEMMOVE(new_data_ptr, old_data_ptr, block_size); /* Copy old buffer size to new location */ LWMEM_MEMMOVE(new_data_ptr, old_data_ptr, block_size); /* Copy old buffer size to new location */
lwobj->mem_available_bytes -= /* Decrease effective available bytes for free blocks before and after input block */
prev->size lwobj->mem_available_bytes -= prev->size + prev->next->size;
+ prev->next
->size; /* Decrease effective available bytes for free blocks before and after input block */
LWMEM_UPDATE_MIN_FREE(lwobj); LWMEM_UPDATE_MIN_FREE(lwobj);
prev->size += block_size + prev->next->size; /* Increase size of new block by size of 2 free blocks */ prev->size += block_size + prev->next->size; /* Increase size of new block by size of 2 free blocks */
prevprev->next = /* Remove free block before current one and block after current one from linked list (remove 2) */
prev->next prevprev->next = prev->next->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 */ block = prev; /* Previous block is now current */
prv_split_too_big_block(lwobj, block, final_size); /* Split block if it is too big */ prv_split_too_big_block(lwobj, block, final_size); /* Split block if it is too big */
@ -684,14 +683,16 @@ prv_realloc(lwmem_t* const lwobj, const lwmem_region_t* region, void* const ptr,
*/ */
retval = prv_alloc(lwobj, region, size); /* Try to allocate new block */ retval = prv_alloc(lwobj, region, size); /* Try to allocate new block */
if (retval != NULL) { if (retval != NULL) {
block_size = /* Get application size from input pointer, then copy content to new block */
(block->size & ~LWMEM_ALLOC_BIT) - LWMEM_BLOCK_META_SIZE; /* Get application size from input pointer */ block_size = (block->size & ~LWMEM_ALLOC_BIT) - LWMEM_BLOCK_META_SIZE;
LWMEM_MEMCPY(retval, ptr, size > block_size ? block_size : size); /* Copy content to new allocated block */ LWMEM_MEMCPY(retval, ptr, size > block_size ? block_size : size);
prv_free(lwobj, ptr); /* Free input pointer */ prv_free(lwobj, ptr); /* Free old block */
} }
return retval; return retval;
} }
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
/** /**
* \brief Initializes and assigns user regions for memory used by allocator algorithm * \brief Initializes and assigns user regions for memory used by allocator algorithm
* \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance * \param[in] lwobj: LwMEM instance. Set to `NULL` to use default instance
@ -873,6 +874,8 @@ lwmem_calloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t nitem
return ptr; return ptr;
} }
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__
/** /**
* \brief Reallocates already allocated memory with new size in specific lwmem instance and region. * \brief Reallocates already allocated memory with new size in specific lwmem instance and region.
* *
@ -1022,6 +1025,8 @@ lwmem_get_size_ex(lwmem_t* lwobj, void* ptr) {
return len; return len;
} }
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__ */
#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ #if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__
/** /**