Cleanup malloc

This commit is contained in:
Baptiste Wicht 2014-01-23 20:43:55 +01:00
parent d5ff8f3b6a
commit 4d2dd9bce2
6 changed files with 94 additions and 90 deletions

View File

@ -5,12 +5,14 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
//======================================================================= //=======================================================================
#ifndef MEMORY_H #ifndef MALLOC_H
#define MEMORY_H #define MALLOC_H
#include "stl/types.hpp" #include "stl/types.hpp"
void init_memory_manager(); namespace malloc {
void init();
void* k_malloc(uint64_t bytes); void* k_malloc(uint64_t bytes);
void k_free(void* block); void k_free(void* block);
@ -24,6 +26,8 @@ uint64_t allocated_memory();
uint64_t used_memory(); uint64_t used_memory();
uint64_t free_memory(); uint64_t free_memory();
void malloc_debug(); void debug();
}
#endif #endif

View File

@ -8,7 +8,7 @@
#include "ata.hpp" #include "ata.hpp"
#include "kernel_utils.hpp" #include "kernel_utils.hpp"
#include "timer.hpp" #include "timer.hpp"
#include "memory.hpp" #include "malloc.hpp"
#include "thor.hpp" #include "thor.hpp"
#include "interrupts.hpp" #include "interrupts.hpp"
#include "console.hpp" #include "console.hpp"

View File

