mem tracker updates
This commit is contained in:
parent
f9820457d1
commit
c405c47e6c
@ -57,7 +57,8 @@ hmap_chained_init :: proc( $HMapChainedType : typeid/HMapChained($Type), lookup_
|
||||
pool_bucket_cap : uint = 1 * Kilo,
|
||||
pool_bucket_reserve_num : uint = 0,
|
||||
pool_alignment : uint = mem.DEFAULT_ALIGNMENT,
|
||||
dbg_name : string = ""
|
||||
dbg_name : string = "",
|
||||
enable_mem_tracking : b32 = false,
|
||||
) -> (table : HMapChained(Type), error : AllocatorError)
|
||||
{
|
||||
header_size := size_of(HMapChainedHeader(Type))
|
||||
@ -75,7 +76,8 @@ hmap_chained_init :: proc( $HMapChainedType : typeid/HMapChained($Type), lookup_
|
||||
bucket_reserve_num = pool_bucket_reserve_num,
|
||||
alignment = pool_alignment,
|
||||
allocator = allocator,
|
||||
dbg_name = str_intern(str_fmt("%v: pool", dbg_name)).str
|
||||
dbg_name = str_intern(str_fmt("%v: pool", dbg_name)).str,
|
||||
enable_mem_tracking = enable_mem_tracking,
|
||||
)
|
||||
data := transmute([^] ^HMapChainedSlot(Type)) (transmute( [^]HMapChainedHeader(Type)) table.header)[1:]
|
||||
table.lookup = slice_ptr( data, int(lookup_capacity) )
|
||||
|
@ -13,11 +13,12 @@ MemoryTrackerEntry :: struct {
|
||||
}
|
||||
|
||||
MemoryTracker :: struct {
|
||||
parent : ^MemoryTracker,
|
||||
name : string,
|
||||
entries : Array(MemoryTrackerEntry),
|
||||
}
|
||||
|
||||
Track_Memory :: false
|
||||
Track_Memory :: true
|
||||
|
||||
memtracker_clear :: proc ( tracker : MemoryTracker ) {
|
||||
when ! Track_Memory {
|
||||
@ -69,17 +70,17 @@ memtracker_register :: proc( tracker : ^MemoryTracker, new_entry : MemoryTracker
|
||||
|
||||
if (entry.end < new_entry.start)
|
||||
{
|
||||
msg := str_fmt("Memory tracker(%v) detected a collision:\nold_entry: %v\nnew_entry: %v", tracker.name, entry, new_entry)
|
||||
msg := str_fmt("Detected a collision:\nold_entry: %v -> %v\nnew_entry: %v -> %v | %v", entry.start, entry.end, new_entry.start, new_entry.end, tracker.name )
|
||||
ensure( false, msg )
|
||||
memtracker_dump_entries(tracker ^)
|
||||
}
|
||||
array_append_at( & tracker.entries, new_entry, idx )
|
||||
logf("%v : Registered: %v", tracker.name, new_entry)
|
||||
logf("Registered: %v -> %v | %v", new_entry.start, new_entry.end, tracker.name)
|
||||
return
|
||||
}
|
||||
|
||||
array_append( & tracker.entries, new_entry )
|
||||
logf("%v : Registered: %v", tracker.name, new_entry)
|
||||
logf("Registered: %v -> %v | %v", new_entry.start, new_entry.end, tracker.name )
|
||||
}
|
||||
|
||||
memtracker_register_auto_name :: proc( tracker : ^MemoryTracker, start, end : rawptr )
|
||||
@ -117,17 +118,17 @@ memtracker_unregister :: proc( tracker : MemoryTracker, to_remove : MemoryTracke
|
||||
entry := & entries[idx]
|
||||
if entry.start == to_remove.start {
|
||||
if (entry.end == to_remove.end || to_remove.end == nil) {
|
||||
logf("%v: Unregistered: %v", tracker.name, to_remove);
|
||||
logf("Unregistered: %v -> %v | %v", to_remove.start, to_remove.end, tracker.name );
|
||||
array_remove_at(tracker.entries, idx)
|
||||
return
|
||||
}
|
||||
|
||||
ensure(false, str_fmt("%v: Found an entry with the same start address but end address was different:\nentry : %v\nto_remove: %v", tracker.name, entry, to_remove))
|
||||
ensure(false, str_fmt("Found an entry with the same start address but end address was different:\nentry : %v -> %v\nto_remove: %v -> %v | %v", entry.start, entry.end, to_remove.start, to_remove.end, tracker.name ))
|
||||
memtracker_dump_entries(tracker)
|
||||
}
|
||||
}
|
||||
|
||||
ensure(false, str_fmt("%v: Attempted to unregister an entry that was not tracked: %v", tracker.name, to_remove))
|
||||
ensure(false, str_fmt("Attempted to unregister an entry that was not tracked: %v -> %v | %v", to_remove.start, to_remove.end, tracker.name))
|
||||
memtracker_dump_entries(tracker)
|
||||
}
|
||||
|
||||
@ -150,7 +151,7 @@ memtracker_check_for_collisions :: proc ( tracker : MemoryTracker )
|
||||
|
||||
collided := left.start > right.start || left.end > right.end
|
||||
if collided {
|
||||
msg := str_fmt("%v: Memory tracker detected a collision:\nleft: %v\nright: %v", tracker.name, left, right)
|
||||
msg := str_fmt("Memory tracker detected a collision:\nleft: %v\nright: %v | %v", left, right, tracker.name )
|
||||
memtracker_dump_entries(tracker)
|
||||
}
|
||||
}
|
||||
@ -165,6 +166,6 @@ memtracker_dump_entries :: proc( tracker : MemoryTracker )
|
||||
log( "Dumping Memory Tracker:")
|
||||
for idx in 0 ..< tracker.entries.num {
|
||||
entry := & tracker.entries.data[idx]
|
||||
logf("%v", entry)
|
||||
logf("%v -> %v", entry.start, entry.end)
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ Pool :: struct {
|
||||
PoolHeader :: struct {
|
||||
backing : Allocator,
|
||||
dbg_name : string,
|
||||
tracker : MemoryTracker,
|
||||
tracker : MemoryTracker,
|
||||
// bucket_tracker : MemoryTracker,
|
||||
|
||||
zero_bucket : b32,
|
||||
block_size : uint,
|
||||
@ -57,6 +58,7 @@ pool_init :: proc (
|
||||
alignment : uint = mem.DEFAULT_ALIGNMENT,
|
||||
allocator : Allocator = context.allocator,
|
||||
dbg_name : string = "",
|
||||
enable_mem_tracking : b32 = false,
|
||||
) -> ( pool : Pool, alloc_error : AllocatorError )
|
||||
{
|
||||
header_size := align_forward_int( size_of(PoolHeader), int(alignment) )
|
||||
@ -76,8 +78,9 @@ pool_init :: proc (
|
||||
pool.bucket_capacity = bucket_capacity
|
||||
pool.alignment = alignment
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && enable_mem_tracking {
|
||||
memtracker_init( & pool.tracker, allocator, Kilobyte * 96, dbg_name )
|
||||
// memtracker_init( & pool.bucket_tracker, allocator, Kilobyte * 96, dbg_name )
|
||||
}
|
||||
|
||||
if bucket_reserve_num > 0 {
|
||||
@ -104,8 +107,9 @@ pool_destroy :: proc ( using self : Pool )
|
||||
|
||||
free( self.header, backing )
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && self.tracker.entries.header != nil {
|
||||
memtracker_clear( self.tracker )
|
||||
// memtracker_clear( self.bucket_tracker )
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,6 +137,10 @@ pool_allocate_buckets :: proc( pool : Pool, num_buckets : uint ) -> AllocatorErr
|
||||
}
|
||||
pool_validate( pool )
|
||||
|
||||
// if Track_Memory && pool.tracker.entries.header != nil {
|
||||
// memtracker_register_auto_name_slice( & pool.bucket_tracker, bucket_memory)
|
||||
// }
|
||||
|
||||
// log(str_fmt_tmp("Bucket memory size: %d bytes, without header: %d", len(bucket_memory), len(bucket_memory) - int(header_size)))
|
||||
|
||||
if alloc_error != .None {
|
||||
@ -195,7 +203,7 @@ pool_grab :: proc( pool : Pool, zero_memory := false ) -> ( block : []byte, allo
|
||||
slice.zero(block)
|
||||
}
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && pool.tracker.entries.header != nil {
|
||||
memtracker_register_auto_name_slice( & pool.tracker, block)
|
||||
}
|
||||
return
|
||||
@ -258,7 +266,7 @@ pool_grab :: proc( pool : Pool, zero_memory := false ) -> ( block : []byte, allo
|
||||
// log( str_fmt_tmp("Zeroed memory - Range(%p to %p)", block_ptr, cast(rawptr) (uintptr(block_ptr) + uintptr(pool.block_size))))
|
||||
}
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && pool.tracker.entries.header != nil {
|
||||
memtracker_register_auto_name_slice( & pool.tracker, block)
|
||||
}
|
||||
return
|
||||
@ -289,7 +297,7 @@ pool_release :: proc( self : Pool, block : []byte, loc := #caller_location )
|
||||
|
||||
start := new_free_block
|
||||
end := transmute(rawptr) (uintptr(new_free_block) + uintptr(self.block_size) - 1)
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && self.tracker.entries.header != nil {
|
||||
memtracker_unregister( self.tracker, { start, end } )
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ package grime
|
||||
import "base:runtime"
|
||||
import "core:mem"
|
||||
import "core:slice"
|
||||
import "core:strings"
|
||||
|
||||
SlabSizeClass :: struct {
|
||||
bucket_capacity : uint,
|
||||
@ -55,7 +56,12 @@ slab_allocator :: proc( slab : Slab ) -> ( allocator : Allocator ) {
|
||||
return
|
||||
}
|
||||
|
||||
slab_init :: proc( policy : ^SlabPolicy, bucket_reserve_num : uint = 0, allocator : Allocator = context.allocator, dbg_name : string = "", should_zero_buckets : b32 = false ) -> ( slab : Slab, alloc_error : AllocatorError )
|
||||
slab_init :: proc( policy : ^SlabPolicy, bucket_reserve_num : uint = 0,
|
||||
allocator : Allocator = context.allocator,
|
||||
dbg_name : string = "",
|
||||
should_zero_buckets : b32 = false,
|
||||
enable_mem_tracking : b32 = false,
|
||||
) -> ( slab : Slab, alloc_error : AllocatorError )
|
||||
{
|
||||
header_size :: size_of( SlabHeader )
|
||||
|
||||
@ -66,10 +72,10 @@ slab_init :: proc( policy : ^SlabPolicy, bucket_reserve_num : uint = 0, allocato
|
||||
slab.header = cast( ^SlabHeader) raw_mem
|
||||
slab.backing = allocator
|
||||
slab.dbg_name = dbg_name
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && enable_mem_tracking {
|
||||
memtracker_init( & slab.tracker, allocator, Kilobyte * 256, dbg_name )
|
||||
}
|
||||
alloc_error = slab_init_pools( slab, policy, bucket_reserve_num, should_zero_buckets )
|
||||
alloc_error = slab_init_pools( slab, policy, bucket_reserve_num, should_zero_buckets )
|
||||
return
|
||||
}
|
||||
|
||||
@ -80,8 +86,12 @@ slab_init_pools :: proc ( using self : Slab, policy : ^SlabPolicy, bucket_reserv
|
||||
for id in 0 ..< policy.idx {
|
||||
using size_class := policy.items[id]
|
||||
|
||||
pool_dbg_name := str_fmt("%v pool[%v]", dbg_name, block_size, allocator = backing)
|
||||
pool, alloc_error := pool_init( should_zero_buckets, block_size, bucket_capacity, bucket_reserve_num, block_alignment, backing, pool_dbg_name )
|
||||
name_temp := str_fmt_tmp("%v pool[%v]", dbg_name, block_size)
|
||||
pool_dbg_name, error := strings.clone( name_temp, allocator = backing )
|
||||
pool, alloc_error := pool_init( should_zero_buckets, block_size, bucket_capacity, bucket_reserve_num, block_alignment, backing,
|
||||
pool_dbg_name,
|
||||
enable_mem_tracking = Track_Memory && tracker.entries.header != nil
|
||||
)
|
||||
if alloc_error != .None do return alloc_error
|
||||
|
||||
push( & self.pools, pool )
|
||||
@ -107,7 +117,7 @@ slab_destroy :: proc( using self : Slab )
|
||||
}
|
||||
|
||||
free( self.header, backing )
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && self.tracker.entries.header != nil {
|
||||
memtracker_clear(tracker)
|
||||
}
|
||||
}
|
||||
@ -148,7 +158,7 @@ slab_alloc :: proc( self : Slab,
|
||||
slice.zero(data)
|
||||
}
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && self.tracker.entries.header != nil {
|
||||
memtracker_register_auto_name( & self.tracker, raw_data(block), & block[ len(block) - 1 ] )
|
||||
}
|
||||
return
|
||||
@ -165,7 +175,7 @@ slab_free :: proc( using self : Slab, data : []byte, loc := #caller_location )
|
||||
start := raw_data(data)
|
||||
end := ptr_offset(start, pool.block_size - 1)
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && self.tracker.entries.header != nil {
|
||||
memtracker_unregister( self.tracker, { start, end } )
|
||||
}
|
||||
|
||||
@ -255,13 +265,13 @@ slab_resize :: proc( using self : Slab,
|
||||
start := raw_data( data )
|
||||
end := rawptr(uintptr(start) + uintptr(pool_old.block_size) - 1)
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && self.tracker.entries.header != nil {
|
||||
memtracker_unregister( self.tracker, { start, end } )
|
||||
}
|
||||
}
|
||||
|
||||
new_data = new_block[ :new_size]
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && self.tracker.entries.header != nil {
|
||||
memtracker_register_auto_name( & self.tracker, raw_data(new_block), & new_block[ len(new_block) - 1 ] )
|
||||
}
|
||||
return
|
||||
@ -273,7 +283,7 @@ slab_reset :: proc( slab : Slab )
|
||||
pool := slab.pools.items[id]
|
||||
pool_reset( pool )
|
||||
}
|
||||
when ODIN_DEBUG {
|
||||
when Track_Memory {
|
||||
memtracker_clear(slab.tracker)
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ VArena :: struct {
|
||||
dbg_name : string,
|
||||
commit_used : uint,
|
||||
growth_policy : VArena_GrowthPolicyProc,
|
||||
allow_any_reize : b32,
|
||||
allow_any_resize : b32,
|
||||
mutex : sync.Mutex,
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ varena_allocator :: proc( arena : ^VArena ) -> ( allocator : Allocator ) {
|
||||
|
||||
// Default growth_policy is nil
|
||||
varena_init :: proc( base_address : uintptr, to_reserve, to_commit : uint,
|
||||
growth_policy : VArena_GrowthPolicyProc, allow_any_reize : b32 = false, dbg_name : string
|
||||
growth_policy : VArena_GrowthPolicyProc, allow_any_resize : b32 = false, dbg_name : string, enable_mem_tracking : b32 = false,
|
||||
) -> ( arena : VArena, alloc_error : AllocatorError)
|
||||
{
|
||||
page_size := uint(virtual_get_page_size())
|
||||
@ -86,9 +86,9 @@ varena_init :: proc( base_address : uintptr, to_reserve, to_commit : uint,
|
||||
else {
|
||||
arena.growth_policy = growth_policy
|
||||
}
|
||||
arena.allow_any_reize = allow_any_reize
|
||||
arena.allow_any_resize = allow_any_resize
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && enable_mem_tracking {
|
||||
memtracker_init( & arena.tracker, runtime.heap_allocator(), Kilobyte * 128, dbg_name )
|
||||
}
|
||||
return
|
||||
@ -165,7 +165,7 @@ varena_alloc :: proc( using self : ^VArena,
|
||||
mem_zero( data_ptr, int(requested_size) )
|
||||
}
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && self.tracker.entries.header != nil {
|
||||
memtracker_register_auto_name( & tracker, & data[0], & data[len(data) - 1] )
|
||||
}
|
||||
return
|
||||
@ -176,7 +176,7 @@ varena_free_all :: proc( using self : ^VArena )
|
||||
sync.mutex_guard( & mutex )
|
||||
commit_used = 0
|
||||
|
||||
when ODIN_DEBUG && Track_Memory {
|
||||
if Track_Memory && self.tracker.entries.header != nil {
|
||||
array_clear(tracker.entries)
|
||||
}
|
||||
}
|
||||
@ -251,13 +251,13 @@ varena_allocator_proc :: proc(
|
||||
}
|
||||
}
|
||||
|
||||
verify( old_memory_offset == current_offset || arena.allow_any_reize,
|
||||
verify( old_memory_offset == current_offset || arena.allow_any_resize,
|
||||
"Cannot resize existing allocation in vitual arena to a larger size unless it was the last allocated" )
|
||||
|
||||
log_backing : [Kilobyte * 16]byte
|
||||
backing_slice := byte_slice( & log_backing[0], len(log_backing))
|
||||
|
||||
if old_memory_offset != current_offset && arena.allow_any_reize
|
||||
if old_memory_offset != current_offset && arena.allow_any_resize
|
||||
{
|
||||
// Give it new memory and copy the old over. Old memory is unrecoverable until clear.
|
||||
new_region : []byte
|
||||
@ -266,7 +266,7 @@ varena_allocator_proc :: proc(
|
||||
ensure(false, "Failed to grab new region")
|
||||
data = byte_slice( old_memory, old_size )
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && arena.tracker.entries.header != nil {
|
||||
memtracker_register_auto_name( & arena.tracker, & data[0], & data[len(data) - 1] )
|
||||
}
|
||||
return
|
||||
@ -276,7 +276,7 @@ varena_allocator_proc :: proc(
|
||||
data = new_region
|
||||
// log( str_fmt_tmp("varena resize (new): old: %p %v new: %p %v", old_memory, old_size, (& data[0]), size))
|
||||
|
||||
when ODIN_DEBUG {
|
||||
when Track_Memory {
|
||||
memtracker_register_auto_name( & arena.tracker, & data[0], & data[len(data) - 1] )
|
||||
}
|
||||
return
|
||||
@ -293,7 +293,7 @@ varena_allocator_proc :: proc(
|
||||
data = byte_slice( old_memory, size )
|
||||
// log( str_fmt_tmp("varena resize (expanded): old: %p %v new: %p %v", old_memory, old_size, (& data[0]), size))
|
||||
|
||||
when ODIN_DEBUG {
|
||||
if Track_Memory && arena.tracker.entries.header != nil {
|
||||
memtracker_register_auto_name( & arena.tracker, & data[0], & data[len(data) - 1] )
|
||||
}
|
||||
return
|
||||
|
@ -129,7 +129,8 @@ setup_memory :: proc( profiler : ^SpallProfiler ) -> ClientMemory
|
||||
sectr.Memory_Commit_Initial_Persistent,
|
||||
growth_policy = nil,
|
||||
allow_any_resize = false,
|
||||
dbg_name = "persistent" )
|
||||
dbg_name = "persistent",
|
||||
enable_mem_tracking = true )
|
||||
verify( alloc_error == .None, "Failed to allocate persistent virtual arena for the sectr module")
|
||||
|
||||
frame, alloc_error = varena_init(
|
||||
|
@ -92,7 +92,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
// push( policy_ptr, SlabSizeClass { 512 * Megabyte, 512 * Megabyte, alignment })
|
||||
|
||||
alloc_error : AllocatorError
|
||||
persistent_slab, alloc_error = slab_init( policy_ptr, allocator = persistent_allocator(), dbg_name = Persistent_Slab_DBG_Name )
|
||||
persistent_slab, alloc_error = slab_init( policy_ptr, allocator = persistent_allocator(), dbg_name = Persistent_Slab_DBG_Name, enable_mem_tracking = true )
|
||||
verify( alloc_error == .None, "Failed to allocate the persistent slab" )
|
||||
|
||||
transient_slab, alloc_error = slab_init( & default_slab_policy, allocator = transient_allocator(), dbg_name = Transient_Slab_DBG_Name )
|
||||
|
Loading…
Reference in New Issue
Block a user