Skip to content

Commit 6ba3347

Browse files
committed
zephyr: alloc: Map native_sim heap to the C library
When building the firmware for native_sim, debugging allocations with host machine tools like Valgrind is constrained due to Zephyr's internal minimal libc tracking the heap manually via static pools. By bypassing Zephyr's memory interception on native_sim using nsi_host_malloc, dynamically tracked memory can surface appropriately to Valgrind memory checkers without causing a libc heap pool panic. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent 182c351 commit 6ba3347

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

zephyr/lib/alloc.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ extern char _end[], _heap_sentry[];
153153

154154
static struct k_heap sof_heap;
155155

156+
#if !defined(CONFIG_BOARD_NATIVE_SIM)
156157
/**
157158
* Checks whether pointer is from a given heap memory.
158159
* @param heap Pointer to a heap.
@@ -171,6 +172,7 @@ static bool is_heap_pointer(const struct k_heap *heap, void *ptr)
171172
return ((POINTER_TO_UINT(ptr) >= heap_start) &&
172173
(POINTER_TO_UINT(ptr) < heap_end));
173174
}
175+
#endif
174176

175177
#if CONFIG_SOF_USERSPACE_USE_SHARED_HEAP
176178
static struct k_heap shared_buffer_heap;
@@ -382,6 +384,7 @@ struct k_heap *sof_sys_heap_get(void)
382384
return &sof_heap;
383385
}
384386

387+
#if !defined(CONFIG_BOARD_NATIVE_SIM)
385388
static void *heap_alloc_aligned(struct k_heap *h, size_t min_align, size_t bytes)
386389
{
387390
k_spinlock_key_t key;
@@ -451,7 +454,106 @@ static void heap_free(struct k_heap *h, void *mem)
451454

452455
k_spin_unlock(&h->lock, key);
453456
}
457+
#endif
458+
454459

460+
#if defined(CONFIG_BOARD_NATIVE_SIM)
461+
#include <nsi_host_trampolines.h>
462+
#include <string.h>
463+
464+
void *rmalloc_align(uint32_t flags, size_t bytes, uint32_t alignment)
465+
{
466+
void *ptr;
467+
void *raw;
468+
469+
if (alignment < sizeof(void *))
470+
alignment = sizeof(void *);
471+
472+
raw = nsi_host_malloc(bytes + alignment + sizeof(void *));
473+
if (!raw)
474+
return NULL;
475+
476+
ptr = (void *)(((uintptr_t)raw + sizeof(void *) + alignment - 1) & ~(alignment - 1));
477+
((void **)ptr)[-1] = raw;
478+
479+
return ptr;
480+
}
481+
EXPORT_SYMBOL(rmalloc_align);
482+
483+
void *rmalloc(uint32_t flags, size_t bytes)
484+
{
485+
return rmalloc_align(flags, bytes, 0);
486+
}
487+
EXPORT_SYMBOL(rmalloc);
488+
489+
void *rbrealloc_align(void *ptr, uint32_t flags, size_t bytes,
490+
size_t old_bytes, uint32_t alignment)
491+
{
492+
void *new_ptr;
493+
494+
if (!ptr)
495+
return rmalloc_align(flags, bytes, alignment);
496+
497+
if (!bytes) {
498+
void *raw = ((void **)ptr)[-1];
499+
500+
nsi_host_free(raw);
501+
return NULL;
502+
}
503+
504+
new_ptr = rmalloc_align(flags, bytes, alignment);
505+
if (!new_ptr)
506+
return NULL;
507+
508+
if (!(flags & SOF_MEM_FLAG_NO_COPY))
509+
memcpy_s(new_ptr, bytes, ptr, MIN(bytes, old_bytes));
510+
511+
void *raw_old = ((void **)ptr)[-1];
512+
513+
nsi_host_free(raw_old);
514+
515+
return new_ptr;
516+
}
517+
518+
void *rzalloc(uint32_t flags, size_t bytes)
519+
{
520+
void *ptr = rmalloc_align(flags, bytes, 0);
521+
522+
if (ptr)
523+
memset(ptr, 0, bytes);
524+
return ptr;
525+
}
526+
EXPORT_SYMBOL(rzalloc);
527+
528+
void *rballoc_align(uint32_t flags, size_t bytes, uint32_t align)
529+
{
530+
return rmalloc_align(flags, bytes, align);
531+
}
532+
EXPORT_SYMBOL(rballoc_align);
533+
534+
void rfree(void *ptr)
535+
{
536+
if (!ptr)
537+
return;
538+
539+
void *raw = ((void **)ptr)[-1];
540+
541+
nsi_host_free(raw);
542+
}
543+
EXPORT_SYMBOL(rfree);
544+
545+
void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes,
546+
size_t alignment)
547+
{
548+
return rmalloc_align(flags, bytes, alignment);
549+
}
550+
551+
void sof_heap_free(struct k_heap *heap, void *addr)
552+
{
553+
rfree(addr);
554+
}
555+
556+
#else
455557

456558
void *rmalloc_align(uint32_t flags, size_t bytes, uint32_t alignment)
457559
{
@@ -642,6 +744,8 @@ void sof_heap_free(struct k_heap *heap, void *addr)
642744
rfree(addr);
643745
}
644746

747+
#endif /* CONFIG_BOARD_NATIVE_SIM */
748+
645749
static int heap_init(void)
646750
{
647751
sys_heap_init(&sof_heap.heap, heapmem, HEAPMEM_SIZE - SHARED_BUFFER_HEAP_MEM_SIZE);

0 commit comments

Comments
 (0)