73 lines
2.1 KiB
C
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;
|
|
}
|