Change macro to LWMEM_CFG_FULL

This commit is contained in:
Tilen Majerle 2024-10-09 15:49:23 +02:00
parent 14740ff4f5
commit 187bc462eb
9 changed files with 97 additions and 92 deletions

View File

@ -3,7 +3,7 @@
## Develop
- Rework library CMake with removed INTERFACE type
- Add `LWMEM_CFG_SUPPORT_REALLOC_AND_FREE` to disable realloc and free functions
- Add `LWMEM_CFG_FULL` to allow control build configuration of the library
- Implement support for simple (no realloc, no free, grow-only malloc) allocation mechanism
## v2.1.0

View File

@ -41,10 +41,10 @@
* Open "include/lwmem/lwmem_opt.h" and
* copy & replace here settings you want to change values
*/
#define LWMEM_CFG_OS 1
#define LWMEM_CFG_OS_MUTEX_HANDLE HANDLE
#define LWMEM_CFG_ENABLE_STATS 0
#define LWMEM_CFG_CLEAN_MEMORY 1
#define LWMEM_CFG_SUPPORT_REALLOC_AND_FREE 1
#define LWMEM_CFG_OS 1
#define LWMEM_CFG_OS_MUTEX_HANDLE HANDLE
#define LWMEM_CFG_ENABLE_STATS 0
#define LWMEM_CFG_CLEAN_MEMORY 1
#define LWMEM_CFG_FULL 0
#endif /* LWMEM_HDR_OPTS_H */

View File

