Files
lab-rv32i-freertos-heap4/src/tasks/task01_first_fit_split.c
T

73 lines
2.1 KiB
C

#include "heap4_model.h"
enum {
ARENA_BYTES = 256,
REQUEST_BYTES = 13,
WANTED_BYTES = (sizeof(ModelBlock) + REQUEST_BYTES + 7U) & ~7U
};
typedef struct {
ModelBlock allocated;
uint8_t payload[WANTED_BYTES - sizeof(ModelBlock)];
ModelBlock remainder;
uint8_t free_payload[ARENA_BYTES - WANTED_BYTES - sizeof(ModelBlock)];
} SplitArena;
typedef union {
uint64_t force_alignment;
SplitArena blocks;
} AlignedSplitArena;
AlignedSplitArena g_split_arena;
ModelBlock *g_free_head;
volatile size_t g_header_bytes;
volatile size_t g_wanted_bytes;
volatile size_t g_remainder_bytes;
volatile size_t g_payload_offset;
volatile int g_split_addresses_aligned;
volatile int g_task01_pass;
__attribute__((noinline)) void task01_debug_checkpoint(void)
{
#if defined(__GNUC__)
__asm__ volatile("" ::: "memory");
#endif
}
int main(void)
{
SplitArena *arena = &g_split_arena.blocks;
uintptr_t base = (uintptr_t)&arena->allocated;
uintptr_t remainder = (uintptr_t)&arena->remainder;
arena->allocated.next = NULL;
arena->allocated.size = WANTED_BYTES;
arena->remainder.next = NULL;
arena->remainder.size = ARENA_BYTES - WANTED_BYTES;
arena->payload[0] = (uint8_t)'A';
g_free_head = &arena->remainder;
g_header_bytes = sizeof(ModelBlock);
g_wanted_bytes = WANTED_BYTES;
g_remainder_bytes = arena->remainder.size;
g_payload_offset = (size_t)((uintptr_t)&arena->payload[0] - base);
g_split_addresses_aligned =
(base % MODEL_ALIGNMENT) == 0U &&
(remainder % MODEL_ALIGNMENT) == 0U;
g_task01_pass =
g_wanted_bytes == model_align_up(sizeof(ModelBlock) + REQUEST_BYTES) &&
(size_t)(remainder - base) == g_wanted_bytes &&
g_remainder_bytes + g_wanted_bytes == ARENA_BYTES &&
g_payload_offset == sizeof(ModelBlock) &&
g_split_addresses_aligned;
task01_debug_checkpoint();
#if defined(HOST_PRINTF)
printf("header=%zu wanted=%zu remainder=%zu payload=%zu aligned=%d pass=%d\n",
g_header_bytes, g_wanted_bytes, g_remainder_bytes,
g_payload_offset, g_split_addresses_aligned, g_task01_pass);
#endif
return g_task01_pass ? 0 : 1;
}