From 0cccf363ec22c5f11c5c1bcf8cd0f5d712666bee Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Wed, 6 Nov 2013 21:38:37 +0100 Subject: [PATCH] memory allocator improvements Fix small bug with the split decision of k_malloc Add debug routines --- kernel/src/memory.cpp | 47 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/kernel/src/memory.cpp b/kernel/src/memory.cpp index 7b02c0d6..c78a64b0 100644 --- a/kernel/src/memory.cpp +++ b/kernel/src/memory.cpp @@ -3,6 +3,10 @@ namespace { +//Used to compile with malloc operations in the console +//can produce a lot of output +const bool DEBUG_MALLOC = false; + struct bios_mmap_entry { uint32_t base_low; uint32_t base_high; @@ -110,6 +114,35 @@ uint64_t* allocate_block(uint64_t blocks){ return block; } +template +void debug_malloc(const char* point = nullptr){ + if(Debug){ + if(point){ + k_print_line(point); + } + + auto it = malloc_head; + + k_print("next: "); + do { + k_printf("%h -> ", reinterpret_cast(it)); + it = it->next; + } while(it != malloc_head); + + k_printf("%h\n", malloc_head); + + it = malloc_head; + + k_print("prev: "); + do { + k_printf("%h <- ", reinterpret_cast(it)); + it = it->prev; + } while(it != malloc_head); + + k_printf("%h\n", malloc_head); + } +} + } //end of anonymous namespace void init_memory_manager(){ @@ -147,12 +180,12 @@ uint64_t* k_malloc(uint64_t bytes){ auto header = reinterpret_cast(block); header->size = MIN_BLOCKS * BLOCK_SIZE - META_SIZE; + header->next = current->next; + header->prev = current; + current->next->prev = header; current->next = header; - header->next = current->next; - header->prev = current; - auto footer = reinterpret_cast( reinterpret_cast(block) + header->size + sizeof(malloc_header_chunk)); footer->size = header->size; @@ -160,7 +193,7 @@ uint64_t* k_malloc(uint64_t bytes){ //This block is big enough //Is it worth splitting the block ? - if(current->size - bytes - META_SIZE > MIN_SPLIT){ + if(current->size > bytes + META_SIZE + MIN_SPLIT){ auto new_block_size = current->size - bytes - META_SIZE; //Set the new size; @@ -183,12 +216,16 @@ uint64_t* k_malloc(uint64_t bytes){ reinterpret_cast(new_block) + new_block_size + sizeof(malloc_header_chunk)); new_footer->size = new_block_size; + debug_malloc("after malloc split"); + break; } else { //Remove this node from the free list current->prev->next = current->next; current->next->prev = current->prev; + debug_malloc("after malloc no split"); + break; } } @@ -219,6 +256,8 @@ void k_free(uint64_t* block){ header->next->prev = free_header; header->next = free_header; + + debug_malloc("after free"); } void load_memory_map(){