mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Prepare for tlsf.free_all
This commit is contained in:
+16
-7
@@ -39,12 +39,14 @@ Allocator :: struct {
|
|||||||
// statistics like how much memory is still available,
|
// statistics like how much memory is still available,
|
||||||
// fragmentation, etc.
|
// fragmentation, etc.
|
||||||
pool: Pool,
|
pool: Pool,
|
||||||
|
|
||||||
|
// 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)
|
#assert(size_of(Allocator) % ALIGN_SIZE == 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
allocator :: proc(t: ^Allocator) -> runtime.Allocator {
|
allocator :: proc(t: ^Allocator) -> runtime.Allocator {
|
||||||
return runtime.Allocator{
|
return runtime.Allocator{
|
||||||
@@ -60,13 +62,18 @@ init_from_buffer :: proc(control: ^Allocator, buf: []byte) -> Error {
|
|||||||
return .Invalid_Alignment
|
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 {
|
if pool_bytes < BLOCK_SIZE_MIN {
|
||||||
return .Backing_Buffer_Too_Small
|
return .Backing_Buffer_Too_Small
|
||||||
} else if pool_bytes > BLOCK_SIZE_MAX {
|
} else if pool_bytes > BLOCK_SIZE_MAX {
|
||||||
return .Backing_Buffer_Too_Large
|
return .Backing_Buffer_Too_Large
|
||||||
}
|
}
|
||||||
|
|
||||||
|
control.pool = Pool{
|
||||||
|
data = buf,
|
||||||
|
allocator = {},
|
||||||
|
}
|
||||||
|
|
||||||
clear(control)
|
clear(control)
|
||||||
return pool_add(control, buf[:])
|
return pool_add(control, buf[:])
|
||||||
}
|
}
|
||||||
@@ -74,7 +81,7 @@ init_from_buffer :: proc(control: ^Allocator, buf: []byte) -> Error {
|
|||||||
@(require_results)
|
@(require_results)
|
||||||
init_from_allocator :: proc(control: ^Allocator, backing: runtime.Allocator, initial_pool_size: int, new_pool_size := 0) -> Error {
|
init_from_allocator :: proc(control: ^Allocator, backing: runtime.Allocator, initial_pool_size: int, new_pool_size := 0) -> Error {
|
||||||
assert(control != nil)
|
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 {
|
if pool_bytes < BLOCK_SIZE_MIN {
|
||||||
return .Backing_Buffer_Too_Small
|
return .Backing_Buffer_Too_Small
|
||||||
} else if pool_bytes > BLOCK_SIZE_MAX {
|
} 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 {
|
if backing_err != nil {
|
||||||
return .Backing_Allocator_Error
|
return .Backing_Allocator_Error
|
||||||
}
|
}
|
||||||
err := init_from_buffer(control, buf)
|
|
||||||
control.pool = Pool{
|
control.pool = Pool{
|
||||||
data = buf,
|
data = buf,
|
||||||
allocator = backing,
|
allocator = backing,
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
|
clear(control)
|
||||||
|
return pool_add(control, buf[:])
|
||||||
}
|
}
|
||||||
init :: proc{init_from_buffer, init_from_allocator}
|
init :: proc{init_from_buffer, init_from_allocator}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ package mem_tlsf
|
|||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
// import "core:fmt"
|
|
||||||
|
|
||||||
// log2 of number of linear subdivisions of block sizes.
|
// log2 of number of linear subdivisions of block sizes.
|
||||||
// Larger values require more memory in the control structure.
|
// Larger values require more memory in the control structure.
|
||||||
@@ -58,7 +57,6 @@ Pool :: struct {
|
|||||||
next: ^Pool,
|
next: ^Pool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Block header structure.
|
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))
|
BLOCK_HEADER_OVERHEAD :: uint(size_of(uint))
|
||||||
|
|
||||||
POOL_OVERHEAD :: 2 * BLOCK_HEADER_OVERHEAD
|
POOL_OVERHEAD :: 2 * BLOCK_HEADER_OVERHEAD
|
||||||
|
INITIAL_POOL_OVERHEAD :: 48
|
||||||
|
|
||||||
// User data starts directly after the size field in a used block.
|
// 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)
|
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
|
queries using bitmasks and architecture-specific bit-manipulation
|
||||||
routines.
|
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)
|
@(require_results)
|
||||||
|
|||||||
Reference in New Issue
Block a user