From 62ae217a27531d9767bcdda0e7ff6c4368ed857e Mon Sep 17 00:00:00 2001 From: steven-na Date: Wed, 29 Jul 2026 01:53:59 -0700 Subject: Scratch and temp arenas --- tests/smrt_arena.c | 133 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 115 insertions(+), 18 deletions(-) (limited to 'tests') diff --git a/tests/smrt_arena.c b/tests/smrt_arena.c index 87230d3..5e3ef5c 100644 --- a/tests/smrt_arena.c +++ b/tests/smrt_arena.c @@ -18,7 +18,7 @@ Test(smrt_arena, create_arena) { } Test(smrt_arena, alloc_arena) { - smrt_arena_t *arena = smrt_arena_create(sizeof(uint32_t), true, false); + smrt_arena_t *arena = smrt_arena_create(sizeof(uint32_t), plat_get_pagesize(), false); uint32_t *i = smrt_arena_push(arena, sizeof(uint32_t), true); @@ -30,7 +30,7 @@ Test(smrt_arena, alloc_arena) { } Test(smrt_arena, alloc_zero_arena) { - smrt_arena_t *arena = smrt_arena_create(sizeof(uint32_t), true, false); + smrt_arena_t *arena = smrt_arena_create(sizeof(uint32_t), plat_get_pagesize(), false); uint32_t *i = smrt_arena_push(arena, sizeof(uint32_t), true); @@ -43,7 +43,7 @@ Test(smrt_arena, alloc_array_arena) { const size_t len = 24; cr_expect(len != 0); - smrt_arena_t *arena = smrt_arena_create(sizeof(uint8_t) * len, true, false); + smrt_arena_t *arena = smrt_arena_create(sizeof(uint8_t) * len, plat_get_pagesize(), false); uint8_t *arr = SMRTA_ALLOC_ARRAY(arena, uint8_t, len); @@ -58,7 +58,7 @@ Test(smrt_arena, alloc_array_arena) { } Test(smrt_arena, alloc_clear_arena) { - smrt_arena_t *arena = smrt_arena_create(sizeof(uint32_t), true, false); + smrt_arena_t *arena = smrt_arena_create(sizeof(uint32_t), plat_get_pagesize(), false); uint32_t *i = smrt_arena_push(arena, sizeof(uint32_t), true); @@ -72,7 +72,7 @@ Test(smrt_arena, alloc_clear_arena) { } Test(smrt_arena, alloc_clear_zero_arena) { - smrt_arena_t *arena = smrt_arena_create(sizeof(uint32_t), true, false); + smrt_arena_t *arena = smrt_arena_create(sizeof(uint32_t), plat_get_pagesize(), false); uint32_t *i = smrt_arena_push(arena, sizeof(uint32_t), true); @@ -95,7 +95,7 @@ Test(smrt_arena, alloc_clear_zero_arena) { } Test(smrt_arena, alloc_clear_dont_zero_arena) { - smrt_arena_t *arena = smrt_arena_create(sizeof(uint32_t), true, false); + smrt_arena_t *arena = smrt_arena_create(sizeof(uint32_t), plat_get_pagesize(), false); uint32_t *i = smrt_arena_push(arena, sizeof(uint32_t), true); @@ -109,7 +109,7 @@ Test(smrt_arena, alloc_clear_dont_zero_arena) { } Test(smrt_arena, pop_arena) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); uint64_t mark = arena->pos; uint32_t *i = smrt_arena_push(arena, sizeof(uint32_t), true); @@ -124,7 +124,7 @@ Test(smrt_arena, pop_arena) { } Test(smrt_arena, pop_to_arena) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); smrt_arena_push(arena, sizeof(uint32_t), true); uint64_t mark = arena->pos; @@ -139,7 +139,7 @@ Test(smrt_arena, pop_to_arena) { } Test(smrt_arena, pop_clamped_arena) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); smrt_arena_push(arena, sizeof(uint32_t), true); smrt_arena_pop(arena, KiB(1)); @@ -164,7 +164,7 @@ Test(smrt_arena, push_grows_commit_arena) { } Test(smrt_arena, push_exceeds_reserve_arena) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); void *p = smrt_arena_push(arena, KiB(64), true); @@ -174,7 +174,7 @@ Test(smrt_arena, push_exceeds_reserve_arena) { } Test(smrt_arena, push_alignment_arena) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); smrt_arena_push(arena, sizeof(uint8_t), true); void *p = smrt_arena_push(arena, sizeof(uint64_t), true); @@ -185,13 +185,13 @@ Test(smrt_arena, push_alignment_arena) { } Test(smrt_arena, create_fails_when_reserve_exceeds_address_space) { - smrt_arena_t *arena = smrt_arena_create((u64)1 << 48, true, false); + smrt_arena_t *arena = smrt_arena_create((u64)1 << 48, plat_get_pagesize(), false); cr_expect_eq(arena, NULL); } Test(smrt_arena, mark_push_sets_mark) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); uint64_t pre_mark_pos = arena->pos; smrt_arena_mark_push(arena, sizeof(uint32_t), true); @@ -202,7 +202,7 @@ Test(smrt_arena, mark_push_sets_mark) { } Test(smrt_arena, mark_push_failure_leaves_mark_unset) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); void *p = smrt_arena_mark_push(arena, KiB(64), true); @@ -213,7 +213,7 @@ Test(smrt_arena, mark_push_failure_leaves_mark_unset) { } Test(smrt_arena, pop_to_mark_restores_position) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); uint32_t *i = smrt_arena_mark_push(arena, sizeof(uint32_t), true); smrt_arena_push(arena, sizeof(uint32_t), true); @@ -229,7 +229,7 @@ Test(smrt_arena, pop_to_mark_restores_position) { } Test(smrt_arena, mark_at_base_position_is_valid) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); cr_assert_eq(arena->pos, SMRT_ARENA_BASE_POS); @@ -246,7 +246,7 @@ Test(smrt_arena, mark_at_base_position_is_valid) { } Test(smrt_arena, pop_to_mark_without_mark_fails) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); smrt_arena_push(arena, sizeof(uint32_t), true); @@ -258,7 +258,7 @@ Test(smrt_arena, pop_to_mark_without_mark_fails) { } Test(smrt_arena, pop_to_ahead_of_pos_is_noop) { - smrt_arena_t *arena = smrt_arena_create(KiB(1), true, false); + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); smrt_arena_push(arena, sizeof(uint32_t), true); uint64_t pos = arena->pos; @@ -348,6 +348,103 @@ Test(smrt_arena, auto_decommit_pop_past_mark_resets_mark) { smrt_arena_destroy(arena); } +Test(smrt_arena, mark_sets_current_pos) { + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); + + smrt_arena_push(arena, sizeof(uint32_t), true); + uint64_t pos = arena->pos; + + smrt_arena_mark(arena); + + cr_expect_eq(arena->mark_pos, pos); + + smrt_arena_destroy(arena); +} + +Test(smrt_arena, temp_start_captures_arena_and_pos) { + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); + smrt_arena_push(arena, sizeof(uint32_t), true); + + smrta_temp_t temp = smrta_temp_start(arena); + + cr_expect_eq(temp.arena, arena); + cr_expect_eq(temp.start_pos, arena->pos); + + smrt_arena_destroy(arena); +} + +Test(smrt_arena, temp_start_end_restores_position) { + smrt_arena_t *arena = smrt_arena_create(KiB(1), plat_get_pagesize(), false); + + smrt_arena_push(arena, sizeof(uint32_t), true); + uint64_t pos_before = arena->pos; + + smrta_temp_t temp = smrta_temp_start(arena); + smrt_arena_push(arena, sizeof(uint32_t), true); + smrt_arena_push(arena, sizeof(uint32_t), true); + + smrta_temp_end(temp); + + cr_expect_eq(arena->pos, pos_before); + + smrt_arena_destroy(arena); +} + +Test(smrt_arena, scratch_start_end_provides_usable_arena) { + smrta_temp_t scratch = smrta_scratch_start(NULL, 0); + + cr_assert_neq(scratch.arena, NULL); + + uint32_t *i = TEMP_ARENA_PUSH(scratch, uint32_t); + *i = UINT32_MAX; + + cr_expect_eq(*i, UINT32_MAX); + + smrta_scratch_end(scratch); +} + +Test(smrt_arena, scratch_end_pops_arena_to_start) { + smrta_temp_t scratch = smrta_scratch_start(NULL, 0); + uint64_t pos_before = scratch.arena->pos; + + TEMP_ARENA_PUSH(scratch, uint32_t); + cr_assert_gt(scratch.arena->pos, pos_before); + + smrta_scratch_end(scratch); + + cr_expect_eq(scratch.arena->pos, pos_before); +} + +Test(smrt_arena, scratch_start_avoids_conflicts) { + smrta_temp_t first = smrta_scratch_start(NULL, 0); + cr_assert_neq(first.arena, NULL); + + smrt_arena_t *conflicts[] = { first.arena }; + smrta_temp_t second = smrta_scratch_start(conflicts, 1); + + cr_assert_neq(second.arena, NULL); + cr_expect_neq(second.arena, first.arena); + + smrta_scratch_end(second); + smrta_scratch_end(first); +} + +Test(smrt_arena, scratch_start_returns_zeroed_when_pool_exhausted) { + smrta_temp_t a = smrta_scratch_start(NULL, 0); + + smrt_arena_t *a_conflict[] = { a.arena }; + smrta_temp_t b = smrta_scratch_start(a_conflict, 1); + cr_assert_neq(b.arena, a.arena); + + smrt_arena_t *conflicts[] = { a.arena, b.arena }; + smrta_temp_t c = smrta_scratch_start(conflicts, 2); + + cr_expect_eq(c.arena, NULL); + + smrta_scratch_end(b); + smrta_scratch_end(a); +} + Test(smrt_arena, decommit_then_recommit_pages) { u32 pagesize = plat_get_pagesize(); void *mem = plat_mem_reserve(pagesize); -- cgit v1.2.3