Skip to content

Commit df5e113

Browse files
authored
HeapSelectDram for pvPortMalloc, ... (#7790)
* Add inline always option to HeapSelect * Add option to force DRAM for pvPort... APIs * revert print_loc premature change * Renamed macro to be more specific, FORCE_ALWAYS_INLINE to FORCE_ALWAYS_INLINE_HEAP_SELECT
1 parent e938739 commit df5e113

File tree

3 files changed

+99
-19
lines changed

3 files changed

+99
-19
lines changed

cores/esp8266/heap.cpp

+61-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55

66
#include <stdlib.h>
77
#include "umm_malloc/umm_malloc.h"
8+
9+
// Need FORCE_ALWAYS_INLINE to put HeapSelect class constructor/deconstructor in IRAM
10+
#define FORCE_ALWAYS_INLINE_HEAP_SELECT
11+
#include "umm_malloc/umm_heap_select.h"
12+
813
#include <c_types.h>
914
#include <sys/reent.h>
1015
#include <user_interface.h>
@@ -16,6 +21,7 @@ extern "C" {
1621
#define UMM_CALLOC(n,s) umm_poison_calloc(n,s)
1722
#define UMM_REALLOC_FL(p,s,f,l) umm_poison_realloc_fl(p,s,f,l)
1823
#define UMM_FREE_FL(p,f,l) umm_poison_free_fl(p,f,l)
24+
#define STATIC_ALWAYS_INLINE
1925

2026
#undef realloc
2127
#undef free
@@ -25,6 +31,7 @@ extern "C" {
2531
#define UMM_CALLOC(n,s) umm_calloc(n,s)
2632
#define UMM_REALLOC_FL(p,s,f,l) umm_realloc(p,s)
2733
#define UMM_FREE_FL(p,f,l) umm_free(p)
34+
#define STATIC_ALWAYS_INLINE
2835

2936
#undef realloc
3037
#undef free
@@ -34,6 +41,10 @@ extern "C" {
3441
#define UMM_CALLOC(n,s) calloc(n,s)
3542
#define UMM_REALLOC_FL(p,s,f,l) realloc(p,s)
3643
#define UMM_FREE_FL(p,f,l) free(p)
44+
45+
// STATIC_ALWAYS_INLINE only applys to the non-debug build path,
46+
// it must not be enabled on the debug build path.
47+
#define STATIC_ALWAYS_INLINE static ALWAYS_INLINE
3748
#endif
3849

3950

@@ -259,8 +270,8 @@ void ICACHE_RAM_ATTR free(void* p)
259270
}
260271
#endif
261272

262-
263-
void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line)
273+
STATIC_ALWAYS_INLINE
274+
void* ICACHE_RAM_ATTR heap_pvPortMalloc(size_t size, const char* file, int line)
264275
{
265276
INTEGRITY_CHECK__PANIC_FL(file, line);
266277
POISON_CHECK__PANIC_FL(file, line);
@@ -270,7 +281,8 @@ void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line)
270281
return ret;
271282
}
272283

273-
void* ICACHE_RAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line)
284+
STATIC_ALWAYS_INLINE
285+
void* ICACHE_RAM_ATTR heap_pvPortCalloc(size_t count, size_t size, const char* file, int line)
274286
{
275287
INTEGRITY_CHECK__PANIC_FL(file, line);
276288
POISON_CHECK__PANIC_FL(file, line);
@@ -280,7 +292,8 @@ void* ICACHE_RAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file,
280292
return ret;
281293
}
282294

283-
void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line)
295+
STATIC_ALWAYS_INLINE
296+
void* ICACHE_RAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line)
284297
{
285298
INTEGRITY_CHECK__PANIC_FL(file, line);
286299
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
290303
return ret;
291304
}
292305

293-
void* ICACHE_RAM_ATTR pvPortZalloc(size_t size, const char* file, int line)
306+
STATIC_ALWAYS_INLINE
307+
void* ICACHE_RAM_ATTR heap_pvPortZalloc(size_t size, const char* file, int line)
294308
{
295309
INTEGRITY_CHECK__PANIC_FL(file, line);
296310
POISON_CHECK__PANIC_FL(file, line);
@@ -300,7 +314,8 @@ void* ICACHE_RAM_ATTR pvPortZalloc(size_t size, const char* file, int line)
300314
return ret;
301315
}
302316

