Skip to content

Commit

Permalink
Merge branch 'zlo/allocator-playground' of https://github.com/flipper…
Browse files Browse the repository at this point in the history
  • Loading branch information
Willy-JL committed Apr 9, 2024
2 parents 01c55c7 + f1e6de7 commit d81e72d
Show file tree
Hide file tree
Showing 18 changed files with 334 additions and 613 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@
[submodule "documentation/doxygen/doxygen-awesome-css"]
path = documentation/doxygen/doxygen-awesome-css
url = https://github.com/jothepro/doxygen-awesome-css.git
[submodule "lib/tlsf"]
path = lib/tlsf
url = https://github.com/espressif/tlsf
2 changes: 1 addition & 1 deletion .pvsoptions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/microtar -e lib/mlib -e lib/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e lib/mjs -e */arm-none-eabi/*
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -e lib/tlsf -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/microtar -e lib/mlib -e lib/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e lib/mjs -e */arm-none-eabi/*
48 changes: 45 additions & 3 deletions applications/services/cli/cli_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,16 +435,58 @@ void cli_command_free(Cli* cli, FuriString* args, void* context) {
printf("Minimum heap size: %zu\r\n", memmgr_get_minimum_free_heap());
printf("Maximum heap block: %zu\r\n", memmgr_heap_get_max_free_block());

printf("Pool free: %zu\r\n", memmgr_pool_get_free());
printf("Maximum pool block: %zu\r\n", memmgr_pool_get_max_block());
printf("Aux pool total free: %zu\r\n", memmgr_aux_pool_get_free());
printf("Aux pool max free block: %zu\r\n", memmgr_pool_get_max_block());
}

typedef struct {
void* addr;
size_t size;
} FreeBlockInfo;

#define FREE_BLOCK_INFO_MAX 128

typedef struct {
FreeBlockInfo free_blocks[FREE_BLOCK_INFO_MAX];
size_t free_blocks_count;
} FreeBlockContext;

static bool free_block_walker(void* pointer, size_t size, bool used, void* context) {
FreeBlockContext* free_blocks = (FreeBlockContext*)context;
if(!used) {
if(free_blocks->free_blocks_count < FREE_BLOCK_INFO_MAX) {
free_blocks->free_blocks[free_blocks->free_blocks_count].addr = pointer;
free_blocks->free_blocks[free_blocks->free_blocks_count].size = size;
free_blocks->free_blocks_count++;
} else {
return false;
}
}
return true;
}

void cli_command_free_blocks(Cli* cli, FuriString* args, void* context) {
UNUSED(cli);
UNUSED(args);
UNUSED(context);

memmgr_heap_printf_free_blocks();
FreeBlockContext* free_blocks = malloc(sizeof(FreeBlockContext));
free_blocks->free_blocks_count = 0;

memmgr_heap_walk_blocks(free_block_walker, free_blocks);

for(size_t i = 0; i < free_blocks->free_blocks_count; i++) {
printf(
"A %p S %zu\r\n",
(void*)free_blocks->free_blocks[i].addr,
free_blocks->free_blocks[i].size);
}

if(free_blocks->free_blocks_count == FREE_BLOCK_INFO_MAX) {
printf("... and more\r\n");
}

free(free_blocks);
}

void cli_command_i2c(Cli* cli, FuriString* args, void* context) {
Expand Down
39 changes: 9 additions & 30 deletions furi/core/memmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <furi_hal_memory.h>

extern void* pvPortMalloc(size_t xSize);
extern void* pvPortAllocAligned(size_t xSize, size_t xAlignment);
extern void* pvPortRealloc(void* pv, size_t xSize);
extern void vPortFree(void* pv);
extern size_t xPortGetFreeHeapSize(void);
extern size_t xPortGetTotalHeapSize(void);
Expand All @@ -18,18 +20,7 @@ void free(void* ptr) {
}

void* realloc(void* ptr, size_t size) {
if(size == 0) {
vPortFree(ptr);
return NULL;
}

void* p = pvPortMalloc(size);
if(ptr != NULL) {
memcpy(p, ptr, size);
vPortFree(ptr);
}

return p;
return pvPortRealloc(ptr, size);
}

void* calloc(size_t count, size_t size) {
Expand All @@ -47,6 +38,10 @@ char* strdup(const char* s) {
return y;
}

void* aligned_alloc(size_t alignment, size_t size) {
return pvPortAllocAligned(size, alignment);
}

size_t memmgr_get_free_heap(void) {
return xPortGetFreeHeapSize();
}
Expand Down Expand Up @@ -79,33 +74,17 @@ void* __wrap__realloc_r(struct _reent* r, void* ptr, size_t size) {
return realloc(ptr, size);
}

void* memmgr_alloc_from_pool(size_t size) {
void* memmgr_aux_pool_alloc(size_t size) {
void* p = furi_hal_memory_alloc(size);
if(p == NULL) p = malloc(size);

return p;
}

size_t memmgr_pool_get_free(void) {
size_t memmgr_aux_pool_get_free(void) {
return furi_hal_memory_get_free();
}

size_t memmgr_pool_get_max_block(void) {
return furi_hal_memory_max_pool_block();
}

void* aligned_malloc(size_t size, size_t alignment) {
void* p1; // original block
void** p2; // aligned block
int offset = alignment - 1 + sizeof(void*);
if((p1 = (void*)malloc(size + offset)) == NULL) {
return NULL;
}
p2 = (void**)(((size_t)(p1) + offset) & ~(alignment - 1));
p2[-1] = p1;
return p2;
}

void aligned_free(void* p) {
free(((void**)p)[-1]);
}
25 changes: 5 additions & 20 deletions furi/core/memmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,37 +36,22 @@ size_t memmgr_get_total_heap(void);
size_t memmgr_get_minimum_free_heap(void);

/**
* An aligned version of malloc, used when you need to get the aligned space on the heap
* Freeing the received address is performed ONLY through the aligned_free function
* @param size
* @param alignment
* @return void*
*/
void* aligned_malloc(size_t size, size_t alignment);

/**
* Freed space obtained through the aligned_malloc function
* @param p pointer to result of aligned_malloc
*/
void aligned_free(void* p);

/**
* @brief Allocate memory from separate memory pool. That memory can't be freed.
* @brief Allocate memory from the auxiliary memory pool. That memory can't be freed.
*
* @param size
* @return void*
*/
void* memmgr_alloc_from_pool(size_t size);
void* memmgr_aux_pool_alloc(size_t size);

/**
* @brief Get free memory pool size
* @brief Get the auxiliary pool free memory size
*
* @return size_t
*/
size_t memmgr_pool_get_free(void);
size_t memmgr_aux_pool_get_free(void);

/**
* @brief Get max free block size from memory pool
* @brief Get max free block size from the auxiliary memory pool
*
* @return size_t
*/
Expand Down
Loading

0 comments on commit d81e72d

Please sign in to comment.