Browse Source

Add `mem.Tracking_Allocator`

gingerBill 5 years ago
parent
commit
1f571f48e5
2 changed files with 69 additions and 1 deletions
  1. 1 1
      core/mem/alloc.odin
  2. 68 0
      core/mem/allocators.odin

+ 1 - 1
core/mem/alloc.odin

@@ -168,7 +168,7 @@ default_resize_align :: proc(old_memory: rawptr, old_size, new_size, alignment:
 	new_memory := alloc(new_size, alignment, allocator, loc);
 	if new_memory == nil do return nil;
 
-	copy(new_memory, old_memory, min(old_size, new_size));;
+	copy(new_memory, old_memory, min(old_size, new_size));
 	free(old_memory, allocator, loc);
 	return new_memory;
 }

+ 68 - 0
core/mem/allocators.odin

@@ -1,6 +1,7 @@
 package mem
 
 import "intrinsics"
+import "core:runtime"
 
 nil_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
                            size, alignment: int,
@@ -710,3 +711,70 @@ alloca_allocator :: proc() -> Allocator {
 		data = nil,
 	};
 }
+
+
+
+
+
+Tracking_Allocator_Entry :: struct {
+	memory:   rawptr,
+	size:     int,
+	location: runtime.Source_Code_Location,
+}
+Tracking_Allocator :: struct {
+	backing:           Allocator,
+	allocation_map:    map[rawptr]Tracking_Allocator_Entry,
+	clear_on_free_all: bool,
+}
+
+tracking_allocator_init :: proc(t: ^Tracking_Allocator, backing_allocator: Allocator, allocation_map_allocator := context.allocator) {
+	t.backing = backing_allocator;
+	t.allocation_map.allocator = allocation_map_allocator;
+}
+
+tracking_allocator_destroy :: proc(t: ^Tracking_Allocator) {
+	delete(t.allocation_map);
+}
+
+tracking_allocator :: proc(data: ^Tracking_Allocator) -> Allocator {
+	return Allocator{
+		data = data,
+		procedure = tracking_allocator_proc,
+	};
+}
+
+tracking_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, flags: u64 = 0, loc := #caller_location) -> rawptr {
+	data := (^Tracking_Allocator)(allocator_data);
+	result := data.backing.procedure(data.backing.data, mode, size, alignment, old_memory, old_size, flags, loc);
+
+	if data.allocation_map.allocator.procedure == nil {
+		data.allocation_map.allocator = context.allocator;
+	}
+
+	switch mode {
+	case .Alloc:
+		data.allocation_map[result] = Tracking_Allocator_Entry{
+			memory = result,
+			size = size,
+			location = loc,
+		};
+	case .Free:
+		delete_key(&data.allocation_map, old_memory);
+	case .Resize:
+		if old_memory != result {
+			delete_key(&data.allocation_map, old_memory);
+		}
+		data.allocation_map[result] = Tracking_Allocator_Entry{
+			memory = result,
+			size = size,
+			location = loc,
+		};
+
+	case .Free_All:
+		if data.clear_on_free_all {
+			clear_map(&data.allocation_map);
+		}
+	}
+
+	return result;
+}