瀏覽代碼

[mem]: Add resize_non_zeroed variant to dynamic arena, and rename pool to arena

flysand7 1 年之前
父節點
當前提交
b350a35b77
共有 1 個文件被更改,包括 76 次插入50 次删除
  1. 76 50
      core/mem/allocators.odin

+ 76 - 50
core/mem/allocators.odin

@@ -880,14 +880,14 @@ _dynamic_arena_cycle_new_block :: proc(p: ^Dynamic_Arena, loc := #caller_locatio
 }
 
 @(private, require_results)
-_dynamic_arena_alloc_ptr :: proc(pool: ^Dynamic_Arena, size: int, loc := #caller_location) -> (rawptr, Allocator_Error) {
-	data, err := dynamic_arena_alloc(pool, size, loc)
+_dynamic_arena_alloc_ptr :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> (rawptr, Allocator_Error) {
+	data, err := dynamic_arena_alloc(a, size, loc)
 	return raw_data(data), err
 }
 
 @(require_results)
-dynamic_arena_alloc :: proc(p: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
-	bytes, err := dynamic_arena_alloc_non_zeroed(p, size, loc)
+dynamic_arena_alloc :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
+	bytes, err := dynamic_arena_alloc_non_zeroed(a, size, loc)
 	if bytes != nil {
 		zero_slice(bytes)
 	}
@@ -895,56 +895,91 @@ dynamic_arena_alloc :: proc(p: ^Dynamic_Arena, size: int, loc := #caller_locatio
 }
 
 @(require_results)
-dynamic_arena_alloc_non_zeroed :: proc(p: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
-	n := align_formula(size, p.alignment)
-	if n > p.block_size {
+dynamic_arena_alloc_non_zeroed :: proc(a: ^Dynamic_Arena, size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
+	n := align_formula(size, a.alignment)
+	if n > a.block_size {
 		return nil, .Invalid_Argument
 	}
-	if n >= p.out_band_size {
-		assert(p.block_allocator.procedure != nil, "Backing block allocator must be initialized", loc=loc)
-		memory, err := alloc_bytes_non_zeroed(p.block_size, p.alignment, p.block_allocator, loc)
+	if n >= a.out_band_size {
+		assert(a.block_allocator.procedure != nil, "Backing block allocator must be initialized", loc=loc)
+		memory, err := alloc_bytes_non_zeroed(a.block_size, a.alignment, a.block_allocator, loc)
 		if memory != nil {
-			append(&p.out_band_allocations, raw_data(memory), loc = loc)
+			append(&a.out_band_allocations, raw_data(memory), loc = loc)
 		}
 		return memory, err
 	}
-	if p.bytes_left < n {
-		err := _dynamic_arena_cycle_new_block(p, loc)
+	if a.bytes_left < n {
+		err := _dynamic_arena_cycle_new_block(a, loc)
 		if err != nil {
 			return nil, err
 		}
-		if p.current_block == nil {
+		if a.current_block == nil {
 			return nil, .Out_Of_Memory
 		}
 	}
-	memory := p.current_pos
-	p.current_pos = ([^]byte)(p.current_pos)[n:]
-	p.bytes_left -= n
+	memory := a.current_pos
+	a.current_pos = ([^]byte)(a.current_pos)[n:]
+	a.bytes_left -= n
 	return ([^]byte)(memory)[:size], nil
 }
 
-dynamic_arena_reset :: proc(p: ^Dynamic_Arena, loc := #caller_location) {
-	if p.current_block != nil {
-		append(&p.unused_blocks, p.current_block, loc=loc)
-		p.current_block = nil
+dynamic_arena_reset :: proc(a: ^Dynamic_Arena, loc := #caller_location) {
+	if a.current_block != nil {
+		append(&a.unused_blocks, a.current_block, loc=loc)
+		a.current_block = nil
+	}
+	for block in a.used_blocks {
+		append(&a.unused_blocks, block, loc=loc)
+	}
+	clear(&a.used_blocks)
+	for a in a.out_band_allocations {
+		free(a, a.block_allocator, loc=loc)
 	}
-	for block in p.used_blocks {
-		append(&p.unused_blocks, block, loc=loc)
+	clear(&a.out_band_allocations)
+	a.bytes_left = 0 // Make new allocations call `_dynamic_arena_cycle_new_block` again.
+}
+
+dynamic_arena_free_all :: proc(a: ^Dynamic_Arena, loc := #caller_location) {
+	dynamic_arena_reset(a)
+	for block in a.unused_blocks {
+		free(block, a.block_allocator, loc)
 	}
-	clear(&p.used_blocks)
-	for a in p.out_band_allocations {
-		free(a, p.block_allocator, loc=loc)
+	clear(&a.unused_blocks)
+}
+
+dynamic_arena_resize :: proc(
+	a: ^Dynamic_Arena,
+	old_memory: rawptr,
+	old_size: int,
+	size: int,
+	loc := #caller_location,
+) -> ([]byte, Allocator_Error) {
+	bytes, err := dynamic_arena_resize_non_zeroed(a, old_memory, old_size, size, loc)
+	if bytes != nil {
+		if old_memory == nil {
+			zero_slice(bytes)
+		} else if size > old_size {
+			zero_slice(bytes[old_size:])
+		}
 	}
-	clear(&p.out_band_allocations)
-	p.bytes_left = 0 // Make new allocations call `_dynamic_arena_cycle_new_block` again.
+	return bytes, err
 }
 
-dynamic_arena_free_all :: proc(p: ^Dynamic_Arena) {
-	dynamic_arena_reset(p)
-	for block in p.unused_blocks {
-		free(block, p.block_allocator)
+dynamic_arena_resize_non_zeroed :: proc(
+	a: ^Dynamic_Arena,
+	old_memory: rawptr,
+	old_size: int,
+	size: int,
+	loc := #caller_location,
+) -> ([]byte, Allocator_Error) {
+	if old_size >= size {
+		return byte_slice(old_memory, size), nil
 	}
-	clear(&p.unused_blocks)
+	data, err := dynamic_arena_alloc_non_zeroed(a, size, loc)
+	if err == nil {
+		runtime.copy(data, byte_slice(old_memory, old_size))
+	}
+	return data, err
 }
 
 dynamic_arena_allocator_proc :: proc(
@@ -956,35 +991,26 @@ dynamic_arena_allocator_proc :: proc(
 	old_size: int,
 	loc := #caller_location,
 ) -> ([]byte, Allocator_Error) {
-	pool := (^Dynamic_Arena)(allocator_data)
-
+	arena := (^Dynamic_Arena)(allocator_data)
 	switch mode {
 	case .Alloc:
-		return dynamic_arena_alloc(pool, size, loc)
+		return dynamic_arena_alloc(arena, size, loc)
 	case .Alloc_Non_Zeroed:
-		return dynamic_arena_alloc_non_zeroed(pool, size, loc)
+		return dynamic_arena_alloc_non_zeroed(arena, size, loc)
 	case .Free:
 		return nil, .Mode_Not_Implemented
 	case .Free_All:
-		dynamic_arena_free_all(pool)
-		return nil, nil
-	case .Resize, .Resize_Non_Zeroed:
-		if old_size >= size {
-			return byte_slice(old_memory, size), nil
-		}
-		data, err := dynamic_arena_alloc(pool, size)
-		if err == nil {
-			runtime.copy(data, byte_slice(old_memory, old_size))
-		}
-		return data, err
-
+		dynamic_arena_free_all(arena, loc)
+	case .Resize:
+		return dynamic_arena_resize(arena, old_memory, old_size, size, loc)
+	case .Resize_Non_Zeroed:
+		return dynamic_arena_resize_non_zeroed(arena, old_memory, old_size, size, loc)
 	case .Query_Features:
 		set := (^Allocator_Mode_Set)(old_memory)
 		if set != nil {
 			set^ = {.Alloc, .Alloc_Non_Zeroed, .Free_All, .Resize, .Resize_Non_Zeroed, .Query_Features, .Query_Info}
 		}
 		return nil, nil
-
 	case .Query_Info:
 		info := (^Allocator_Query_Info)(old_memory)
 		if info != nil && info.pointer != nil {