mirror of
https://github.com/MaJerle/lwmem.git
synced 2025-01-26 06:02:54 +08:00
Change macro to LWMEM_CFG_FULL
This commit is contained in:
parent
14740ff4f5
commit
187bc462eb
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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__
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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>
|
||||
|
@ -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 */
|
@ -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 */
|
Loading…
x
Reference in New Issue
Block a user