Skip to content

Commit

Permalink
py/malloc: Add m_tracked_realloc.
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
  • Loading branch information
pi-anl committed Oct 17, 2024
1 parent 838f212 commit fef3597
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 0 deletions.
7 changes: 7 additions & 0 deletions ports/unix/coverage.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,13 @@ static mp_obj_t extra_coverage(void) {
gc_collect();
}

// resize one of the blocks
void *before = ptrs[1];
ptrs[1] = FLIP_POINTER(m_tracked_realloc(FLIP_POINTER(ptrs[1]), 2 * NUM_BYTES));
void *after = ptrs[1];
bool location_changed = before != after;
mp_printf(&mp_plat_print, "%d\n", location_changed);

// check the memory blocks have the correct content
for (size_t i = 0; i < NUM_PTRS; ++i) {
bool correct_contents = true;
Expand Down
43 changes: 43 additions & 0 deletions py/malloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,49 @@ void *m_tracked_calloc(size_t nmemb, size_t size) {
return &node->data[0];
}

void *m_tracked_realloc(void *ptr_in, size_t n_bytes) {
// check for pure allocation
if (ptr_in == NULL) {
return m_tracked_alloc(n_bytes);
}
// check for pure free
if (n_bytes == 0) {
m_tracked_free(ptr_in);
return NULL;
}
m_tracked_node_t *node = (m_tracked_node_t *)((uint8_t *)ptr_in - sizeof(m_tracked_node_t));
size_t prev_bytes;
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE || MICROPY_DEBUG_VERBOSE
#if MICROPY_TRACKED_ALLOC_STORE_SIZE
prev_bytes = node->size;
#else
prev_bytes = gc_nbytes(node);
#endif
#if MICROPY_DEBUG_VERBOSE
size_t nb;
size_t n = m_tracked_count_links(&nb);
DEBUG_printf("m_tracked_realloc(%p, [%p, %p], pbytes=%u, nbytes=%u, links=%u;%u)\n", node, node->prev, node->next, (int)prev_bytes, (int)n_bytes, (int)n, (int)nb);
#endif
#endif
node = m_realloc(node,
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE
sizeof(m_tracked_node_t) + prev_bytes,
#endif
sizeof(m_tracked_node_t) + n_bytes
);
if (node == NULL) {
node->prev->next = node->next;
node->next->prev = node->prev;
return NULL;
}
#if MICROPY_TRACKED_ALLOC_STORE_SIZE
node->size = n_bytes;
#endif
node->prev->next = node;
node->next->prev = node;
return &node->data[0];
}

void m_tracked_free(void *ptr_in) {
if (ptr_in == NULL) {
return;
Expand Down
1 change: 1 addition & 0 deletions py/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ NORETURN void m_malloc_fail(size_t num_bytes);
// These alloc/free functions track the pointers in a linked list so the GC does not reclaim
// them. They can be used by code that requires traditional C malloc/free semantics.
void *m_tracked_calloc(size_t nmemb, size_t size);
void *m_tracked_realloc(void *ptr_in, size_t n_bytes);
void m_tracked_free(void *ptr_in);
#endif

Expand Down
1 change: 1 addition & 0 deletions tests/ports/unix/extra_coverage.py.exp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ m_tracked_head = 0
5 1
6 1
7 1
1
0 1
1 1
2 1
Expand Down
4 changes: 4 additions & 0 deletions tests/run-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,10 @@ def main():
run-tests.py -i async - exclude all, then include tests containing "async" anywhere
run-tests.py -e '/big.+int' - include all, then exclude by regex
run-tests.py -e async -i async_foo - include all, exclude async, yet still include async_foo
For tests that use cpython, unix micropython and mpy-cross, the default executables
vcan be overridden with the environment variables MICROPY_CPYTHON3, MICROPY_MICROPYTHON and
MICROPY_MPYCROSS respectively.
""",
)
cmd_parser.add_argument("--target", default="unix", help="the target platform")
Expand Down

0 comments on commit fef3597

Please sign in to comment.