Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 4863

SDK • Re: Proper way to get Heap size

$
0
0
What does this do?

Code:

&__HeapLimit - &__end__// Assumes you use up to 4K stacks per core(&__StackOneTop - (10 * 1024)) - &__end__// If you clobber
It looks like the globals are at low addresses growing up. The heap is on top of that growing up. The stack is at high addresses growing down.

You have 2K stacks allocated for each core. You plan to clobber core1 or allocate on heap?
I did try that it gives 468940 this seems correct. I was allocating a huge array to use for memory.

I've reversed the stacks positions so core one is at the end of memory and core zero can "safely" overflow. I tried but couldn't work out how to extend the stack size. This effort was a quite awhile ago now the result of was working out how to reverse the stacks.
Heap Size: 4294957056
It looks like an integer overflow, probably negative subtraction result seen as unsigned.

Could you explain this formula ?
printf("Heap size %u bytes\r\n", ((&__StackLimit - (10 * 1024)) - &__HeapLimit));
P.S.
4294957056 = 0xFFFFD800 = -10240 = - (10 * 1024)
&__StackLimit = &__HeapLimit


I mentioned in my port that it was the -10k and something had gone wrong. The formula I don't remember how I came up with it, I was trying to replace pico_malloc with a custom allocator. &__HeapLimit was the address used for the start of heap. It's simpler to include the wrapper code

Code:

#include <stdlib.h>#include <stdio.h>#include "pico.h"#ifndef USE_MALLOC_MUTEX#define USE_MALLOC_MUTEX 1#include "pico/mutex.h"auto_init_mutex(malloc_mutex);#endif#include "umm_malloc.h"#include "umm_malloc_cfg.h"   // Override with umm_malloc_cfg_xxx.hextern char __StackLimit; /* Set by linker.  */extern char __HeapLimit;#ifndef STACK_EXTEND#define STACK_EXTEND 14#endif#define __HEAP_UPPER (&__StackLimit - (STACK_EXTEND * 1024))void *UMM_MALLOC_CFG_HEAP_ADDR = &__HeapLimit;uint32_t UMM_MALLOC_CFG_HEAP_SIZE = 0;static void stackoverflow_check() {#if 1    register char *sp asm("sp");    int r = sp - __HEAP_UPPER;    if (r < 0) panic ("STACK OVERFLOW  [%d bytes]  sp = 0x%p, __StackLimit = 0x%p __HEAP_UPPER = 0x%p", r, sp, &__StackLimit, __HEAP_UPPER);#endif}static inline void check_alloc(__unused void *mem, __unused uint size) {#if UMM_POISON_CHECK    if (umm_poison_check() == false) {        panic("Heap poisoned");    }#endif#if UMM_INTEGRITY_CHECK    if(umm_integrity_check() == 0) {        panic("Heap integrity check failed");    }#endif    if (!mem || (((char *)mem) + size) > __HEAP_UPPER)    {        panic("Out of memory");    }    stackoverflow_check();    // if (((&__StackLimit - (char*)&mem) + size) > ((&__StackLimit - &__HeapLimit) - (1024 * 20))) puts("LOW WATER WATNING!");    // (0x20040000 - 0x2001649C); (0x20040000 - 0x200126f0); (186640 - 170852);}void *__wrap_malloc(size_t size) {#if USE_MALLOC_MUTEX    mutex_enter_blocking(&malloc_mutex);#endif#if UMM_POISON_CHECK    void *rc = umm_poison_malloc(size);#else    void *rc = umm_malloc(size);#endif#if USE_MALLOC_MUTEX    mutex_exit(&malloc_mutex);#endif#if PICO_DEBUG_MALLOC    if (!rc || ((uint8_t *)rc) + size > (uint8_t*)PICO_DEBUG_MALLOC_LOW_WATER) {        printf("malloc %d %p->%p\n", (uint) size, rc, ((uint8_t *) rc) + size);    }#endif#if MEM_DEBUG_MALLOC    printf("umm_malloc %d %p->%p\n", (uint) size, rc, ((uint8_t *) rc) + size);#endif    check_alloc(rc, size);    return rc;}void *__wrap_calloc(size_t count, size_t size) {#if USE_MALLOC_MUTEX    mutex_enter_blocking(&malloc_mutex);#endif#if UMM_POISON_CHECK    void *rc = umm_poison_calloc(count, size);#else    void *rc = umm_calloc(count, size);#endif#if USE_MALLOC_MUTEX    mutex_exit(&malloc_mutex);#endif#if PICO_DEBUG_MALLOC    if (!rc || ((uint8_t *)rc) + size > (uint8_t*)PICO_DEBUG_MALLOC_LOW_WATER) {        printf("calloc %d %p->%p\n", (uint) (count * size), rc, ((uint8_t *) rc) + size);    }#endif#if MEM_DEBUG_MALLOC        printf("umm_calloc %d %p->%p\n", (uint) (count * size), rc, ((uint8_t *) rc) + size);#endif    check_alloc(rc, size);    return rc;}void *__wrap_realloc(void *mem, size_t size) {#if USE_MALLOC_MUTEX    mutex_enter_blocking(&malloc_mutex);#endif#if UMM_POISON_CHECK    void *rc = umm_poison_realloc(mem, size);#else    void *rc = umm_realloc(mem, size);#endif#if USE_MALLOC_MUTEX    mutex_exit(&malloc_mutex);#endif#if PICO_DEBUG_MALLOC    if (!rc || ((uint8_t *)rc) + size > (uint8_t*)PICO_DEBUG_MALLOC_LOW_WATER) {        printf("realloc %p %d->%p\n", mem, (uint) size, rc);    }#endif#if MEM_DEBUG_MALLOC        printf("umm_realloc %p %d->%p\n", mem, (uint) size, rc);#endif    check_alloc(rc, size);    return rc;}void __wrap_free(void *mem) {#if USE_MALLOC_MUTEX    mutex_enter_blocking(&malloc_mutex);#endif#if UMM_POISON_CHECK    umm_poison_free(mem);#else    umm_free(mem);#endif#if USE_MALLOC_MUTEX    mutex_exit(&malloc_mutex);#endif}void init_memory(){    UMM_MALLOC_CFG_HEAP_SIZE = (__HEAP_UPPER - &__HeapLimit);    umm_init();}
I could be wrong but I think this is the basics of pico_malloc only I'm using umm_malloc to look after the memory I liked it so much because it can maintain more than one heap.

I haven't tried to compile for the RP2040 to see what is different, all I know right now is that with the allocator loaded the code doesn't work I'm not sure if we have an access violation or what. If I could keep core 1 running even where core 0 has panics then I might be able to see.

Statistics: Posted by DarkElvenAngel — Sat Dec 21, 2024 12:55 am



Viewing all articles
Browse latest Browse all 4863

Trending Articles