feat: rebuild heap4 card around upstream FreeRTOS allocator
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#if defined(HOST_PRINTF)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
uint8_t ucHeap[configTOTAL_HEAP_SIZE] __attribute__((aligned(portBYTE_ALIGNMENT)));
|
||||
|
||||
HeapStats_t g_fragmented_stats;
|
||||
HeapStats_t g_final_stats;
|
||||
volatile size_t g_initial_free;
|
||||
volatile size_t g_after_allocations;
|
||||
volatile size_t g_final_free;
|
||||
volatile size_t g_minimum_ever_free;
|
||||
volatile int g_allocations_aligned;
|
||||
volatile int g_oom_is_null;
|
||||
volatile int g_malloc_failed_hooks;
|
||||
volatile int g_assert_failures;
|
||||
volatile int g_task03_pass;
|
||||
|
||||
void vApplicationMallocFailedHook(void)
|
||||
{
|
||||
g_malloc_failed_hooks++;
|
||||
}
|
||||
|
||||
void heap4_lab_assert(const char *file, int line)
|
||||
{
|
||||
(void)file;
|
||||
(void)line;
|
||||
g_assert_failures++;
|
||||
}
|
||||
|
||||
#if defined(HEAP4_HOST_ADAPTER)
|
||||
void vTaskSuspendAll(void)
|
||||
{
|
||||
}
|
||||
|
||||
BaseType_t xTaskResumeAll(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__((noinline)) void heap4_fragmented_checkpoint(void)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
__asm__ volatile("" ::: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((noinline)) void task03_debug_checkpoint(void)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
__asm__ volatile("" ::: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
void *probe;
|
||||
void *a;
|
||||
void *b;
|
||||
void *c;
|
||||
void *too_large;
|
||||
|
||||
vPortHeapResetState();
|
||||
probe = pvPortMalloc(1U);
|
||||
if (probe != NULL)
|
||||
{
|
||||
vPortFree(probe);
|
||||
}
|
||||
g_initial_free = xPortGetFreeHeapSize();
|
||||
|
||||
a = pvPortMalloc(24U);
|
||||
b = pvPortMalloc(40U);
|
||||
c = pvPortMalloc(16U);
|
||||
g_after_allocations = xPortGetFreeHeapSize();
|
||||
g_allocations_aligned =
|
||||
a != NULL && b != NULL && c != NULL &&
|
||||
((uintptr_t)a % portBYTE_ALIGNMENT) == 0U &&
|
||||
((uintptr_t)b % portBYTE_ALIGNMENT) == 0U &&
|
||||
((uintptr_t)c % portBYTE_ALIGNMENT) == 0U;
|
||||
|
||||
vPortFree(a);
|
||||
vPortFree(c);
|
||||
vPortGetHeapStats(&g_fragmented_stats);
|
||||
heap4_fragmented_checkpoint();
|
||||
|
||||
vPortFree(b);
|
||||
g_final_free = xPortGetFreeHeapSize();
|
||||
g_minimum_ever_free = xPortGetMinimumEverFreeHeapSize();
|
||||
vPortGetHeapStats(&g_final_stats);
|
||||
|
||||
too_large = pvPortMalloc(configTOTAL_HEAP_SIZE * 2U);
|
||||
g_oom_is_null = too_large == NULL;
|
||||
g_task03_pass =
|
||||
probe != NULL && g_allocations_aligned &&
|
||||
g_initial_free > g_after_allocations &&
|
||||
g_final_free == g_initial_free &&
|
||||
g_minimum_ever_free <= g_after_allocations &&
|
||||
g_fragmented_stats.xNumberOfFreeBlocks == 2U &&
|
||||
g_final_stats.xNumberOfFreeBlocks == 1U &&
|
||||
g_final_stats.xSizeOfLargestFreeBlockInBytes == g_initial_free &&
|
||||
g_oom_is_null && g_malloc_failed_hooks == 1 &&
|
||||
g_assert_failures == 0;
|
||||
|
||||
task03_debug_checkpoint();
|
||||
|
||||
#if defined(HOST_PRINTF)
|
||||
printf("initial=%zu after=%zu fragmented=%zu final=%zu min=%zu "
|
||||
"aligned=%d oom=%d hooks=%d asserts=%d pass=%d\n",
|
||||
g_initial_free, g_after_allocations,
|
||||
g_fragmented_stats.xNumberOfFreeBlocks, g_final_free,
|
||||
g_minimum_ever_free, g_allocations_aligned, g_oom_is_null,
|
||||
g_malloc_failed_hooks, g_assert_failures, g_task03_pass);
|
||||
#endif
|
||||
return g_task03_pass ? 0 : 1;
|
||||
}
|
||||
Reference in New Issue
Block a user