diff --git a/base/runtime/default_temp_allocator_arena.odin b/base/runtime/default_temp_allocator_arena.odin index 6e2900411..5f25dac95 100644 --- a/base/runtime/default_temp_allocator_arena.odin +++ b/base/runtime/default_temp_allocator_arena.odin @@ -104,13 +104,15 @@ arena_alloc :: proc(arena: ^Arena, size, alignment: uint, loc := #caller_locatio if size == 0 { return } - - needed := align_forward_uint(size, alignment) - if arena.curr_block == nil || (safe_add(arena.curr_block.used, needed) or_else 0) > arena.curr_block.capacity { + + prev_used := 0 if arena.curr_block == nil else arena.curr_block.used + data, err = alloc_from_memory_block(arena.curr_block, size, alignment) + if err == .Out_Of_Memory { if arena.minimum_block_size == 0 { arena.minimum_block_size = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE } + needed := align_forward_uint(size, alignment) block_size := max(needed, arena.minimum_block_size) if arena.backing_allocator.procedure == nil { @@ -121,10 +123,9 @@ arena_alloc :: proc(arena: ^Arena, size, alignment: uint, loc := #caller_locatio new_block.prev = arena.curr_block arena.curr_block = new_block arena.total_capacity += new_block.capacity + prev_used = 0 + data, err = alloc_from_memory_block(arena.curr_block, size, alignment) } - - prev_used := arena.curr_block.used - data, err = alloc_from_memory_block(arena.curr_block, size, alignment) arena.total_used += arena.curr_block.used - prev_used return } diff --git a/core/mem/virtual/arena.odin b/core/mem/virtual/arena.odin index 5191505cf..73084f77b 100644 --- a/core/mem/virtual/arena.odin +++ b/core/mem/virtual/arena.odin @@ -107,8 +107,9 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l switch arena.kind { case .Growing: - needed := mem.align_forward_uint(size, alignment) - if arena.curr_block == nil || (safe_add(arena.curr_block.used, needed) or_else 0) > arena.curr_block.reserved { + prev_used := 0 if arena.curr_block == nil else arena.curr_block.used + data, err = alloc_from_memory_block(arena.curr_block, size, alignment, default_commit_size=arena.default_commit_size) + if err == .Out_Of_Memory { if arena.minimum_block_size == 0 { arena.minimum_block_size = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE arena.minimum_block_size = mem.align_forward_uint(arena.minimum_block_size, DEFAULT_PAGE_SIZE) @@ -124,6 +125,7 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l max(arena.default_commit_size, arena.minimum_block_size) } + needed := mem.align_forward_uint(size, alignment) needed = max(needed, arena.default_commit_size) block_size := max(needed, arena.minimum_block_size) @@ -131,10 +133,10 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l new_block.prev = arena.curr_block arena.curr_block = new_block arena.total_reserved += new_block.reserved - } - prev_used := arena.curr_block.used - data, err = alloc_from_memory_block(arena.curr_block, size, alignment, default_commit_size=arena.default_commit_size) + prev_used = 0 + data, err = alloc_from_memory_block(arena.curr_block, size, alignment, default_commit_size=arena.default_commit_size) + } arena.total_used += arena.curr_block.used - prev_used case .Static: if arena.curr_block == nil { diff --git a/tests/core/mem/test_core_mem.odin b/tests/core/mem/test_core_mem.odin index d282ae1fd..3a1517747 100644 --- a/tests/core/mem/test_core_mem.odin +++ b/tests/core/mem/test_core_mem.odin @@ -1,6 +1,7 @@ package test_core_mem import "core:mem/tlsf" +import "core:mem/virtual" import "core:testing" @test @@ -38,4 +39,17 @@ test_tlsf_bitscan :: proc(t: ^testing.T) { testing.expectf(t, res == test.exp, "Expected tlsf.fls_uint(0x%16x) == %v, got %v", test.v, test.exp, res) } } -} \ No newline at end of file +} + +@(test) +test_align_bumping_block_limit :: proc(t: ^testing.T) { + a: virtual.Arena + + data, err := virtual.arena_alloc(&a, 4193371, 1) + testing.expect_value(t, err, nil) + testing.expect(t, len(data) == 4193371) + + data, err = virtual.arena_alloc(&a, 896, 64) + testing.expect_value(t, err, nil) + testing.expect(t, len(data) == 896) +} diff --git a/tests/core/runtime/test_core_runtime.odin b/tests/core/runtime/test_core_runtime.odin index be6c24c72..0d02ae2d8 100644 --- a/tests/core/runtime/test_core_runtime.odin +++ b/tests/core/runtime/test_core_runtime.odin @@ -31,6 +31,20 @@ test_temp_allocator_big_alloc_and_alignment :: proc(t: ^testing.T) { testing.expect(t, err == nil) } +@(test) +test_align_bumping_block_limit :: proc(t: ^testing.T) { + a: runtime.Arena + a.minimum_block_size = 8*mem.Megabyte + + data, err := runtime.arena_alloc(&a, 4193371, 1) + testing.expect_value(t, err, nil) + testing.expect(t, len(data) == 4193371) + + data, err = runtime.arena_alloc(&a, 896, 64) + testing.expect_value(t, err, nil) + testing.expect(t, len(data) == 896) +} + @(test) test_temp_allocator_returns_correct_size :: proc(t: ^testing.T) { arena: runtime.Arena