From 0fc141db5de0a635d7f20782e694636af18383f2 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Mon, 14 Apr 2025 20:40:05 +0200 Subject: [PATCH] `core:mem/tlsf`: Add early-out in OOM logic This implementation doesn't allow for out-of-band allocations to be passed through, as it's not designed to track those. Nor is it able to signal those allocations then need to be freed on the backing allocator, as opposed to regular allocations handled for you when you `destroy` the TLSF instance. So if we're asked for more than we're configured to grow by, we can fail with an OOM error early, without adding a new pool. --- core/mem/tlsf/tlsf_internal.odin | 14 +++++++++++++- tests/core/mem/test_core_mem.odin | 7 ++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/core/mem/tlsf/tlsf_internal.odin b/core/mem/tlsf/tlsf_internal.odin index 9aee2097d..f8a9bf60c 100644 --- a/core/mem/tlsf/tlsf_internal.odin +++ b/core/mem/tlsf/tlsf_internal.odin @@ -187,8 +187,20 @@ alloc_bytes_non_zeroed :: proc(control: ^Allocator, size: uint, align: uint) -> if block == nil { // OOM: Couldn't find block of `aligned_size` bytes. if control.new_pool_size > 0 && control.pool.allocator.procedure != nil { - // TLSF is configured to grow. Trying to allocate a new pool of `control.new_pool_size` bytes. + // TLSF is configured to grow. + /* + This implementation doesn't allow for out-of-band allocations to be passed through, as it's not designed to + track those. Nor is it able to signal those allocations then need to be freed on the backing allocator, + as opposed to regular allocations handled for you when you `destroy` the TLSF instance. + + So if we're asked for more than we're configured to grow by, we can fail with an OOM error early, without adding a new pool. + */ + if aligned_size > control.new_pool_size { + return nil, .Out_Of_Memory + } + + // Trying to allocate a new pool of `control.new_pool_size` bytes. new_pool_buf := runtime.make_aligned([]byte, control.new_pool_size, ALIGN_SIZE, control.pool.allocator) or_return // Add new pool to control structure diff --git a/tests/core/mem/test_core_mem.odin b/tests/core/mem/test_core_mem.odin index d50d15999..bd072b4e9 100644 --- a/tests/core/mem/test_core_mem.odin +++ b/tests/core/mem/test_core_mem.odin @@ -111,11 +111,8 @@ tlsf_test_grow_pools :: proc(t: ^testing.T) { } context.allocator = tlsf.allocator(&alloc) - err: mem.Allocator_Error - s: []byte - - for err == .None && len(allocations) < NUM_ALLOCATIONS { - s, err = make([]byte, ALLOC_SIZE) + for len(allocations) < NUM_ALLOCATIONS { + s := make([]byte, ALLOC_SIZE) or_break testing.expect_value(t, len(s), ALLOC_SIZE) append(&allocations, s) }