8000 py/gc & esp32: Include largest free block in gc.mem_free() if MICROPY_GC_SPLIT_HEAP_AUTO is enabled by projectgus · Pull Request #12366 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content

py/gc & esp32: Include largest free block in gc.mem_free() if MICROPY_GC_SPLIT_HEAP_AUTO is enabled #12366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions docs/library/esp32.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,6 @@ Functions
two most useful ones are predefined as `esp32.HEAP_DATA` for data heap regions and
`esp32.HEAP_EXEC` for executable regions as used by the native code emitter.

Free IDF heap memory in the `esp32.HEAP_DATA` region is available to be
automatically added to the MicroPython heap to prevent a MicroPython
allocation from failing. However, the information returned here is otherwise
*not* useful to troubleshoot Python allocation failures, use
`micropython.mem_info()` instead. The "max new split" value in
`micropython.mem_info()` output corresponds to the largest free block of
ESP-IDF heap that could be automatically added on demand to the MicroPython
heap.

The return value is a list of 4-tuples, where each 4-tuple corresponds to one heap
and contains: the total bytes, the free bytes, the largest free block, and
the minimum free seen over time.
Expand All @@ -75,6 +66,21 @@ Functions
[(240, 0, 0, 0), (7288, 0, 0, 0), (16648, 4, 4, 4), (79912, 35712, 35512, 35108),
(15072, 15036, 15036, 15036), (113840, 0, 0, 0)]

.. note:: Free IDF heap memory in the `esp32.HEAP_DATA` region is available
to be automatically added to the MicroPython heap to prevent a
MicroPython allocation from failing. However, the information returned
here is otherwise *not* useful to troubleshoot Python allocation
failures. :func:`micropython.mem_info()` and :func:`gc.mem_free()` should
be used instead:

The "max new split" value in :func:`micropython.mem_info()` output
corresponds to the largest free block of ESP-IDF heap that could be
automatically added on demand to the MicroPython heap.

The result of :func:`gc.mem_free()` is the total of the current "free"
and "max new split" values printed by :func:`micropython.mem_info()`.


Flash partitions
----------------

Expand Down
6 changes: 3 additions & 3 deletions docs/library/gc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Functions

.. function:: mem_alloc()

Return the number of bytes of heap RAM that are allocated.
Return the number of bytes of heap RAM that are allocated by Python code.

.. admonition:: Difference to CPython
:class: attention
Expand All @@ -33,8 +33,8 @@ Functions

.. function:: mem_free()

Return the number of bytes of available heap RAM, or -1 if this amount
is not known.
Return the number of bytes of heap RAM that is available for Python
code to allocate, or -1 if this amount is not known.

.. admonition:: Difference to CPython
:class: attention
Expand Down
7 changes: 6 additions & 1 deletion py/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,11 @@ void gc_info(gc_info_t *info) {

info->used *= BYTES_PER_BLOCK;
info->free *= BYTES_PER_BLOCK;

#if MICROPY_GC_SPLIT_HEAP_AUTO
info->max_new_split = gc_get_max_new_split();
#endif

GC_EXIT();
}

Expand Down Expand Up @@ -1159,7 +1164,7 @@ void gc_dump_info(const mp_print_t *print) {
mp_printf(print, "GC: total: %u, used: %u, free: %u",
(uint)info.total, (uint)info.used, (uint)info.free);
#if MICROPY_GC_SPLIT_HEAP_AUTO
mp_printf(print, ", max new split: %u", (uint)gc_get_max_new_split());
mp_printf(print, ", max new split: %u", (uint)info.max_new_split);
#endif
mp_printf(print, "\n No. of 1-blocks: %u, 2-blocks: %u, max blk sz: %u, max free sz: %u\n",
(uint)info.num_1block, (uint)info.num_2block, (uint)info.max_block, (uint)info.max_free);
Expand Down
3 changes: 3 additions & 0 deletions py/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ typedef struct _gc_info_t {
size_t num_1block;
size_t num_2block;
size_t max_block;
#if MICROPY_GC_SPLIT_HEAP_AUTO
size_t max_new_split;
#endif
} gc_info_t;

void gc_info(gc_info_t *info);
Expand Down
5 changes: 5 additions & 0 deletions py/modgc.c
6644
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ MP_DEFINE_CONST_FUN_OBJ_0(gc_isenabled_obj, gc_isenabled);
STATIC mp_obj_t gc_mem_free(void) {
gc_info_t info;
gc_info(&info);
#if MICROPY_GC_SPLIT_HEAP_AUTO
// Include max_new_split value here as a more useful heuristic
return MP_OBJ_NEW_SMALL_INT(info.free + info.max_new_split);
#else
return MP_OBJ_NEW_SMALL_INT(info.free);
#endif
}
MP_DEFINE_CONST_FUN_OBJ_0(gc_mem_free_obj, gc_mem_free);

Expand Down
0