@ -9,7 +9,7 @@
#include "physical_allocator.hpp" #include "physical_allocator.hpp"
#include "virtual_allocator.hpp" #include "virtual_allocator.hpp"
#include "paging.hpp" #include "paging.hpp"
#include "memory.hpp" #include "malloc.hpp"
#include "timer.hpp" #include "timer.hpp"
#include "shell.hpp" #include "shell.hpp"
#include "keyboard.hpp" #include "keyboard.hpp"
@ -39,7 +39,7 @@ void kernel_main(){
virtual_allocator::init(); virtual_allocator::init();
physical_allocator::init(); physical_allocator::init();
init_memory_manager(); malloc::init();
//Install drivers //Install drivers
install_timer(); install_timer();

View File

@ -5,7 +5,7 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
//======================================================================= //=======================================================================
#include "memory.hpp" #include "malloc.hpp"
#include "console.hpp" #include "console.hpp"
#include "physical_allocator.hpp" #include "physical_allocator.hpp"
#include "paging.hpp" #include "paging.hpp"
@ -58,7 +58,7 @@ public:
__prev = reinterpret_cast<malloc_header_chunk*>(reinterpret_cast<uintptr_t>(__prev) & (~0l - 1)); __prev = reinterpret_cast<malloc_header_chunk*>(reinterpret_cast<uintptr_t>(__prev) & (~0l - 1));
} }
bool is_free(){ bool is_free() const {
return reinterpret_cast<uintptr_t>(__prev) & 0x1; return reinterpret_cast<uintptr_t>(__prev) & 0x1;
} }
@ -215,9 +215,70 @@ void expand_heap(malloc_header_chunk* current){
insert_after(current, header); insert_after(current, header);
} }
malloc_header_chunk* left_block(malloc_header_chunk* b){
auto left_footer = reinterpret_cast<malloc_footer_chunk*>(
reinterpret_cast<uintptr_t>(b) - sizeof(malloc_footer_chunk));
if(reinterpret_cast<uintptr_t>(left_footer)>= min_address){
auto left_size = left_footer->size();
auto left_header = reinterpret_cast<malloc_header_chunk*>(
reinterpret_cast<uintptr_t>(left_footer) - left_size - sizeof(malloc_header_chunk));
if(reinterpret_cast<uintptr_t>(left_header) >= min_address){
return left_header;
}
}
return nullptr;
}
malloc_header_chunk* right_block(malloc_header_chunk* b){
auto right_header = reinterpret_cast<malloc_header_chunk*>(
reinterpret_cast<uintptr_t>(b) + META_SIZE + b->size());
if(reinterpret_cast<uintptr_t>(right_header) < max_address){
auto right_footer = right_header->footer();
if(reinterpret_cast<uintptr_t>(right_footer) < max_address){
return right_header;
}
}
return nullptr;
}
malloc_header_chunk* coalesce(malloc_header_chunk* b){
auto a = left_block(b);
auto c = right_block(b);
if(a && a->is_free()){
auto new_size = a->size() + b->size() + META_SIZE;
//Remove a from the free list
remove(a);
b = a;
b->size() = new_size;
b->footer()->size() = new_size;
}
if(c && c->is_free()){
auto new_size = b->size() + c->size() + META_SIZE;
//Remove c from the free list
remove(c);
b->size() = new_size;
b->footer()->size() = new_size;
}
return b;
}
} //end of anonymous namespace } //end of anonymous namespace
void init_memory_manager(){ void malloc::init(){
//Init the fake head //Init the fake head
init_head(); init_head();
@ -225,7 +286,7 @@ void init_memory_manager(){
expand_heap(malloc_head); expand_heap(malloc_head);
} }
void* k_malloc(uint64_t bytes){ void* malloc::k_malloc(uint64_t bytes){
auto current = malloc_head->next(); auto current = malloc_head->next();
//Try not to create too small blocks //Try not to create too small blocks
@ -297,68 +358,7 @@ void* k_malloc(uint64_t bytes){
return b; return b;
} }
malloc_header_chunk* left_block(malloc_header_chunk* b){ void malloc::k_free(void* block){
auto left_footer = reinterpret_cast<malloc_footer_chunk*>(
reinterpret_cast<uintptr_t>(b) - sizeof(malloc_footer_chunk));
if(reinterpret_cast<uintptr_t>(left_footer)>= min_address){
auto left_size = left_footer->size();
auto left_header = reinterpret_cast<malloc_header_chunk*>(
reinterpret_cast<uintptr_t>(left_footer) - left_size - sizeof(malloc_header_chunk));
if(reinterpret_cast<uintptr_t>(left_header) >= min_address){
return left_header;
}
}
return nullptr;
}
malloc_header_chunk* right_block(malloc_header_chunk* b){
auto right_header = reinterpret_cast<malloc_header_chunk*>(
reinterpret_cast<uintptr_t>(b) + META_SIZE + b->size());
if(reinterpret_cast<uintptr_t>(right_header) < max_address){
auto right_footer = right_header->footer();
if(reinterpret_cast<uintptr_t>(right_footer) < max_address){
return right_header;
}
}
return nullptr;
}
malloc_header_chunk* coalesce(malloc_header_chunk* b){
auto a = left_block(b);
auto c = right_block(b);
if(a && a->is_free()){
auto new_size = a->size() + b->size() + META_SIZE;
//Remove a from the free list
remove(a);
b = a;
b->size() = new_size;
b->footer()->size() = new_size;
}
if(c && c->is_free()){
auto new_size = b->size() + c->size() + META_SIZE;
//Remove c from the free list
remove(c);
b->size() = new_size;
b->footer()->size() = new_size;
}
return b;
}
void k_free(void* block){
auto free_header = reinterpret_cast<malloc_header_chunk*>( auto free_header = reinterpret_cast<malloc_header_chunk*>(
reinterpret_cast<uintptr_t>(block) - sizeof(malloc_header_chunk)); reinterpret_cast<uintptr_t>(block) - sizeof(malloc_header_chunk));
@ -382,15 +382,15 @@ void k_free(void* block){
debug_malloc<DEBUG_MALLOC>("after free"); debug_malloc<DEBUG_MALLOC>("after free");
} }
size_t allocated_memory(){ size_t malloc::allocated_memory(){
return _allocated_memory; return _allocated_memory;
} }
size_t used_memory(){ size_t malloc::used_memory(){
return _used_memory; return _used_memory;
} }
size_t free_memory(){ size_t malloc::free_memory(){
size_t memory_free = 0; size_t memory_free = 0;
auto it = malloc_head; auto it = malloc_head;
@ -403,7 +403,7 @@ size_t free_memory(){
return memory_free; return memory_free;
} }
void malloc_debug(){ void malloc::debug(){
size_t memory_free = 0; size_t memory_free = 0;
size_t non_free_blocks = 0; size_t non_free_blocks = 0;
size_t inconsistent = 0; size_t inconsistent = 0;

View File

@ -26,7 +26,7 @@
#include "physical_allocator.hpp" #include "physical_allocator.hpp"
#include "virtual_allocator.hpp" #include "virtual_allocator.hpp"
#include "memory.hpp" #include "malloc.hpp"
#include "e820.hpp" #include "e820.hpp"
//Commands //Commands
@ -295,13 +295,13 @@ void memory_command(const std::vector<std::string>&){
k_printf("\tFree: %m (%h)\n", virtual_allocator::free(), virtual_allocator::free()); k_printf("\tFree: %m (%h)\n", virtual_allocator::free(), virtual_allocator::free());
k_print_line("Dynamic:"); k_print_line("Dynamic:");
k_printf("\tAllocated: %m (%h)\n", allocated_memory(), allocated_memory()); k_printf("\tAllocated: %m (%h)\n", malloc::allocated_memory(), malloc::allocated_memory());
k_printf("\tUsed: %m (%h)\n", used_memory(), used_memory()); k_printf("\tUsed: %m (%h)\n", malloc::used_memory(), malloc::used_memory());
k_printf("\tFree: %m (%h)\n", free_memory(), free_memory()); k_printf("\tFree: %m (%h)\n", malloc::free_memory(), malloc::free_memory());
} }
void mallocdebug_command(const std::vector<std::string>&){ void mallocdebug_command(const std::vector<std::string>&){
malloc_debug(); malloc::debug();
} }
void disks_command(const std::vector<std::string>& params){ void disks_command(const std::vector<std::string>& params){
@ -781,7 +781,7 @@ bool allocate_segments(char* buffer, void** allocated_segments, uint8_t flags){
} }
//2. Get enough physical memory //2. Get enough physical memory
auto memory = k_malloc(bytes); auto memory = malloc::k_malloc(bytes);
if(!memory){ if(!memory){
k_print_line("Cannot allocate memory, probably out of memory"); k_print_line("Cannot allocate memory, probably out of memory");
@ -833,7 +833,7 @@ void* allocate_user_stack(size_t stack_address, size_t stack_size, uint8_t flags
} }
//2. Get enough physical memory //2. Get enough physical memory
auto memory = k_malloc(bytes); auto memory = malloc::k_malloc(bytes);
if(!memory){ if(!memory){
k_print_line("Cannot allocate memory, probably out of memory"); k_print_line("Cannot allocate memory, probably out of memory");
@ -871,7 +871,7 @@ void release_segments(char* buffer, void** allocated_segments){
auto a = allocated_segments[p]; auto a = allocated_segments[p];
if(a){ if(a){
k_free(a); malloc::k_free(a);
auto address = p_header.p_vaddr; auto address = p_header.p_vaddr;
auto first_page = reinterpret_cast<uintptr_t>(paging::page_align(reinterpret_cast<void*>(address))); auto first_page = reinterpret_cast<uintptr_t>(paging::page_align(reinterpret_cast<void*>(address)));

View File

@ -6,22 +6,22 @@
//======================================================================= //=======================================================================
#include "thor.hpp" #include "thor.hpp"
#include "memory.hpp" #include "malloc.hpp"
void* operator new(uint64_t size){ void* operator new(uint64_t size){
return k_malloc(size); return malloc::k_malloc(size);
} }
void operator delete(void* p){ void operator delete(void* p){
k_free(p); malloc::k_free(p);
} }
void* operator new[](uint64_t size){ void* operator new[](uint64_t size){
return k_malloc(size); return malloc::k_malloc(size);
} }
void operator delete[](void* p){ void operator delete[](void* p){
return k_free(p); return malloc::k_free(p);
} }
extern "C" { extern "C" {