From 70b13ce107cdae76f95166b7b80b420842560d9e Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 14 May 2024 14:07:29 -0400 Subject: [PATCH] fixes for hmap_chained_init and other stuff --- code/font_provider.odin | 2 +- code/grime_hashmap_chained.odin | 6 ++--- code/grime_linked_list.odin | 20 +++++++-------- code/grime_pool_allocator.odin | 12 +++++++++ code/grime_stack.odin | 43 +++++++++++++++++---------------- 5 files changed, 48 insertions(+), 35 deletions(-) diff --git a/code/font_provider.odin b/code/font_provider.odin index ce666d3..cffa1a8 100644 --- a/code/font_provider.odin +++ b/code/font_provider.odin @@ -66,7 +66,7 @@ font_provider_startup :: proc() font_provider_data := & get_state().font_provider_data; using font_provider_data font_cache_alloc_error : AllocatorError - font_cache, font_cache_alloc_error = hmap_chained_init(FontDef, hmap_closest_prime(1 * Kilo), persistent_slab_allocator() ) + font_cache, font_cache_alloc_error = hmap_chained_init(FontDef, hmap_closest_prime(1 * Kilo), persistent_allocator(), dbg_name = "font_cache" ) verify( font_cache_alloc_error == AllocatorError.None, "Failed to allocate font_cache" ) log("font_cache created") diff --git a/code/grime_hashmap_chained.odin b/code/grime_hashmap_chained.odin index 4fe9da8..36c5436 100644 --- a/code/grime_hashmap_chained.odin +++ b/code/grime_hashmap_chained.odin @@ -52,13 +52,13 @@ hmap_closest_prime :: proc( capacity : uint ) -> uint } hmap_chained_init :: proc( $Type : typeid, lookup_capacity : uint, allocator : Allocator, - pool_bucket_cap : uint = 0, + pool_bucket_cap : uint = 1 * Kilo, pool_bucket_reserve_num : uint = 0, pool_alignment : uint = mem.DEFAULT_ALIGNMENT, dbg_name : string = "" ) -> (table : HMapChainedPtr(Type), error : AllocatorError) { - header_size := size_of(HMapChainedPtr(Type)) + header_size := size_of(HMapChained(Type)) size := header_size + int(lookup_capacity) * size_of( ^HMapChainedSlot(Type)) + size_of(int) raw_mem : rawptr @@ -73,7 +73,7 @@ hmap_chained_init :: proc( $Type : typeid, lookup_capacity : uint, allocator : A bucket_reserve_num = pool_bucket_reserve_num, alignment = pool_alignment, allocator = allocator, - dbg_name = str_intern(str_fmt_tmp("%: pool", dbg_name)).str + dbg_name = str_intern(str_fmt_tmp("%v: pool", dbg_name)).str ) data := transmute([^] ^HMapChainedSlot(Type)) (transmute( [^]HMapChained(Type)) table.header)[1:] table.lookup = slice_ptr( data, int(lookup_capacity) ) diff --git a/code/grime_linked_list.odin b/code/grime_linked_list.odin index a4073c8..ce4c1a3 100644 --- a/code/grime_linked_list.odin +++ b/code/grime_linked_list.odin @@ -41,23 +41,23 @@ DLL_NodeFull :: struct ( $ Type : typeid ) { } DLL_NodePN :: struct ( $ Type : typeid ) { - using _ : struct { + // using _ : struct { prev, next : ^Type, - }, - using _ : struct { - left, right : ^Type, - }, + // }, + // using _ : struct { + // left, right : ^Type, + // }, } DLL_NodeFL :: struct ( $ Type : typeid ) #raw_union { - using _ : struct { + // using _ : struct { first, last : ^Type, - }, + // }, // TODO(Ed): Review this - using _ : struct { - bottom, top: ^Type, - }, + // using _ : struct { + // bottom, top: ^Type, + // }, } type_is_node :: #force_inline proc "contextless" ( $ Type : typeid ) -> bool diff --git a/code/grime_pool_allocator.odin b/code/grime_pool_allocator.odin index d7ba31d..b2219e9 100644 --- a/code/grime_pool_allocator.odin +++ b/code/grime_pool_allocator.odin @@ -65,6 +65,9 @@ pool_init :: proc ( raw_mem, alloc_error = alloc( header_size, int(alignment), allocator ) if alloc_error != .None do return + ensure(block_size > 0, "Bad block size provided") + ensure(bucket_capacity > 0, "Bad bucket capacity provided") + pool.header = cast( ^PoolHeader) raw_mem pool.zero_bucket = should_zero_buckets pool.backing = allocator @@ -304,12 +307,21 @@ pool_reset :: proc( using pool : Pool ) pool_validate :: proc( pool : Pool ) { + when !ODIN_DEBUG do return pool := pool // Make sure all buckets don't show any indication of corruption bucket : ^PoolBucket = pool.bucket_list.first + + if bucket != nil && uintptr(bucket) < 0x10000000000 { + ensure(false, str_fmt_tmp("Found a corrupted bucket %p", bucket )) + } // Compiler bug ^^ same as pool_reset for ; bucket != nil; bucket = bucket.next { + if bucket != nil && uintptr(bucket) < 0x10000000000 { + ensure(false, str_fmt_tmp("Found a corrupted bucket %p", bucket )) + } + if ( bucket.blocks == nil ) { ensure(false, str_fmt_tmp("Found a corrupted bucket %p", bucket )) } diff --git a/code/grime_stack.odin b/code/grime_stack.odin index 9cdb0ed..1088941 100644 --- a/code/grime_stack.odin +++ b/code/grime_stack.odin @@ -87,8 +87,8 @@ stack_allocator_init :: proc( size : int, allocator := context.allocator ) -> ( stack.size = size stack.data = cast( [^]byte) (cast( [^]StackAllocatorBase) stack.base)[ 1:] - stack.top = cast(^StackAllocatorHeader) stack.data - stack.bottom = stack.top + stack.last = cast(^StackAllocatorHeader) stack.data + stack.first = stack.last return } @@ -110,8 +110,8 @@ stack_allocator_init_via_memory :: proc( memory : []byte ) -> ( stack : StackAll stack.size = len(memory) - header_size stack.data = cast( [^]byte ) (cast( [^]StackAllocatorBase) stack.base)[ 1:] - stack.top = cast( ^StackAllocatorHeader) stack.data - stack.bottom = stack.top + stack.last = cast( ^StackAllocatorHeader) stack.data + stack.first = stack.last return } @@ -119,16 +119,16 @@ stack_allocator_push :: proc( using self : StackAllocator, block_size, alignment { // TODO(Ed): Make sure first push is fine. verify( block_size > Kilobyte, "Attempted to push onto the stack less than a Kilobyte") - top_block_ptr := memory_after_header( top ) + top_block_ptr := memory_after_header( last ) - theoretical_size := cast(int) (uintptr(top_block_ptr) + uintptr(block_size) - uintptr(bottom)) + theoretical_size := cast(int) (uintptr(top_block_ptr) + uintptr(block_size) - uintptr(first)) if theoretical_size > size { // TODO(Ed) : Check if backing allocator supports resize, if it does attempt to grow. return nil, .Out_Of_Memory } - top_block_slice := slice_ptr( top_block_ptr, top.block_size ) - next_spot := uintptr( top_block_ptr) + uintptr(top.block_size) + top_block_slice := slice_ptr( top_block_ptr, last.block_size ) + next_spot := uintptr( top_block_ptr) + uintptr(last.block_size) header_offset_pad := calc_padding_with_header( uintptr(next_spot), uintptr(alignment), size_of(StackAllocatorHeader) ) header := cast( ^StackAllocatorHeader) (next_spot + uintptr(header_offset_pad) - uintptr(size_of( StackAllocatorHeader))) @@ -139,7 +139,7 @@ stack_allocator_push :: proc( using self : StackAllocator, block_size, alignment curr_block_ptr := memory_after_header( header ) curr_block := slice_ptr( curr_block_ptr, block_size ) - curr_used := cast(int) (uintptr(curr_block_ptr) + uintptr(block_size) - uintptr(self.top)) + curr_used := cast(int) (uintptr(curr_block_ptr) + uintptr(block_size) - uintptr(self.last)) self.peak_used += max( peak_used, curr_used ) dll_push_back( & base.links.last, header ) @@ -154,29 +154,30 @@ stack_allocator_push :: proc( using self : StackAllocator, block_size, alignment stack_allocator_resize_top :: proc( using self : StackAllocator, new_block_size, alignment : int, zero_memory : bool ) -> AllocatorError { verify( new_block_size > Kilobyte, "Attempted to resize the last pushed on the stack to less than a Kilobyte") - top_block_ptr := memory_after_header( top ) + top_block_ptr := memory_after_header( last ) - theoretical_size := cast(int) (uintptr(top_block_ptr) + uintptr(top.block_size) - uintptr(bottom)) + theoretical_size := cast(int) (uintptr(top_block_ptr) + uintptr(last.block_size) - uintptr(first)) if theoretical_size > size { // TODO(Ed) : Check if backing allocator supports resize, if it does attempt to grow. return .Out_Of_Memory } - if zero_memory && new_block_size > top.block_size { - added_ptr := top_block_ptr[ top.block_size:] - added_slice := slice_ptr( added_ptr, new_block_size - top.block_size ) + if zero_memory && new_block_size > last.block_size { + added_ptr := top_block_ptr[ last.block_size:] + added_slice := slice_ptr( added_ptr, new_block_size - last.block_size ) slice.zero( added_slice ) } - top.block_size = new_block_size + last.block_size = new_block_size return .None } stack_allocator_pop :: proc( using self : StackAllocator ) { - base.links.top = top.prev - base.links.top.next = nil + base.links.last = last.prev + base.links.last.next = nil } + stack_allocator_proc :: proc( allocator_data : rawptr, mode : AllocatorMode, @@ -221,9 +222,9 @@ stack_allocator_proc :: proc( } case .Free_All: // TODO(Ed) : Review that we don't have any header issues with the reset. - stack.bottom = stack.top - stack.top.next = nil - stack.top.block_size = 0 + stack.first = stack.last + stack.last.next = nil + stack.last.block_size = 0 case .Resize, .Resize_Non_Zeroed: { @@ -242,7 +243,7 @@ stack_allocator_proc :: proc( verify( start <= curr_addr && curr_addr < end, "Out of bounds memory address passed to stack allocator (resize)" ) - block_ptr := memory_after_header( stack.top ) + block_ptr := memory_after_header( stack.last ) if block_ptr != old_memory { ensure( false, "Attempted to reszie a block of memory on the stack other than top most" ) return nil, .None