303-
void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line)
317+
STATIC_ALWAYS_INLINE
318+
void ICACHE_RAM_ATTR heap_vPortFree(void *ptr, const char* file, int line)
304319
{
305320
INTEGRITY_CHECK__PANIC_FL(file, line);
306321
UMM_FREE_FL(ptr, file, line);
@@ -314,7 +329,47 @@ size_t ICACHE_RAM_ATTR xPortWantedSizeAlign(size_t size)
314329

315330
void system_show_malloc(void)
316331
{
332+
HeapSelectDram ephemeral;
317333
umm_info(NULL, true);
318334
}
319335

336+
/*
337+
NONOS SDK and lwIP do not handle IRAM heap well. Since they also use portable
338+
malloc calls pvPortMalloc, ... we can leverage that for this solution.
339+
Force pvPortMalloc, ... APIs to serve DRAM only.
340+
*/
341+
void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line)
342+
{
343+
HeapSelectDram ephemeral;
344+
return heap_pvPortMalloc(size, file, line);;
345+
}
346+
347+
void* ICACHE_RAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line)
348+
{
349+
HeapSelectDram ephemeral;
350+
return heap_pvPortCalloc(count, size, file, line);
351+
}
352+
353+
void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line)
354+
{
355+
HeapSelectDram ephemeral;
356+
return heap_pvPortRealloc(ptr, size, file, line);
357+
}
358+
359+
void* ICACHE_RAM_ATTR pvPortZalloc(size_t size, const char* file, int line)
360+
{
361+
HeapSelectDram ephemeral;
362+
return heap_pvPortZalloc(size, file, line);
363+
}
364+
365+
void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line)
366+
{
367+
#if defined(DEBUG_ESP_OOM) || defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE) || defined(UMM_INTEGRITY_CHECK)
368+
// This is only needed for debug checks to ensure they are performed in
369+
// correct context. umm_malloc free internally determines the correct heap.
370+
HeapSelectDram ephemeral;
371+
#endif
372+
return heap_vPortFree(ptr, file, line);
373+
}
374+
320375
};

cores/esp8266/umm_malloc/umm_heap_select.h

+24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33

44
#include <umm_malloc/umm_malloc.h>
55

