From 1f571f48e5c3cf823f068e464324ff218314498f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 16 Aug 2020 21:29:14 +0100 Subject: [PATCH] Add `mem.Tracking_Allocator` --- core/mem/alloc.odin | 2 +- core/mem/allocators.odin | 68 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/core/mem/alloc.odin b/core/mem/alloc.odin index dbabc2138..80969aa1f 100644 --- a/core/mem/alloc.odin +++ b/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; } diff --git a/core/mem/allocators.odin b/core/mem/allocators.odin index 6d3d281bc..3a6b95396 100644 --- a/core/mem/allocators.odin +++ b/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; +}