Procházet zdrojové kódy

Prepare for `tlsf.free_all`

Jeroen van Rijn před 5 měsíci
rodič
revize
0e9cd0fb6a
2 změnil soubory, kde provedl 18 přidání a 10 odebrání
  1. 16 7
      core/mem/tlsf/tlsf.odin
  2. 2 3
      core/mem/tlsf/tlsf_internal.odin

+ 16 - 7
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}
 

+ 2 - 3
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)