#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; }