Commit 8eeda17

kravantokh <kravantokh@noreply.codeberg.org>
2026-03-10 15:19:40
Make arenas work correctly.
1 parent 138e2db
memory/arenas.h
@@ -25,6 +25,8 @@ MemArena MemArena_from( MemArena *arena ); /* Get a sub arena, with a new arena
 
 status MemArena_take_amount( MemArena *arena, u64 size, void** out );
 #define MemArena_take( arena, type, count, out ) MemArena_take_amount( arena, (sizeof(type))*(count), out )
+status MemArena_give_amount( MemArena *arena, u64 size );
+#define MemArena_give( arena, type, count ) MemArena_give_amount( arena, (sizeof(type))*(count) )
 
 void MemArena_clear( MemArena *arena );
 status MemArena_uncommit_unused( MemArena *arena );
@@ -96,9 +98,10 @@ status MemArena_uncommit_unused( MemArena *arena );
 		}
 
 		arena->last_commited = (void*)new_committed;
+		arena->top += (allocation - (u64)arena->top + size);
 
 		#if defined(KC_ZERO_MEMORY_STRICT)
-			mem_set( arena->top, arena->end - arena->top, 0 );
+			mem_set_range( arena->top, arena->end, 0 );
 		#endif
 
 		*outptr = (void*)allocation;
@@ -106,11 +109,29 @@ status MemArena_uncommit_unused( MemArena *arena );
 		return STATUS_SUCCESS;
 	}
 
+	status MemArena_give_amount( MemArena *arena, u64 size ) {
+		ASSERT_MEM_ARENA_IS_SANE(arena);
+		assert(size);
+
+		if( size > (u64)(arena->top - arena->start) ) {
+			return ERROR_WOULD_UNDERRUN;
+		}
+
+		u8* new_top = arena->top - size;
+		arena->top = new_top;
+
+		#if defined(KC_ZERO_MEMORY_STRICT)
+			mem_set_range( new_top, arena->top, 0 );
+		#endif
+
+		return STATUS_SUCCESS;
+	}
+
 	void MemArena_clear( MemArena *arena ) {
 		ASSERT_MEM_ARENA_IS_SANE(arena);
 
 		#if defined(KC_ZERO_MEMORY_STRICT)
-			mem_set( arena->start, arena->end - arena->start, 0 );
+			mem_set_range( arena->start, arena->end, 0 );
 		#endif
 
 		arena->top = arena->start;
@@ -119,14 +140,15 @@ status MemArena_uncommit_unused( MemArena *arena );
 	status MemArena_uncommit_unused( MemArena *arena ) {
 		ASSERT_MEM_ARENA_IS_SANE(arena);
 
+
+		u8* new_commited = (u8*)ROUND_UP_TO_A_POW2( (u64)arena->top, KC_PLATFORM_MEM_PAGESIZE );
+
 		#if defined(KC_ZERO_MEMORY_STRICT)
-			mem_set( arena->top, arena->end - arena->start, 0 );
+			mem_set_range( new_commited, arena->last_commited, 0 );
 		#endif
+		PROPAGATE_ERROR( kc_platform_mem_va_uncommit( new_commited,  arena->last_commited - new_commited ) );
 
-		u64 new_last_commit = ROUND_UP_TO_A_POW2( arena->top, KC_PLATFORM_MEM_PAGESIZE );
-
-		PROPAGATE_ERROR( kc_platform_mem_va_uncommit( (void*)new_last_commit, (u64)arena->last_commited - new_last_commit) );
-		arena->last_commited = (u8*)new_last_commit;
+		arena->last_commited = new_commited;
 
 		return STATUS_SUCCESS;
 	}
memory/ops.h
@@ -6,6 +6,6 @@
 status mem_copy( void *src, void *dst, u64 size );
 status mem_move( void *src, void *dst, u64 size );
 status mem_set( void *buf, u64 size, u8 value );
-
+status mem_set_range( void *start, void *end, u8 value );
 
 #endif
tests/a.out
Binary file
tests/main.c
@@ -10,7 +10,7 @@
 
 
 int main(void) {
-MemArena a;
+	MemArena a;
 
 	assert(OK( MemArena_create( &a, GiB(120) )) );
 
@@ -21,8 +21,11 @@ MemArena a;
 		data[i] = 'K';
 	}
 
-	MemArena_uncommit_unused( &a );
+	assert( OK(MemArena_give_amount( &a, MiB(512) ) ));
+	assert( OK(MemArena_uncommit_unused( &a )));
 
+	assert( OK(MemArena_give_amount( &a, MiB(512) ) ));
+	assert( OK(MemArena_uncommit_unused( &a )));
 
 	assert(OK(MemArena_destroy(&a)));
 }
tests/main.o
Binary file
types/types.h
@@ -18,6 +18,7 @@ enum _Status {
 	STATUS_SUCCESS = 0,
 	ERROR_GENERIC = 1,
 	ERROR_WOULD_OVERRUN = 2,
+	ERROR_WOULD_UNDERRUN = 3,
 
 	ERROR_PLATFORM_GENERIC = 10000,
 	ERROR_PLATFORM_MAPPING_FAILED = 10001,