Browse Source

py/malloc: Add m_tracked_realloc.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
pull/16023/head
Andrew Leech 3 weeks ago
parent
commit
008dab26b3
  1. 7
      ports/unix/coverage.c
  2. 43
      py/malloc.c
  3. 1
      py/misc.h
  4. 1
      tests/ports/unix/extra_coverage.py.exp
  5. 4
      tests/run-tests.py

7
ports/unix/coverage.c

@ -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;

43
py/malloc.c

@ -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_calloc(1, 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));
#if MICROPY_MALLOC_USES_ALLOCATED_SIZE || MICROPY_DEBUG_VERBOSE
size_t prev_bytes;
#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;

1
py/misc.h

@ -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

1
tests/ports/unix/extra_coverage.py.exp

@ -29,6 +29,7 @@ m_tracked_head = 0
5 1
6 1
7 1
1
0 1
1 1
2 1

4
tests/run-tests.py

@ -937,6 +937,10 @@ the last matching regex is used:
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")

Loading…
Cancel
Save