6+
#ifndef ALWAYS_INLINE
7+
#define ALWAYS_INLINE inline __attribute__ ((always_inline))
8+
#endif
9+
10+
// Use FORCE_ALWAYS_INLINE to ensure HeapSelect... construtor/deconstructor
11+
// are placed in IRAM
12+
#ifdef FORCE_ALWAYS_INLINE_HEAP_SELECT
13+
#define MAYBE_ALWAYS_INLINE ALWAYS_INLINE
14+
#else
15+
#define MAYBE_ALWAYS_INLINE
16+
#endif
17+
618
/*
719
This class is modeled after interrupts.h
820
@@ -20,13 +32,17 @@
2032
class HeapSelect {
2133
public:
2234
#if (UMM_NUM_HEAPS == 1)
35+
MAYBE_ALWAYS_INLINE
2336
HeapSelect(size_t id) { (void)id; }
37+
MAYBE_ALWAYS_INLINE
2438
~HeapSelect() {}
2539
#else
40+
MAYBE_ALWAYS_INLINE
2641
HeapSelect(size_t id) : _heap_id(umm_get_current_heap_id()) {
2742
umm_set_heap_by_id(id);
2843
}
2944

45+
MAYBE_ALWAYS_INLINE
3046
~HeapSelect() {
3147
umm_set_heap_by_id(_heap_id);
3248
}
@@ -39,10 +55,12 @@ class HeapSelect {
3955
class HeapSelectIram {
4056
public:
4157
#ifdef UMM_HEAP_IRAM
58+
MAYBE_ALWAYS_INLINE
4259
HeapSelectIram() : _heap_id(umm_get_current_heap_id()) {
4360
umm_set_heap_by_id(UMM_HEAP_IRAM);
4461
}
4562

63+
MAYBE_ALWAYS_INLINE
4664
~HeapSelectIram() {
4765
umm_set_heap_by_id(_heap_id);
4866
}
@@ -51,21 +69,27 @@ class HeapSelectIram {
5169
size_t _heap_id;
5270

5371
#else
72+
MAYBE_ALWAYS_INLINE
5473
HeapSelectIram() {}
74+
MAYBE_ALWAYS_INLINE
5575
~HeapSelectIram() {}
5676
#endif
5777
};
5878

5979
class HeapSelectDram {
6080
public:
6181
#if (UMM_NUM_HEAPS == 1)
82+
MAYBE_ALWAYS_INLINE
6283
HeapSelectDram() {}
84+
MAYBE_ALWAYS_INLINE
6385
~HeapSelectDram() {}
6486
#else
87+
MAYBE_ALWAYS_INLINE
6588
HeapSelectDram() : _heap_id(umm_get_current_heap_id()) {
6689
umm_set_heap_by_id(UMM_HEAP_DRAM);
6790
}
6891

92+
MAYBE_ALWAYS_INLINE
6993
~HeapSelectDram() {
7094
umm_set_heap_by_id(_heap_id);
7195
}

cores/esp8266/umm_malloc/umm_malloc_cfg.h

+14-13
Original file line numberDiff line numberDiff line change
@@ -792,28 +792,29 @@ extern "C" {
792792
// Arduino.h recall us to redefine them
793793
#include <pgmspace.h>
794794
// Reuse pvPort* calls, since they already support passing location information.
795-
void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line);
796-
void* ICACHE_RAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line);
797-
void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line);
798-
void* ICACHE_RAM_ATTR pvPortZalloc(size_t size, const char* file, int line);
799-
void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line);
795+
// Specificly the debug version (heap_...) that does not force DRAM heap.
796+
void* ICACHE_RAM_ATTR heap_pvPortMalloc(size_t size, const char* file, int line);
797+
void* ICACHE_RAM_ATTR heap_pvPortCalloc(size_t count, size_t size, const char* file, int line);
798+
void* ICACHE_RAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line);
799+
void* ICACHE_RAM_ATTR heap_pvPortZalloc(size_t size, const char* file, int line);
800+
void ICACHE_RAM_ATTR heap_vPortFree(void *ptr, const char* file, int line);
800801

801-
#define malloc(s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; pvPortMalloc(s, mem_debug_file, __LINE__); })
802-
#define calloc(n,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; pvPortCalloc(n, s, mem_debug_file, __LINE__); })
803-
#define realloc(p,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; pvPortRealloc(p, s, mem_debug_file, __LINE__); })
802+
#define malloc(s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortMalloc(s, mem_debug_file, __LINE__); })
803+
#define calloc(n,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortCalloc(n, s, mem_debug_file, __LINE__); })
804+
#define realloc(p,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortRealloc(p, s, mem_debug_file, __LINE__); })
804805

805806
#if defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE)
806-
#define dbg_heap_free(p) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; vPortFree(p, mem_debug_file, __LINE__); })
807+
#define dbg_heap_free(p) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_vPortFree(p, mem_debug_file, __LINE__); })
807808
#else
808809
#define dbg_heap_free(p) free(p)
809810
#endif
810811

811812
#elif defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE)
812813
#include <pgmspace.h>
813-
void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int line);
814-
#define realloc(p,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; pvPortRealloc(p, s, mem_debug_file, __LINE__); })
814+
void* ICACHE_RAM_ATTR heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line);
815+
#define realloc(p,s) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_pvPortRealloc(p, s, mem_debug_file, __LINE__); })
815816

816-
void ICACHE_RAM_ATTR vPortFree(void *ptr, const char* file, int line);
817+
void ICACHE_RAM_ATTR heap_vPortFree(void *ptr, const char* file, int line);
817818
//C - to be discussed
818819
/*
819820
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);
828829
Create dbg_heap_free() as an alternative for free() when you need a little
829830
more help in debugging the more challenging problems.
830831
*/
831-
#define dbg_heap_free(p) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; vPortFree(p, mem_debug_file, __LINE__); })
832+
#define dbg_heap_free(p) ({ static const char mem_debug_file[] PROGMEM STORE_ATTR = __FILE__; heap_vPortFree(p, mem_debug_file, __LINE__); })
832833

833834
#else
834835
#define dbg_heap_free(p) free(p)

0 commit comments

Comments
 (0)