mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
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
This commit is contained in:
parent
e938739115
commit
df5e113b88
@ -5,6 +5,11 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "umm_malloc/umm_malloc.h"
|
#include "umm_malloc/umm_malloc.h"
|
||||||
|
|
||||||
|
// Need FORCE_ALWAYS_INLINE to put HeapSelect class constructor/deconstructor in IRAM
|
||||||
|
#define FORCE_ALWAYS_INLINE_HEAP_SELECT
|
||||||
|
#include "umm_malloc/umm_heap_select.h"
|
||||||
|
|
||||||
#include <c_types.h>
|
#include <c_types.h>
|
||||||
#include <sys/reent.h>
|
#include <sys/reent.h>
|
||||||
#include <user_interface.h>
|
#include <user_interface.h>
|
||||||
@ -16,6 +21,7 @@ extern "C" {
|
|||||||
#define UMM_CALLOC(n,s) umm_poison_calloc(n,s)
|
#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_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 UMM_FREE_FL(p,f,l) umm_poison_free_fl(p,f,l)
|
||||||
|
#define STATIC_ALWAYS_INLINE
|
||||||
|
|
||||||
#undef realloc
|
#undef realloc
|
||||||
#undef free
|
#undef free
|
||||||
@ -25,6 +31,7 @@ extern "C" {
|
|||||||
#define UMM_CALLOC(n,s) umm_calloc(n,s)
|
#define UMM_CALLOC(n,s) umm_calloc(n,s)
|
||||||
#define UMM_REALLOC_FL(p,s,f,l) umm_realloc(p,s)
|
#define UMM_REALLOC_FL(p,s,f,l) umm_realloc(p,s)
|
||||||
#define UMM_FREE_FL(p,f,l) umm_free(p)
|
#define UMM_FREE_FL(p,f,l) umm_free(p)
|
||||||
|
#define STATIC_ALWAYS_INLINE
|
||||||
|
|
||||||
#undef realloc
|
#undef realloc
|
||||||
#undef free
|
#undef free
|
||||||
@ -34,6 +41,10 @@ extern "C" {
|
|||||||
#define UMM_CALLOC(n,s) calloc(n,s)
|
#define UMM_CALLOC(n,s) calloc(n,s)
|
||||||
#define UMM_REALLOC_FL(p,s,f,l) realloc(p,s)
|
#define UMM_REALLOC_FL(p,s,f,l) realloc(p,s)
|
||||||
#define UMM_FREE_FL(p,f,l) free(p)
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -259,8 +270,8 @@ void ICACHE_RAM_ATTR free(void* p)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
STATIC_ALWAYS_INLINE
|
||||||
void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line)
|
void* ICACHE_RAM_ATTR heap_pvPortMalloc(size_t size, const char* file, int line)
|
||||||
{
|
{
|
||||||
INTEGRITY_CHECK__PANIC_FL(file, line);
|
INTEGRITY_CHECK__PANIC_FL(file, line);
|
||||||
POISON_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;
|
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);
|
INTEGRITY_CHECK__PANIC_FL(file, line);
|
||||||
POISON_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;
|
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);
|
INTEGRITY_CHECK__PANIC_FL(file, line);
|
||||||
void* ret = UMM_REALLOC_FL(ptr, size, 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;
|
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);
|
INTEGRITY_CHECK__PANIC_FL(file, line);
|
||||||
POISON_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;
|
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);
|
INTEGRITY_CHECK__PANIC_FL(file, line);
|
||||||
UMM_FREE_FL(ptr, 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)
|
void system_show_malloc(void)
|
||||||
{
|
{
|
||||||
|
HeapSelectDram ephemeral;
|
||||||
umm_info(NULL, true);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,18 @@
|
|||||||
|
|
||||||
#include <umm_malloc/umm_malloc.h>
|
#include <umm_malloc/umm_malloc.h>
|
||||||
|
|
||||||
|
#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_HEAP_SELECT
|
||||||
|
#define MAYBE_ALWAYS_INLINE ALWAYS_INLINE
|
||||||
|
#else
|
||||||
|
#define MAYBE_ALWAYS_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This class is modeled after interrupts.h
|
This class is modeled after interrupts.h
|
||||||
|
|
||||||
@ -20,13 +32,17 @@
|
|||||||
class HeapSelect {
|
class HeapSelect {
|
||||||
public:
|
public:
|
||||||
#if (UMM_NUM_HEAPS == 1)
|
#if (UMM_NUM_HEAPS == 1)
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
HeapSelect(size_t id) { (void)id; }
|
HeapSelect(size_t id) { (void)id; }
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
~HeapSelect() {}
|
~HeapSelect() {}
|
||||||
#else
|
#else
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
HeapSelect(size_t id) : _heap_id(umm_get_current_heap_id()) {
|
HeapSelect(size_t id) : _heap_id(umm_get_current_heap_id()) {
|
||||||
umm_set_heap_by_id(id);
|
umm_set_heap_by_id(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
~HeapSelect() {
|
~HeapSelect() {
|
||||||
umm_set_heap_by_id(_heap_id);
|
umm_set_heap_by_id(_heap_id);
|
||||||
}
|
}
|
||||||
@ -39,10 +55,12 @@ protected:
|
|||||||
class HeapSelectIram {
|
class HeapSelectIram {
|
||||||
public:
|
public:
|
||||||
#ifdef UMM_HEAP_IRAM
|
#ifdef UMM_HEAP_IRAM
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
HeapSelectIram() : _heap_id(umm_get_current_heap_id()) {
|
HeapSelectIram() : _heap_id(umm_get_current_heap_id()) {
|
||||||
umm_set_heap_by_id(UMM_HEAP_IRAM);
|
umm_set_heap_by_id(UMM_HEAP_IRAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
~HeapSelectIram() {
|
~HeapSelectIram() {
|
||||||
umm_set_heap_by_id(_heap_id);
|
umm_set_heap_by_id(_heap_id);
|
||||||
}
|
}
|
||||||
@ -51,7 +69,9 @@ protected:
|
|||||||
size_t _heap_id;
|
size_t _heap_id;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
HeapSelectIram() {}
|
HeapSelectIram() {}
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
~HeapSelectIram() {}
|
~HeapSelectIram() {}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -59,13 +79,17 @@ protected:
|
|||||||
class HeapSelectDram {
|
class HeapSelectDram {
|
||||||
public:
|
public:
|
||||||
#if (UMM_NUM_HEAPS == 1)
|
#if (UMM_NUM_HEAPS == 1)
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
HeapSelectDram() {}
|
HeapSelectDram() {}
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
~HeapSelectDram() {}
|
~HeapSelectDram() {}
|
||||||
#else
|
#else
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
HeapSelectDram() : _heap_id(umm_get_current_heap_id()) {
|
HeapSelectDram() : _heap_id(umm_get_current_heap_id()) {
|
||||||
umm_set_heap_by_id(UMM_HEAP_DRAM);
|
umm_set_heap_by_id(UMM_HEAP_DRAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MAYBE_ALWAYS_INLINE
|
||||||
~HeapSelectDram() {
|
~HeapSelectDram() {
|
||||||
umm_set_heap_by_id(_heap_id);
|
umm_set_heap_by_id(_heap_id);
|
||||||
}
|
}
|
||||||
|
@ -792,28 +792,29 @@ extern "C" {
|
|||||||
// Arduino.h recall us to redefine them
|
// Arduino.h recall us to redefine them
|
||||||
#include <pgmspace.h>
|
#include <pgmspace.h>
|
||||||
// Reuse pvPort* calls, since they already support passing location information.
|
// Reuse pvPort* calls, since they already support passing location information.
|
||||||
void* ICACHE_RAM_ATTR pvPortMalloc(size_t size, const char* file, int line);
|
// Specificly the debug version (heap_...) that does not force DRAM heap.
|
||||||
void* ICACHE_RAM_ATTR pvPortCalloc(size_t count, size_t size, const char* file, int line);
|
void* ICACHE_RAM_ATTR heap_pvPortMalloc(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 heap_pvPortCalloc(size_t count, 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 heap_pvPortRealloc(void *ptr, size_t size, const char* file, int line);
|
||||||
void ICACHE_RAM_ATTR vPortFree(void *ptr, 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 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__; pvPortCalloc(n, 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__; pvPortRealloc(p, 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)
|
#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
|
#else
|
||||||
#define dbg_heap_free(p) free(p)
|
#define dbg_heap_free(p) free(p)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE)
|
#elif defined(UMM_POISON_CHECK) || defined(UMM_POISON_CHECK_LITE)
|
||||||
#include <pgmspace.h>
|
#include <pgmspace.h>
|
||||||
void* ICACHE_RAM_ATTR pvPortRealloc(void *ptr, size_t size, const char* file, int 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__; pvPortRealloc(p, 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__); })
|
||||||
|
|
||||||
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
|
//C - to be discussed
|
||||||
/*
|
/*
|
||||||
Problem, I would like to report the file and line number with the umm poison
|
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
|
Create dbg_heap_free() as an alternative for free() when you need a little
|
||||||
more help in debugging the more challenging problems.
|
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
|
#else
|
||||||
#define dbg_heap_free(p) free(p)
|
#define dbg_heap_free(p) free(p)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user