From c2636559c26007da30bf084eb6bbe725d6d96c0b Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Mon, 21 Dec 2020 15:20:39 -0800 Subject: [PATCH 1/4] Add inline always option to HeapSelect --- cores/esp8266/umm_malloc/umm_heap_select.h | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cores/esp8266/umm_malloc/umm_heap_select.h b/cores/esp8266/umm_malloc/umm_heap_select.h index 4c9150819f..c0ddc31d9d 100644 --- a/cores/esp8266/umm_malloc/umm_heap_select.h +++ b/cores/esp8266/umm_malloc/umm_heap_select.h @@ -3,6 +3,18 @@ #include +#ifndef ALWAYS_INLINE +#define ALWAYS_INLINE inline __attribute__ ((always_inline)) +#endif + +// Use FORCE_ALWAYS_INLINE to ensure HeapSelect... construtor/deconstructor +// are placed in IRAM +#ifdef FORCE_ALWAYS_INLINE +#define MAYBE_ALWAYS_INLINE ALWAYS_INLINE +#else +#define MAYBE_ALWAYS_INLINE +#endif + /* This class is modeled after interrupts.h @@ -20,13 +32,17 @@ class HeapSelect { public: #if (UMM_NUM_HEAPS == 1) + MAYBE_ALWAYS_INLINE HeapSelect(size_t id) { (void)id; } + MAYBE_ALWAYS_INLINE ~HeapSelect() {} #else + MAYBE_ALWAYS_INLINE HeapSelect(size_t id) : _heap_id(umm_get_current_heap_id()) { umm_set_heap_by_id(id); } + MAYBE_ALWAYS_INLINE ~HeapSelect() { umm_set_heap_by_id(_heap_id); } @@ -39,10 +55,12 @@ class HeapSelect { class HeapSelectIram { public: #ifdef UMM_HEAP_IRAM + MAYBE_ALWAYS_INLINE HeapSelectIram() : _heap_id(umm_get_current_heap_id()) { umm_set_heap_by_id(UMM_HEAP_IRAM); } + MAYBE_ALWAYS_INLINE ~HeapSelectIram() { umm_set_heap_by_id(_heap_id); } @@ -51,7 +69,9 @@ class HeapSelectIram { size_t _heap_id; #else + MAYBE_ALWAYS_INLINE HeapSelectIram() {} + MAYBE_ALWAYS_INLINE ~HeapSelectIram() {} #endif }; @@ -59,13 +79,17 @@ class HeapSelectIram { class HeapSelectDram { public: #if (UMM_NUM_HEAPS == 1) + MAYBE_ALWAYS_INLINE HeapSelectDram() {} + MAYBE_ALWAYS_INLINE ~HeapSelectDram() {} #else + MAYBE_ALWAYS_INLINE HeapSelectDram() : _heap_id(umm_get_current_heap_id()) { umm_set_heap_by_id(UMM_HEAP_DRAM); } + MAYBE_ALWAYS_INLINE ~HeapSelectDram() { umm_set_heap_by_id(_heap_id); } From d1c4c4dfcded7f1ba89f678f0140f78dca6048d2 Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Mon, 21 Dec 2020 15:22:29 -0800 Subject: [PATCH 2/4] Add option to force DRAM for pvPort... APIs --- cores/esp8266/heap.cpp | 71 ++++++++++++++++++++--- cores/esp8266/umm_malloc/umm_malloc_cfg.h | 27 ++++----- 2 files changed, 77 insertions(+), 21 deletions(-) diff --git a/cores/esp8266/heap.cpp b/cores/esp8266/heap.cpp index 3f549716f4..c2473a0e45 100644 --- a/cores/esp8266/heap.cpp +++ b/cores/esp8266/heap.cpp @@ -5,6 +5,11 @@ #include #include "umm_malloc/umm_malloc.h" + +// Need FORCE_ALWAYS_INLINE to put HeapSelect class constructor/deconstructor in IRAM +#define FORCE_ALWAYS_INLINE +#include "umm_malloc/umm_heap_select.h" + #include #include #include @@ -16,6 +21,7 @@ extern "C" { #define UMM_CALLOC(n,s) umm_poison_calloc(n,s) #define UMM_REALLOC_FL(p,s,f,l) umm_poison_realloc_fl(p,s,f,l) #define UMM_FREE_FL(p,f,l) umm_poison_free_fl(p,f,l) +#define STATIC_ALWAYS_INLINE #undef realloc #undef free @@ -25,6 +31,7 @@ extern "C" { #define UMM_CALLOC(n,s) umm_calloc(n,s) #define UMM_REALLOC_FL(p,s,f,l) umm_realloc(p,s) #define UMM_FREE_FL(p,f,l) umm_free(p) +#define STATIC_ALWAYS_INLINE #undef realloc #undef free @@ -34,6 +41,10 @@ extern "C" { #define UMM_CALLOC(n,s) calloc(n,s) #define UMM_REALLOC_FL(p,s,f,l) realloc(p,s) #define UMM_FREE_FL(p,f,l) free(p) + +// STATIC_ALWAYS_INLINE only applys to the non-debug build path, +// it must not be enabled on the debug build path. +#define STATIC_ALWAYS_INLINE static ALWAYS_INLINE #endif @@ -164,8 +175,8 @@ void ICACHE_RAM_ATTR print_loc(size_t size, const char* file, int line) if (inISR && (uint32_t)file >= 0x40200000) { DEBUG_HEAP_PRINTF("File: %p", file); } else if (!inISR && (uint32_t)file >= 0x40200000) { - char buf[ets_strlen(file) + 1] __attribute__((aligned(4))); - ets_strcpy(buf, file); + char buf[strlen_P(file) + 1]; + strcpy_P(buf, file); DEBUG_HEAP_PRINTF(buf); } else { DEBUG_HEAP_PRINTF(file); @@ -259,8 +270,8 @@ void ICACHE_RAM_ATTR free(void* p) } #endif - -void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line) +STATIC_ALWAYS_INLINE +void* ICACHE_RAM_ATTR heap_pvPortMalloc(size_t size, const char* file, int line) { INTEGRITY_CHECK__PANIC_FL(file, line); POISON_CHECK__PANIC_FL(file, line); @@ -270,7 +281,8 @@ void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line) return ret; } -void* ICACHE_RAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line) +STATIC_ALWAYS_INLINE +void* ICACHE_RAM_ATTR heap_pvPortCalloc(size_t count, size_t size, const char* file, int line) { INTEGRITY_CHECK__PANIC_FL(file, line); POISON_CHECK__PANIC_FL(file, line); @@ -280,7 +292,8 @@ void* ICACHE_RAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, return ret; } -void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line) +STATIC_ALWAYS_INLINE +void* ICACHE_RAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line) { INTEGRITY_CHECK__PANIC_FL(file, line); void* ret = UMM_REALLOC_FL(ptr, size, file, line); @@ -290,7 +303,8 @@ void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, in return ret; } -void* ICACHE_RAM_ATTR pvPortZalloc(size_t size, const char* file, int line) +STATIC_ALWAYS_INLINE +void* ICACHE_RAM_ATTR heap_pvPortZalloc(size_t size, const char* file, int line) { INTEGRITY_CHECK__PANIC_FL(file, line); POISON_CHECK__PANIC_FL(file, line); @@ -300,7 +314,8 @@ void* ICACHE_RAM_ATTR pvPortZalloc(size_t size, const char* file, int line) return ret; } -void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line) +STATIC_ALWAYS_INLINE +void ICACHE_RAM_ATTR heap_vPortFree(void *ptr, const char* file, int line) { INTEGRITY_CHECK__PANIC_FL(file, line); UMM_FREE_FL(ptr, file, line); @@ -314,7 +329,47 @@ size_t ICACHE_RAM_ATTR xPortWantedSizeAlign(size_t size) void system_show_malloc(void) { + HeapSelectDram ephemeral; umm_info(NULL, true); } +/* + NONOS SDK and lwIP do not handle IRAM heap well. Since they also use portable + malloc calls pvPortMalloc, ... we can leverage that for this solution. + Force pvPortMalloc, ... APIs to serve DRAM only. +*/ +void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line) +{ + HeapSelectDram ephemeral; + return heap_pvPortMalloc(size, file, line);; +} + +void* ICACHE_RAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line) +{ + HeapSelectDram ephemeral; + return heap_pvPortCalloc(count, size, file, line); +} + +void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line) +{ + HeapSelectDram ephemeral; + return heap_pvPortRealloc(ptr, size, file, line); +} + +void* ICACHE_RAM_ATTR pvPortZalloc(size_t size, const char* file, int line) +{ + HeapSelectDram ephemeral; + return heap_pvPortZalloc(size, file, line); +} + +void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line) +{ +#if defined(DEBUG_ESP_OOM) || defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE) || defined(UMM_INTEGRITY_CHECK) + // This is only needed for debug checks to ensure they are performed in + // correct context. umm_malloc free internally determines the correct heap. + HeapSelectDram ephemeral; +#endif + return heap_vPortFree(ptr, file, line); +} + }; diff --git a/cores/esp8266/umm_malloc/umm_malloc_cfg.h b/cores/esp8266/umm_malloc/umm_malloc_cfg.h index 1e5d7f8003..4fc059a49c 100644 --- a/cores/esp8266/umm_malloc/umm_malloc_cfg.h +++ b/cores/esp8266/umm_malloc/umm_malloc_cfg.h @@ -792,28 +792,29 @@ extern "C" { // Arduino.h recall us to redefine them #include // Reuse pvPort* calls, since they already support passing location information. -void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line); -void* ICACHE_RAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line); -void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line); -void* ICACHE_RAM_ATTR pvPortZalloc(size_t size, const char* file, int line); -void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line); +// Specificly the debug version (heap_...) that does not force DRAM heap. +void* ICACHE_RAM_ATTR heap_pvPortMalloc(size_t size, const char* file, int line); +void* ICACHE_RAM_ATTR heap_pvPortCalloc(size_t count, size_t size, const char* file, int line); +void* ICACHE_RAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line); +void* ICACHE_RAM_ATTR heap_pvPortZalloc(size_t size, const char* file, int line); +void ICACHE_RAM_ATTR heap_vPortFree(void *ptr, const char* file, int line); -#define malloc(s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; pvPortMalloc(s, mem_debug_file, __LINE__); }) -#define calloc(n,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; pvPortCalloc(n, s, mem_debug_file, __LINE__); }) -#define realloc(p,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; pvPortRealloc(p, s, mem_debug_file, __LINE__); }) +#define malloc(s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortMalloc(s, mem_debug_file, __LINE__); }) +#define calloc(n,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortCalloc(n, s, mem_debug_file, __LINE__); }) +#define realloc(p,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortRealloc(p, s, mem_debug_file, __LINE__); }) #if defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE) -#define dbg_heap_free(p) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; vPortFree(p, mem_debug_file, __LINE__); }) +#define dbg_heap_free(p) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_vPortFree(p, mem_debug_file, __LINE__); }) #else #define dbg_heap_free(p) free(p) #endif #elif defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE) #include -void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line); -#define realloc(p,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; pvPortRealloc(p, s, mem_debug_file, __LINE__); }) +void* ICACHE_RAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line); +#define realloc(p,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortRealloc(p, s, mem_debug_file, __LINE__); }) -void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line); +void ICACHE_RAM_ATTR heap_vPortFree(void *ptr, const char* file, int line); //C - to be discussed /* Problem, I would like to report the file and line number with the umm poison @@ -828,7 +829,7 @@ void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line); Create dbg_heap_free() as an alternative for free() when you need a little more help in debugging the more challenging problems. */ -#define dbg_heap_free(p) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; vPortFree(p, mem_debug_file, __LINE__); }) +#define dbg_heap_free(p) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_vPortFree(p, mem_debug_file, __LINE__); }) #else #define dbg_heap_free(p) free(p) From 4777cfa5021502696f28535e777e504b7c4033a7 Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Tue, 22 Dec 2020 14:51:34 -0800 Subject: [PATCH 3/4] revert print_loc premature change --- cores/esp8266/heap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp8266/heap.cpp b/cores/esp8266/heap.cpp index c2473a0e45..2be2499ea0 100644 --- a/cores/esp8266/heap.cpp +++ b/cores/esp8266/heap.cpp @@ -175,8 +175,8 @@ void ICACHE_RAM_ATTR print_loc(size_t size, const char* file, int line) if (inISR && (uint32_t)file >= 0x40200000) { DEBUG_HEAP_PRINTF("File: %p", file); } else if (!inISR && (uint32_t)file >= 0x40200000) { - char buf[strlen_P(file) + 1]; - strcpy_P(buf, file); + char buf[ets_strlen(file) + 1] __attribute__((aligned(4))); + ets_strcpy(buf, file); DEBUG_HEAP_PRINTF(buf); } else { DEBUG_HEAP_PRINTF(file); From 0e80628ed096ff573ecf45401dab5029c6f853b2 Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Wed, 23 Dec 2020 08:50:23 -0800 Subject: [PATCH 4/4] Renamed macro to be more specific, FORCE_ALWAYS_INLINE to FORCE_ALWAYS_INLINE_HEAP_SELECT --- cores/esp8266/heap.cpp | 2 +- cores/esp8266/umm_malloc/umm_heap_select.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp8266/heap.cpp b/cores/esp8266/heap.cpp index 2be2499ea0..4821f9b772 100644 --- a/cores/esp8266/heap.cpp +++ b/cores/esp8266/heap.cpp @@ -7,7 +7,7 @@ #include "umm_malloc/umm_malloc.h" // Need FORCE_ALWAYS_INLINE to put HeapSelect class constructor/deconstructor in IRAM -#define FORCE_ALWAYS_INLINE +#define FORCE_ALWAYS_INLINE_HEAP_SELECT #include "umm_malloc/umm_heap_select.h" #include diff --git a/cores/esp8266/umm_malloc/umm_heap_select.h b/cores/esp8266/umm_malloc/umm_heap_select.h index c0ddc31d9d..1a3728d7aa 100644 --- a/cores/esp8266/umm_malloc/umm_heap_select.h +++ b/cores/esp8266/umm_malloc/umm_heap_select.h @@ -9,7 +9,7 @@ // Use FORCE_ALWAYS_INLINE to ensure HeapSelect... construtor/deconstructor // are placed in IRAM -#ifdef FORCE_ALWAYS_INLINE +#ifdef FORCE_ALWAYS_INLINE_HEAP_SELECT #define MAYBE_ALWAYS_INLINE ALWAYS_INLINE #else #define MAYBE_ALWAYS_INLINE pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy