Enable a simple malloc implementation which will minimize memory usage prior relocation. This is essential as memory available prior location is internal memory and limited in size.
This implementation will stored last 2 usage of malloc. When free is invoked and the free address matched, we shall revert to previous value of gd->malloc_ptr that we stored. Signed-off-by: Chin Liang See <cl...@altera.com> Cc: Marek Vasut <ma...@denx.de> Cc: Simon Glass <s...@chromium.org> Cc: Tom Rini <tr...@konsulko.com> Cc: Dinh Nguyen <dingu...@opensource.altera.com> Cc: Tien Fong Chee <tfc...@altera.com> --- common/dlmalloc.c | 6 ++++-- common/malloc_simple.c | 34 ++++++++++++++++++++++++++++++++++ include/asm-generic/global_data.h | 2 ++ include/malloc.h | 3 ++- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/common/dlmalloc.c b/common/dlmalloc.c index adc680e..ba42d0d 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -1523,9 +1523,11 @@ void fREe(mem) Void_t* mem; int islr; /* track whether merging with last_remainder */ #ifdef CONFIG_SYS_MALLOC_F_LEN - /* free() is a no-op - all the memory will be freed on relocation */ - if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) + /* Invoke free_simple. All the memory will be freed on relocation */ + if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) { + free_simple(mem); return; + } #endif if (mem == NULL) /* free(0) has no effect */ diff --git a/common/malloc_simple.c b/common/malloc_simple.c index 0f6bcbc..383a546 100644 --- a/common/malloc_simple.c +++ b/common/malloc_simple.c @@ -26,6 +26,18 @@ void *malloc_simple(size_t bytes) return NULL; } ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes); + + /* implement a simple free mechanism which stored last 2 usage */ + if (gd->malloc_free_addr[0] != 0) { + /* shifting as we are storing depth of 2 */ + gd->malloc_free_addr[1] = gd->malloc_free_addr[0]; + gd->malloc_free_ptr[1] = gd->malloc_free_ptr[0]; + } + /* saving last malloc address for malloc free */ + gd->malloc_free_addr[0] = ptr; + /* saving last malloc_ptr prior allocation for malloc free */ + gd->malloc_free_ptr[0] = gd->malloc_ptr; + gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr)); debug("%lx\n", (ulong)ptr); @@ -42,6 +54,18 @@ void *memalign_simple(size_t align, size_t bytes) if (new_ptr > gd->malloc_limit) return NULL; ptr = map_sysmem(addr, bytes); + + /* implement a simple free mechanism which stored last 2 usage */ + if (gd->malloc_free_addr[0] != 0) { + /* shifting as we are storing depth of 2 */ + gd->malloc_free_addr[1] = gd->malloc_free_addr[0]; + gd->malloc_free_ptr[1] = gd->malloc_free_ptr[0]; + } + /* saving last malloc address for malloc free */ + gd->malloc_free_addr[0] = ptr; + /* saving last malloc_ptr prior allocation for malloc free */ + gd->malloc_free_ptr[0] = gd->malloc_ptr; + gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr)); return ptr; @@ -59,3 +83,13 @@ void *calloc(size_t nmemb, size_t elem_size) return ptr; } #endif + +void free_simple(Void_t* mem) +{ + if (mem == gd->malloc_free_addr[0]) { + gd->malloc_ptr = gd->malloc_free_ptr[0]; + /* shifting as we are storing depth of 2 */ + gd->malloc_free_addr[0] = gd->malloc_free_addr[1]; + gd->malloc_free_ptr[0] = gd->malloc_free_ptr[1]; + } +} diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index a6d1d2a..9380772 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -90,6 +90,8 @@ typedef struct global_data { unsigned long malloc_base; /* base address of early malloc() */ unsigned long malloc_limit; /* limit address */ unsigned long malloc_ptr; /* current address */ + void *malloc_free_addr[2]; /* Last malloc pointer address*/ + unsigned long malloc_free_ptr[2]; /* Last malloc_ptr */ #endif #ifdef CONFIG_PCI struct pci_controller *hose; /* PCI hose for early use */ diff --git a/include/malloc.h b/include/malloc.h index 8175c75..02651aa 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -876,7 +876,7 @@ extern Void_t* sbrk(); #define malloc malloc_simple #define realloc realloc_simple #define memalign memalign_simple -static inline void free(void *ptr) {} +#define free free_simple void *calloc(size_t nmemb, size_t size); void *memalign_simple(size_t alignment, size_t bytes); void *realloc_simple(void *ptr, size_t size); @@ -913,6 +913,7 @@ int initf_malloc(void); /* Simple versions which can be used when space is tight */ void *malloc_simple(size_t size); +void free_simple(Void_t* mem); #pragma GCC visibility push(hidden) # if __STD_C -- 2.2.2 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot