Skip to content

Commit 83f2897

Browse files
committed
Merge branch 'docs/document-task-tracking' into 'master'
docs(heap): Document heap task tracking Closes IDF-12684 See merge request espressif/esp-idf!38247
2 parents 76d74d9 + 0627576 commit 83f2897

File tree

3 files changed

+150
-12
lines changed

3 files changed

+150
-12
lines changed

components/heap/include/esp_heap_task_info.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include "sdkconfig.h"
99

10-
#ifdef CONFIG_HEAP_TASK_TRACKING
10+
#if CONFIG_HEAP_TASK_TRACKING || __DOXYGEN__
1111

1212
#include <stdint.h>
1313
#include <stdio.h>
@@ -104,9 +104,9 @@ typedef struct {
104104
typedef struct {
105105
task_stat_t stat; ///< Statistics of the task
106106
size_t heap_count; ///< size of user defined heap_stat array
107-
heap_stat_t *heap_stat_start; ///> Pointer to the start to the user defined heap_stat array
107+
heap_stat_t *heap_stat_start; ///< Pointer to the start to the user defined heap_stat array
108108
size_t alloc_count; ///< size of user defined alloc_stat array
109-
heap_task_block_t *alloc_stat_start; ///> Pointer to the start to the user defined alloc_stat array
109+
heap_task_block_t *alloc_stat_start; ///< Pointer to the start to the user defined alloc_stat array
110110
} heap_single_task_stat_t;
111111

112112
/**
@@ -117,9 +117,9 @@ typedef struct {
117117
size_t task_count; ///< user defined size of heap_single_task_stat_t array
118118
task_stat_t *stat_arr; ///< Pointer to the user defined array of heap_single_task_stat_t
119119
size_t heap_count; ///< size of user defined heap_stat array
120-
heap_stat_t *heap_stat_start; ///> Pointer to the start to the user defined heap_stat array
120+
heap_stat_t *heap_stat_start; ///< Pointer to the start to the user defined heap_stat array
121121
size_t alloc_count; ///< size of user defined alloc_stat array
122-
heap_task_block_t *alloc_stat_start; ///> Pointer to the start to the user defined alloc_stat array
122+
heap_task_block_t *alloc_stat_start; ///< Pointer to the start to the user defined alloc_stat array
123123
} heap_all_tasks_stat_t;
124124

125125
/**
@@ -169,7 +169,7 @@ esp_err_t heap_caps_get_single_task_stat(heap_single_task_stat_t *task_stat, Tas
169169
* @note This function is an alternative to heap_caps_get_all_task_stat if the goal is just to print information
170170
* and not manipulate them.
171171
*
172-
* @param steam The stream to dump to, if NULL then stdout is used
172+
* @param stream The stream to dump to, if NULL then stdout is used
173173
*/
174174
void heap_caps_print_all_task_stat(FILE *stream);
175175

@@ -179,7 +179,7 @@ void heap_caps_print_all_task_stat(FILE *stream);
179179
* @note The information printed by this function is an array formatted log of task_stat_t content for each running
180180
* task (and deleted ones if HEAP_TRACK_DELETED_TASKS is enabled)
181181
*
182-
* @param steam The stream to dump to, if NULL then stdout is used
182+
* @param stream The stream to dump to, if NULL then stdout is used
183183
*/
184184
void heap_caps_print_all_task_stat_overview(FILE *stream);
185185

@@ -189,7 +189,7 @@ void heap_caps_print_all_task_stat_overview(FILE *stream);
189189
* @note This function is an alternative to heap_caps_get_single_task_stat if the goal is just to print information
190190
* and not manipulate them.
191191
*
192-
* @param steam The stream to dump to, if NULL then stdout is used
192+
* @param stream The stream to dump to, if NULL then stdout is used
193193
* @param task_handle The task handle of the task to get memory usage and associated allocation information from.
194194
*/
195195
void heap_caps_print_single_task_stat(FILE *stream, TaskHandle_t task_handle);
@@ -201,7 +201,7 @@ void heap_caps_print_single_task_stat(FILE *stream, TaskHandle_t task_handle);
201201
* task. This function will not print the task summary information if the given task is deleted and
202202
* HEAP_TRACK_DELETED_TASKS is disabled.
203203
*
204-
* @param steam The stream to dump to, if NULL then stdout is used
204+
* @param stream The stream to dump to, if NULL then stdout is used
205205
* @param task_handle The task handle of the task to get memory usage and associated allocation information from.
206206
*/
207207
void heap_caps_print_single_task_stat_overview(FILE *stream, TaskHandle_t task_handle);
@@ -256,4 +256,4 @@ void heap_caps_free_all_task_stat_arrays(heap_all_tasks_stat_t *tasks_stat);
256256
}
257257
#endif
258258

259-
#endif // CONFIG_HEAP_TASK_TRACKING
259+
#endif // CONFIG_HEAP_TASK_TRACKING || __DOXYGEN__

docs/doxygen/Doxyfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ INPUT = \
269269
$(PROJECT_PATH)/components/hal/include/hal/lp_core_types.h \
270270
$(PROJECT_PATH)/components/heap/include/esp_heap_caps_init.h \
271271
$(PROJECT_PATH)/components/heap/include/esp_heap_caps.h \
272+
$(PROJECT_PATH)/components/heap/include/esp_heap_task_info.h \
272273
$(PROJECT_PATH)/components/heap/include/esp_heap_trace.h \
273274
$(PROJECT_PATH)/components/heap/include/multi_heap.h \
274275
$(PROJECT_PATH)/components/ieee802154/include/esp_ieee802154_types.h \

docs/en/api-reference/system/heap_debug.rst

Lines changed: 139 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,142 @@ Calls to :cpp:func:`heap_caps_check_integrity` or :cpp:func:`heap_caps_check_int
200200
Heap Task Tracking
201201
------------------
202202

203-
Heap Task Tracking can be used to get per-task info for heap memory allocation. The application has to specify the heap capabilities for which the heap allocation is to be tracked.
203+
The Heap Task Tracking can be enabled via the menuconfig: ``Component config`` > ``Heap memory debugging`` > ``Enable heap task tracking`` (see :ref:`CONFIG_HEAP_TASK_TRACKING`).
204204

205-
Example applications are provided in :example:`system/heap_task_tracking/basic` and :example:`system/heap_task_tracking/advanced`.
205+
The feature allows users to track the heap memory usage of each task created since startup and provides a series of statistics that can be accessed via getter functions or simply dumped into the stream of the user's choosing. This feature is useful for identifying memory usage patterns and potential memory leaks.
206206

207+
An additional configuration can be enabled by the user via the menuconfig: ``Component config`` > ``Heap memory debugging`` > ``Keep information about the memory usage of deleted tasks`` (see :ref:`CONFIG_HEAP_TRACK_DELETED_TASKS`) to keep the statistics collected for a given task even after it is deleted.
208+
209+
.. note::
210+
Note that the Heap Task Tracking cannot detect the deletion of statically allocated tasks. Therefore, users will have to keep in mind while reading the following section that statically allocated tasks will always be considered alive in the scope of the Heap Task Tracking feature.
211+
212+
It is important to mention that its usage is strongly discouraged for other purposes than debugging for the following reasons:
213+
214+
.. list::
215+
- Tracking the allocations and storing the resulting statistics for each task requires a non-negligible RAM usage overhead.
216+
- The overall performance of the heap allocator is severely impacted due to the additional processing required for each allocation and free operation.
217+
218+
.. note::
219+
Note that the memory allocated by the heap task tracking feature will not be visible when dumping or accessing the statistics.
220+
221+
Structure of the statistics and information
222+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
223+
224+
For a given task, the heap task tracking feature categorizes statistics on three different levels:
225+
226+
.. list::
227+
- The task level statistics
228+
- The heap level statistics
229+
- The allocation level statistics
230+
231+
The task level statistics provides the following information:
232+
233+
.. list::
234+
- Name of the given task
235+
- Task handle of the given task
236+
- Status of the given task (if the task is running or deleted)
237+
- Peak memory usage of the given task (the maximum amount of memory used by the given task during the task lifetime)
238+
- Current memory usage of the given task
239+
- Number of heaps in which the task has allocated memory
240+
241+
The heap level statistics provides the following information for each heap used by the given task:
242+
243+
.. list::
244+
- Name of the given heap
245+
- Caps the capabilities of the given heap (without priority)
246+
- Size the total size of the given heap
247+
- Current usage of the given task on the given heap
248+
- Peak usage of the given task on the given heap
249+
- Number of allocations done by the given task for on the given heap
250+
251+
The allocation level statistics provides the following information for each allocation done by the given task on the given heap:
252+
253+
.. list::
254+
- Address of the given allocation
255+
- Size of the given allocation
256+
257+
Dumping the statistics and information
258+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
259+
260+
The :cpp:func:`heap_caps_print_single_task_stat_overview` API prints an overview of heap usage for a specific task to the provided output stream.
261+
262+
.. code-block:: text
263+
264+
┌────────────────────┬─────────┬──────────────────────┬───────────────────┬─────────────────┐
265+
│ TASK │ STATUS │ CURRENT MEMORY USAGE │ PEAK MEMORY USAGE │ TOTAL HEAP USED │
266+
├────────────────────┼─────────┼──────────────────────┼───────────────────┼─────────────────┤
267+
│ task_name │ ALIVE │ 0 │ 7152 │ 1 │
268+
└────────────────────┴─────────┴──────────────────────┴───────────────────┴─────────────────┘
269+
270+
:cpp:func:`heap_caps_print_all_task_stat_overview` prints an overview of heap usage for all tasks (including the deleted tasks if :ref:`CONFIG_HEAP_TRACK_DELETED_TASKS` is enabled).
271+
272+
.. code-block:: text
273+
274+
┌────────────────────┬─────────┬──────────────────────┬───────────────────┬─────────────────┐
275+
│ TASK │ STATUS │ CURRENT MEMORY USAGE │ PEAK MEMORY USAGE │ TOTAL HEAP USED │
276+
├────────────────────┼─────────┼──────────────────────┼───────────────────┼─────────────────┤
277+
│ task_name │ DELETED │ 11392 │ 11616 │ 1 │
278+
│ other_task_name │ ALIVE │ 0 │ 9408 │ 2 │
279+
│ main │ ALIVE │ 3860 │ 7412 │ 2 │
280+
│ ipc1 │ ALIVE │ 32 │ 44 │ 1 │
281+
│ ipc0 │ ALIVE │ 10080 │ 10092 │ 1 │
282+
│ Pre-scheduler │ ALIVE │ 2236 │ 2236 │ 1 │
283+
└────────────────────┴─────────┴──────────────────────┴───────────────────┴─────────────────┘
284+
285+
.. note::
286+
Note that the task named “Pre-scheduler” represents allocations that occurred before the scheduler was started. It is not an actual task, so the "status" field (which is shown as "ALIVE") is not meaningful and should be ignored.
287+
288+
Use :cpp:func:`heap_caps_print_single_task_stat` to dump the complete set of statistics for a specific task, or :cpp:func:`heap_caps_print_all_task_stat` to dump statistics for all tasks:
289+
290+
.. code-block:: text
291+
292+
[...]
293+
├ ALIVE: main, CURRENT MEMORY USAGE 308, PEAK MEMORY USAGE 7412, TOTAL HEAP USED 2:
294+
│ ├ HEAP: RAM, CAPS: 0x0010580e, SIZE: 344400, USAGE: CURRENT 220 (0%), PEAK 220 (0%), ALLOC COUNT: 2
295+
│ │ ├ ALLOC 0x3fc99024, SIZE 88
296+
│ │ ├ ALLOC 0x3fc99124, SIZE 132
297+
│ └ HEAP: RAM, CAPS: 0x0010580e, SIZE: 22308, USAGE: CURRENT 88 (0%), PEAK 7192 (32%), ALLOC COUNT: 5
298+
│ ├ ALLOC 0x3fce99f8, SIZE 20
299+
│ ├ ALLOC 0x3fce9a10, SIZE 12
300+
│ ├ ALLOC 0x3fce9a20, SIZE 16
301+
│ ├ ALLOC 0x3fce9a34, SIZE 20
302+
│ ├ ALLOC 0x3fce9a4c, SIZE 20
303+
[...]
304+
└ ALIVE: Pre-scheduler, CURRENT MEMORY USAGE 2236, PEAK MEMORY USAGE 2236, TOTAL HEAP USED 1:
305+
└ HEAP: RAM, CAPS: 0x0010580e, SIZE: 344400, USAGE: CURRENT 2236 (0%), PEAK 2236 (0%), ALLOC COUNT: 11
306+
├ ALLOC 0x3fc95cb0, SIZE 164
307+
├ ALLOC 0x3fc95dd8, SIZE 12
308+
├ ALLOC 0x3fc95dfc, SIZE 12
309+
├ ALLOC 0x3fc95e20, SIZE 16
310+
├ ALLOC 0x3fc95e48, SIZE 24
311+
├ ALLOC 0x3fc95e78, SIZE 88
312+
├ ALLOC 0x3fc95ee8, SIZE 88
313+
├ ALLOC 0x3fc95f58, SIZE 88
314+
├ ALLOC 0x3fc95fc8, SIZE 88
315+
├ ALLOC 0x3fc96038, SIZE 1312
316+
├ ALLOC 0x3fc96570, SIZE 344
317+
318+
.. note::
319+
The dump shown above has been truncated (see "[...]") for readability reasons and only displays the statistics and information of the **main** task and the **Pre-scheduler**. The goal here is only to demonstrate the information displayed when calling the :cpp:func:`heap_caps_print_all_task_stat` (resp. :cpp:func:`heap_caps_print_single_task_stat`) API functions.
320+
321+
.. note::
322+
Detailed use of the API functions described in this section can be found in :example:`system/heap_task_tracking/basic`.
323+
324+
Getting the statistics and information
325+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
326+
327+
:cpp:func:`heap_caps_get_single_task_stat` allows the user to access information of a specific task. The information retrieved by calling this API is identical to the one dumped using :cpp:func:`heap_caps_print_single_task_stat`.
328+
329+
:cpp:func:`heap_caps_get_all_task_stat` allows the user to access an overview of the information of all tasks (including the deleted tasks if :ref:`CONFIG_HEAP_TRACK_DELETED_TASKS` is enabled). The information retrieved by calling this API is identical to the one dumped using :cpp:func:`heap_caps_print_all_task_stat`.
330+
331+
Each getter function requires a pointer to the data structure that will be used by the heap task tracking to gather the statistics and information of a given task (or all tasks). This data structure contains pointers to arrays that the user can allocate statically or dynamically.
332+
333+
Due to the difficulty of estimating the size of the arrays used to store information — since it's hard to determine the number of allocations per task, the number of heaps used by each task, and the number of tasks created since startup — the heap task tracking also provides :cpp:func:`heap_caps_alloc_single_task_stat_arrays` (resp. :cpp:func:`heap_caps_alloc_all_task_stat_arrays`) to dynamically allocate the required amount of memory for those arrays.
334+
335+
Similarly, the heap task tracking also provides :cpp:func:`heap_caps_free_single_task_stat_arrays` (resp. :cpp:func:`heap_caps_free_all_task_stat_arrays`) to free the memory dynamically allocated when calling :cpp:func:`heap_caps_alloc_single_task_stat_arrays` (resp. :cpp:func:`heap_caps_alloc_all_task_stat_arrays`).
336+
337+
.. note::
338+
Detailed use of the API functions described in this section can be found in :example:`system/heap_task_tracking/advanced`.
207339

208340
.. _heap-tracing:
209341

@@ -632,6 +764,11 @@ Application Examples
632764
- :example:`system/heap_task_tracking/basic` demonstrates the use of the overview feature of the heap task tracking, dumping per-task summary statistics on heap memory usage.
633765
- :example:`system/heap_task_tracking/advanced` demonstrates the use of the statistics getter functions of the heap task tracking, accessing per-task complete statistic on the heap memory usage.
634766

767+
API Reference - Heap Task Tracking
768+
----------------------------------
769+
770+
.. include-build-file:: inc/esp_heap_task_info.inc
771+
635772
API Reference - Heap Tracing
636773
----------------------------
637774

0 commit comments

Comments
 (0)