Difference between revisions of "How to use SystemView Heap Monitoring - Custom Heap"
(11 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | ==Intro== |
||
This article assumes a working SystemView setup. To gain some more info on this subject, please consult either the main article ([[How to use SystemView Heap_Monitoring]]) or the SystemView documentation. |
This article assumes a working SystemView setup. To gain some more info on this subject, please consult either the main article ([[How to use SystemView Heap_Monitoring]]) or the SystemView documentation. |
||
+ | ==Heap Initialization== |
||
− | Note that the size reported to SystemView should be the internally allocated size minus the meta data, not the size requested buy a user. |
||
+ | A typical heap organization would look like this: |
||
− | The <code>__heap_start__</code> is a symbol that is defined if the heap region is allocated in the linker script. |
||
[[File:heap_organization.svg]] |
[[File:heap_organization.svg]] |
||
+ | |||
+ | ...where metadata holds the information about the size of the chunk and pointers to other chunks. |
||
+ | This information needs to be provided during the initialization of the SystemView interface through the following function: |
||
+ | <pre> |
||
+ | void SEGGER_SYSVIEW_HeapDefine(void * pHeap, |
||
+ | void * pBase, |
||
+ | unsigned int HeapSize, |
||
+ | unsigned int MetadataSize); |
||
+ | </pre> |
||
+ | |||
+ | The <code>__heap_start__</code> and <code>__heap_size__</code> are symbols that are defined if a region named ''heap'' is specified in the linker script. |
||
+ | E.g. to define a heap which has the metadata holding a size of the chunk and a pointer to the next chunk: |
||
+ | |||
+ | <code>SEGGER_SYSVIEW_HeapDefine(__heap_start__, __heap_start__, (unsigned int)__heap_size__, sizeof(unsigned) + sizeof(void*));</code> |
||
+ | |||
+ | ==Reporting Heap Data To SystemView== |
||
+ | The size reported to SystemView should be the internally allocated size excluding the metadata, and not the size requested by a user. Therefore, an internal utility function for obtaining the size to be reported to SystemView, which also observers alignment, might look like this: |
||
+ | |||
+ | <pre> |
||
+ | #define HEAP_CHUNK_SIZE 8 |
||
+ | |||
+ | static U32 _GetAllocBlockSize(U32 ReqSize) { |
||
+ | return (ReqSize + sizeof(unsigned) + HEAP_CHUNK_SIZE - 1) & (unsigned)(-HEAP_CHUNK_SIZE); |
||
+ | } |
||
+ | </pre> |
||
Allocating the memory should be accompanied by a call to <code>SEGGER_SYSVIEW_HeapAlloc</code>: |
Allocating the memory should be accompanied by a call to <code>SEGGER_SYSVIEW_HeapAlloc</code>: |
||
<pre> |
<pre> |
||
static void* _MyMalloc(size_t size) { |
static void* _MyMalloc(size_t size) { |
||
− | void* p = ... // |
+ | void* p = ... // allocate a block |
// SystemView needs the real internal heap block size, not the amount requested by the user |
// SystemView needs the real internal heap block size, not the amount requested by the user |
||
SEGGER_SYSVIEW_HeapAlloc(__heap_start__, p, _GetAllocBlockSize(size)); |
SEGGER_SYSVIEW_HeapAlloc(__heap_start__, p, _GetAllocBlockSize(size)); |
||
Line 19: | Line 45: | ||
<pre> |
<pre> |
||
static void _MyFree(void* p) { |
static void _MyFree(void* p) { |
||
− | ... // |
+ | ... // freeing procedure |
SEGGER_SYSVIEW_HeapFree(__heap_start__, p); |
SEGGER_SYSVIEW_HeapFree(__heap_start__, p); |
||
} |
} |
||
Line 27: | Line 53: | ||
<pre> |
<pre> |
||
static void* _MyRealloc(void* p, size_t size) { |
static void* _MyRealloc(void* p, size_t size) { |
||
+ | ... // reallocation procedure |
||
− | void* rp = ... // a call to a custom realloc routine |
||
SEGGER_SYSVIEW_HeapFree(__heap_start__, p); |
SEGGER_SYSVIEW_HeapFree(__heap_start__, p); |
||
// SystemView needs the real internal heap block size, not the amount requested by the user |
// SystemView needs the real internal heap block size, not the amount requested by the user |
Revision as of 15:38, 19 July 2023
Intro
This article assumes a working SystemView setup. To gain some more info on this subject, please consult either the main article (How to use SystemView Heap_Monitoring) or the SystemView documentation.
Heap Initialization
A typical heap organization would look like this:
...where metadata holds the information about the size of the chunk and pointers to other chunks. This information needs to be provided during the initialization of the SystemView interface through the following function:
void SEGGER_SYSVIEW_HeapDefine(void * pHeap, void * pBase, unsigned int HeapSize, unsigned int MetadataSize);
The __heap_start__
and __heap_size__
are symbols that are defined if a region named heap is specified in the linker script.
E.g. to define a heap which has the metadata holding a size of the chunk and a pointer to the next chunk:
SEGGER_SYSVIEW_HeapDefine(__heap_start__, __heap_start__, (unsigned int)__heap_size__, sizeof(unsigned) + sizeof(void*));
Reporting Heap Data To SystemView
The size reported to SystemView should be the internally allocated size excluding the metadata, and not the size requested by a user. Therefore, an internal utility function for obtaining the size to be reported to SystemView, which also observers alignment, might look like this:
#define HEAP_CHUNK_SIZE 8 static U32 _GetAllocBlockSize(U32 ReqSize) { return (ReqSize + sizeof(unsigned) + HEAP_CHUNK_SIZE - 1) & (unsigned)(-HEAP_CHUNK_SIZE); }
Allocating the memory should be accompanied by a call to SEGGER_SYSVIEW_HeapAlloc
:
static void* _MyMalloc(size_t size) { void* p = ... // allocate a block // SystemView needs the real internal heap block size, not the amount requested by the user SEGGER_SYSVIEW_HeapAlloc(__heap_start__, p, _GetAllocBlockSize(size)); return p; }
Freeing the memory should be accompanied by a call to SEGGER_SYSVIEW_HeapFree
:
static void _MyFree(void* p) { ... // freeing procedure SEGGER_SYSVIEW_HeapFree(__heap_start__, p); }
Since there is no dedicated realloc SystemView API function, a combination of SEGGER_SYSVIEW_HeapFree
and SEGGER_SYSVIEW_HeapAlloc
is needed:
static void* _MyRealloc(void* p, size_t size) { ... // reallocation procedure SEGGER_SYSVIEW_HeapFree(__heap_start__, p); // SystemView needs the real internal heap block size, not the amount requested by the user SEGGER_SYSVIEW_HeapAlloc(__heap_start__, rp, _GetAllocBlockSize(size)); return rp; }