aboutsummaryrefslogtreecommitdiff
path: root/core/mem
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2025-04-13 15:20:53 +0200
committerJeroen van Rijn <Kelimion@users.noreply.github.com>2025-04-13 15:20:53 +0200
commit0e9cd0fb6abab5b0ac8ef8328423594ebd8f2060 (patch)
treecb2d479c0c196234b8ae94ec14d1a3b435e7e924 /core/mem
parent74a66f7794ba5ba7b26128c9af483d9dd927fc66 (diff)
Prepare for `tlsf.free_all`
Diffstat (limited to 'core/mem')
-rw-r--r--core/mem/tlsf/tlsf.odin23
-rw-r--r--core/mem/tlsf/tlsf_internal.odin5
2 files changed, 18 insertions, 10 deletions
diff --git a/core/mem/tlsf/tlsf.odin b/core/mem/tlsf/tlsf.odin
index 8ec5f52b7..a525f5113 100644
--- a/core/mem/tlsf/tlsf.odin
+++ b/core/mem/tlsf/tlsf.odin
@@ -39,11 +39,13 @@ Allocator :: struct {
// statistics like how much memory is still available,
// fragmentation, etc.
pool: Pool,
-}
-#assert(size_of(Allocator) % ALIGN_SIZE == 0)
-
+ // If we're expected to grow when we run out of memory,
+ // how much should we ask the backing allocator for?
+ new_pool_size: int,
+}
+#assert(size_of(Allocator) % ALIGN_SIZE == 0)
@(require_results)
allocator :: proc(t: ^Allocator) -> runtime.Allocator {
@@ -60,13 +62,18 @@ init_from_buffer :: proc(control: ^Allocator, buf: []byte) -> Error {
return .Invalid_Alignment
}
- pool_bytes := align_down(len(buf) - POOL_OVERHEAD, ALIGN_SIZE)
+ pool_bytes := align_down(len(buf), ALIGN_SIZE) - INITIAL_POOL_OVERHEAD
if pool_bytes < BLOCK_SIZE_MIN {
return .Backing_Buffer_Too_Small
} else if pool_bytes > BLOCK_SIZE_MAX {
return .Backing_Buffer_Too_Large
}
+ control.pool = Pool{
+ data = buf,
+ allocator = {},
+ }
+
clear(control)
return pool_add(control, buf[:])
}
@@ -74,7 +81,7 @@ init_from_buffer :: proc(control: ^Allocator, buf: []byte) -> Error {
@(require_results)
init_from_allocator :: proc(control: ^Allocator, backing: runtime.Allocator, initial_pool_size: int, new_pool_size := 0) -> Error {
assert(control != nil)
- pool_bytes := align_up(uint(initial_pool_size) + POOL_OVERHEAD, ALIGN_SIZE)
+ pool_bytes := align_up(uint(initial_pool_size), ALIGN_SIZE) + INITIAL_POOL_OVERHEAD
if pool_bytes < BLOCK_SIZE_MIN {
return .Backing_Buffer_Too_Small
} else if pool_bytes > BLOCK_SIZE_MAX {
@@ -85,12 +92,14 @@ init_from_allocator :: proc(control: ^Allocator, backing: runtime.Allocator, ini
if backing_err != nil {
return .Backing_Allocator_Error
}
- err := init_from_buffer(control, buf)
+
control.pool = Pool{
data = buf,
allocator = backing,
}
- return err
+
+ clear(control)
+ return pool_add(control, buf[:])
}
init :: proc{init_from_buffer, init_from_allocator}
diff --git a/core/mem/tlsf/tlsf_internal.odin b/core/mem/tlsf/tlsf_internal.odin
index 66141fcbb..1f04515bf 100644
--- a/core/mem/tlsf/tlsf_internal.odin
+++ b/core/mem/tlsf/tlsf_internal.odin
@@ -12,7 +12,6 @@ package mem_tlsf
import "base:intrinsics"
import "base:runtime"
-// import "core:fmt"
// log2 of number of linear subdivisions of block sizes.
// Larger values require more memory in the control structure.
@@ -58,7 +57,6 @@ Pool :: struct {
next: ^Pool,
}
-
/*
Block header structure.
@@ -95,6 +93,7 @@ The `prev_phys_block` field is stored *inside* the previous free block.
BLOCK_HEADER_OVERHEAD :: uint(size_of(uint))
POOL_OVERHEAD :: 2 * BLOCK_HEADER_OVERHEAD
+INITIAL_POOL_OVERHEAD :: 48
// User data starts directly after the size field in a used block.
BLOCK_START_OFFSET :: offset_of(Block_Header, size) + size_of(Block_Header{}.size)
@@ -114,7 +113,7 @@ BLOCK_SIZE_MAX :: uint(1) << FL_INDEX_MAX
queries using bitmasks and architecture-specific bit-manipulation
routines.
- NOTE: TLSF spec relies on ffs/fls returning value 0..31.
+ NOTE: TLSF spec relies on ffs/fls returning a value in the range 0..31.
*/
@(require_results)