@ -13,7 +13,7 @@ static Lwmem::LwmemLight<1024> manager;
int
main(void) {
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#if LWMEM_CFG_FULL
lwmem_test_memory_structure();
//lwmem_test_run();
#else
@ -24,9 +24,9 @@ main(void) {
/* Test C++ code */
void* ret = manager.malloc(123);
std::cout << ret << std::endl;
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#if LWMEM_CFG_FULL
manager.free(ret);
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#endif /* LWMEM_CFG_FULL */
#endif
return 0;

View File

@ -84,7 +84,7 @@ typedef struct {
*/
typedef struct lwmem {
size_t mem_available_bytes; /*!< Memory size available for allocation */
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#if LWMEM_CFG_FULL
lwmem_block_t start_block; /*!< Holds beginning of memory allocation regions */
lwmem_block_t* end_block; /*!< Pointer to the last memory location in regions linked list */
size_t mem_regions_count; /*!< Number of regions used for allocation */
@ -116,13 +116,13 @@ typedef struct {
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_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__
#if LWMEM_CFG_FULL || __DOXYGEN__
void* lwmem_realloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, void* const ptr, const size_t size);
int 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_s_ex(lwmem_t* lwobj, void** const ptr);
size_t lwmem_get_size_ex(lwmem_t* lwobj, void* ptr);
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__ */
#endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__
void lwmem_get_stats_ex(lwmem_t* lwobj, lwmem_stats_t* stats);
#endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */
@ -131,14 +131,14 @@ size_t lwmem_assignmem(const lwmem_region_t* regions);
void* lwmem_malloc(size_t size);
void* lwmem_calloc(size_t nitems, size_t size);
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__
#if LWMEM_CFG_FULL || __DOXYGEN__
void* lwmem_realloc(void* ptr, size_t size);
int lwmem_realloc_s(void** ptr2ptr, size_t size);
void lwmem_free(void* ptr);
void lwmem_free_s(void** ptr2ptr);
size_t lwmem_get_size(void* ptr);
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__ */
#endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__

View File

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

View File

@ -88,16 +88,21 @@ extern "C" {
/**
* \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.
* When enabled (default config), library supports allocation, reallocation and freeing of the memory.
* - Memory allocation and [c]allocation
* - Memory reallocation
* - Memory allocation in user defined memory regions
* - Memory freeing
*
* \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
* When disabled, library only supports allocation and does not provide any other service.
* - Its purpose is for memory allocation at the start of firmware initialization only
*
* \note When disabled, statistics functionaltiy is not available
* and only one region is supported (for now, may be updated later).
* API to allocate memory remains the same as for full configuration.
*/
#ifndef LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#define LWMEM_CFG_SUPPORT_REALLOC_AND_FREE 1
#ifndef LWMEM_CFG_FULL
#define LWMEM_CFG_FULL 1
#endif
/**

View File

@ -40,10 +40,43 @@
#include "system/lwmem_sys.h"
#endif /* LWMEM_CFG_OS */
#if LWMEM_CFG_OS
#define LWMEM_PROTECT(lwobj) lwmem_sys_mutex_wait(&((lwobj)->mutex))
#define LWMEM_UNPROTECT(lwobj) lwmem_sys_mutex_release(&((lwobj)->mutex))
#else /* LWMEM_CFG_OS */
#define LWMEM_PROTECT(lwobj)
#define LWMEM_UNPROTECT(lwobj)
#endif /* !LWMEM_CFG_OS */
/* Statistics part */
#if LWMEM_CFG_ENABLE_STATS
#define LWMEM_INC_STATS(field) (++(field))
#define LWMEM_UPDATE_MIN_FREE(lwobj) \
do { \
if ((lwobj)->mem_available_bytes < (lwobj)->stats.minimum_ever_mem_available_bytes) { \
(lwobj)->stats.minimum_ever_mem_available_bytes = (lwobj)->mem_available_bytes; \
} \
} while (0)
#else
#define LWMEM_INC_STATS(field)
#define LWMEM_UPDATE_MIN_FREE(lwobj)
#endif /* LWMEM_CFG_ENABLE_STATS */
/**
* \brief LwMEM default structure used by application
*/
static lwmem_t lwmem_default;
/**
* \brief Get LwMEM instance based on user input
* \param[in] in_lwobj: LwMEM instance. Set to `NULL` for default instance
*/
#define LWMEM_GET_LWOBJ(in_lwobj) ((in_lwobj) != NULL ? (in_lwobj) : (&lwmem_default))
/**
* \brief Transform alignment number (power of `2`) to bits
*/
#define LWMEM_ALIGN_BITS ((size_t)(((size_t)LWMEM_CFG_ALIGN_NUM) - 1))
#define LWMEM_ALIGN_BITS ((size_t)(((size_t)LWMEM_CFG_ALIGN_NUM) - 1))
/**
* \brief Aligns input value to next alignment bits
@ -60,18 +93,20 @@
* - Input: `7`; Output: `8`
* - Input: `8`; Output: `8`
*/
#define LWMEM_ALIGN(x) (((x) + (LWMEM_ALIGN_BITS)) & ~(LWMEM_ALIGN_BITS))
/**
* \brief Size of metadata header for block information
*/
#define LWMEM_BLOCK_META_SIZE LWMEM_ALIGN(sizeof(lwmem_block_t))
#define LWMEM_ALIGN(x) (((x) + (LWMEM_ALIGN_BITS)) & ~(LWMEM_ALIGN_BITS))
/**
* \brief Cast input pointer to byte
* \param[in] p: Input pointer to cast to byte pointer
*/
#define LWMEM_TO_BYTE_PTR(p) ((uint8_t*)(p))
#define LWMEM_TO_BYTE_PTR(p) ((uint8_t*)(p))
#if LWMEM_CFG_FULL
/**
* \brief Size of metadata header for block information
*/
#define LWMEM_BLOCK_META_SIZE LWMEM_ALIGN(sizeof(lwmem_block_t))
/**
* \brief Bit indicating memory block is allocated
@ -121,13 +156,7 @@
*
* Default size is size of meta block
*/
#define LWMEM_BLOCK_MIN_SIZE (LWMEM_BLOCK_META_SIZE)
/**
* \brief Get LwMEM instance based on user input
* \param[in] in_lwobj: LwMEM instance. Set to `NULL` for default instance
*/
#define LWMEM_GET_LWOBJ(in_lwobj) ((in_lwobj) != NULL ? (in_lwobj) : (&lwmem_default))
#define LWMEM_BLOCK_MIN_SIZE (LWMEM_BLOCK_META_SIZE)
/**
* \brief Gets block before input block (marked as prev) and its previous free block
@ -142,35 +171,6 @@
(in_pp) = (in_p), (in_p) = (in_p)->next) {} \
} while (0)
#if LWMEM_CFG_OS
#define LWMEM_PROTECT(lwobj) lwmem_sys_mutex_wait(&((lwobj)->mutex))
#define LWMEM_UNPROTECT(lwobj) lwmem_sys_mutex_release(&((lwobj)->mutex))
#else /* LWMEM_CFG_OS */
#define LWMEM_PROTECT(lwobj)
#define LWMEM_UNPROTECT(lwobj)
#endif /* !LWMEM_CFG_OS */
/* Statistics part */
#if LWMEM_CFG_ENABLE_STATS
#define LWMEM_INC_STATS(field) (++(field))
#define LWMEM_UPDATE_MIN_FREE(lwobj) \
do { \
if ((lwobj)->mem_available_bytes < (lwobj)->stats.minimum_ever_mem_available_bytes) { \
(lwobj)->stats.minimum_ever_mem_available_bytes = (lwobj)->mem_available_bytes; \
} \
} while (0)
#else
#define LWMEM_INC_STATS(field)
#define LWMEM_UPDATE_MIN_FREE(lwobj)
#endif /* LWMEM_CFG_ENABLE_STATS */
/**
* \brief LwMEM default structure used by application
*/
static lwmem_t lwmem_default;
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
/**
* \brief Get region aligned start address and aligned size
* \param[in] region: Region to check for size and address
@ -765,7 +765,7 @@ prv_assignmem(lwmem_t* lwobj, const lwmem_region_t* regions) {
return lwobj->mem_regions_count; /* Return number of regions used by manager */
}
#else /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#else /* LWMEM_CFG_FULL */
/**
* \brief Assign the regions for simple algorithm
@ -828,7 +828,7 @@ prv_alloc_simple(lwmem_t* const lwobj, const lwmem_region_t* region, const size_
return retval;
}
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#endif /* LWMEM_CFG_FULL */
/**
* \brief Initializes and assigns user regions for memory used by allocator algorithm
@ -858,11 +858,11 @@ lwmem_assignmem_ex(lwmem_t* lwobj, const lwmem_region_t* regions) {
/* Check first things first */
if (regions == NULL || (((size_t)LWMEM_CFG_ALIGN_NUM) & (((size_t)LWMEM_CFG_ALIGN_NUM) - 1)) > 0
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#if LWMEM_CFG_FULL
|| lwobj->end_block != NULL /* Init function may only be called once per lwmem instance */
#else
|| lwobj->is_initialized /* Already initialized? */
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#endif /* LWMEM_CFG_FULL */
) {
return 0;
}
@ -883,7 +883,7 @@ lwmem_assignmem_ex(lwmem_t* lwobj, const lwmem_region_t* regions) {
break;
}
#if !LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#if !LWMEM_CFG_FULL
/*
* In case of simple allocation algorithm, we (for now!) only allow one region.
* Return zero value if user passed more than one region in a sequence.
@ -891,7 +891,7 @@ lwmem_assignmem_ex(lwmem_t* lwobj, const lwmem_region_t* regions) {
else if (idx > 0) {
return 0;
}
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#endif /* LWMEM_CFG_FULL */
/* New region(s) must be higher (in address space) than previous one */
if ((mem_start_addr + mem_size) > LWMEM_TO_BYTE_PTR(regions[idx].start_addr)) {
@ -913,11 +913,11 @@ lwmem_assignmem_ex(lwmem_t* lwobj, const lwmem_region_t* regions) {
return 0;
}
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#if LWMEM_CFG_FULL
return prv_assignmem(lwobj, regions);
#else /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#else /* LWMEM_CFG_FULL */
return prv_assignmem_simple(lwobj, regions);
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#endif /* LWMEM_CFG_FULL */
}
/**
@ -937,11 +937,11 @@ lwmem_malloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t size)
lwobj = LWMEM_GET_LWOBJ(lwobj);
LWMEM_PROTECT(lwobj);
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#if LWMEM_CFG_FULL
ptr = prv_alloc(lwobj, region, size);
#else /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#else /* LWMEM_CFG_FULL */
ptr = prv_alloc_simple(lwobj, region, size);
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#endif /* LWMEM_CFG_FULL */
LWMEM_UNPROTECT(lwobj);
return ptr;
}
@ -969,11 +969,11 @@ lwmem_calloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t nitem
lwobj = LWMEM_GET_LWOBJ(lwobj);
LWMEM_PROTECT(lwobj);
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#if LWMEM_CFG_FULL
ptr = prv_alloc(lwobj, region, alloc_size);
#else /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#else /* LWMEM_CFG_FULL */
ptr = prv_alloc_simple(lwobj, region, alloc_size);
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#endif /* LWMEM_CFG_FULL */
LWMEM_UNPROTECT(lwobj);
if (ptr != NULL) {
@ -982,7 +982,7 @@ lwmem_calloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t nitem
return ptr;
}
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__
#if LWMEM_CFG_FULL || __DOXYGEN__
/**
* \brief Reallocates already allocated memory with new size in specific lwmem instance and region.
@ -1133,7 +1133,7 @@ lwmem_get_size_ex(lwmem_t* lwobj, void* ptr) {
return len;
}
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__ */
#endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__
@ -1203,7 +1203,7 @@ lwmem_calloc(size_t nitems, size_t size) {
return lwmem_calloc_ex(NULL, NULL, nitems, size);
}
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__
#if LWMEM_CFG_FULL || __DOXYGEN__
/**
* \note This is a wrapper for \ref lwmem_realloc_ex function.
@ -1268,12 +1268,12 @@ lwmem_get_size(void* ptr) {
return lwmem_get_size_ex(NULL, ptr);
}
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE || __DOXYGEN__ */
#endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
/* Part of library used ONLY for LWMEM_DEV purposes */
/* To validate and test library */
#if defined(LWMEM_DEV) && !__DOXYGEN__
#if defined(LWMEM_DEV) && LWMEM_CFG_FULL && !__DOXYGEN__
#include <stdio.h>
#include <stdlib.h>

View File

@ -1,7 +1,7 @@
#include <stdio.h>
#include "lwmem/lwmem.h"
#if LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#if LWMEM_CFG_FULL
/* Assert check */
#define ASSERT(x) \
@ -229,4 +229,4 @@ lwmem_test_memory_structure(void) {
(unsigned)rptr3, (unsigned)rptr4);
}
#endif /* LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#endif /* LWMEM_CFG_FULL */

View File

@ -1,7 +1,7 @@
#include <stdio.h>
#include "lwmem/lwmem.h"
#if !LWMEM_CFG_SUPPORT_REALLOC_AND_FREE
#if !LWMEM_CFG_FULL
/* Assert check */
#define ASSERT(x) \
@ -65,4 +65,4 @@ lwmem_test_simple_run(void) {
ASSERT(ptr == NULL);
}
#endif /* !LWMEM_CFG_SUPPORT_REALLOC_AND_FREE */
#endif /* !LWMEM_CFG_FULL */