diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2025-04-13 15:20:53 +0200 |
|---|---|---|
| committer | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2025-04-13 15:20:53 +0200 |
| commit | 0e9cd0fb6abab5b0ac8ef8328423594ebd8f2060 (patch) | |
| tree | cb2d479c0c196234b8ae94ec14d1a3b435e7e924 /core/mem | |
| parent | 74a66f7794ba5ba7b26128c9af483d9dd927fc66 (diff) | |
Prepare for `tlsf.free_all`
Diffstat (limited to 'core/mem')
| -rw-r--r-- | core/mem/tlsf/tlsf.odin | 23 | ||||
| -rw-r--r-- | core/mem/tlsf/tlsf_internal.odin | 5 |
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) |