adding prev to HeapHeader to allow backwards coalescing.
This commit is contained in:
parent
8226764dea
commit
de312ee5fa
2 changed files with 41 additions and 17 deletions
|
|
@ -52,6 +52,7 @@ void *kmalloc(size_t size) {
|
||||||
header->size = PAGE_SIZE - sizeof(HeapHeader);
|
header->size = PAGE_SIZE - sizeof(HeapHeader);
|
||||||
header->is_free = 1;
|
header->is_free = 1;
|
||||||
header->next = NULL;
|
header->next = NULL;
|
||||||
|
header->prev = NULL;
|
||||||
|
|
||||||
heap_free_list = header;
|
heap_free_list = header;
|
||||||
}
|
}
|
||||||
|
|
@ -73,6 +74,10 @@ void *kmalloc(size_t size) {
|
||||||
header->size = PAGE_SIZE - sizeof(HeapHeader);
|
header->size = PAGE_SIZE - sizeof(HeapHeader);
|
||||||
header->is_free = 1;
|
header->is_free = 1;
|
||||||
header->next = heap_free_list;
|
header->next = heap_free_list;
|
||||||
|
header->prev = NULL;
|
||||||
|
if(heap_free_list) {
|
||||||
|
heap_free_list->prev = header;
|
||||||
|
}
|
||||||
heap_free_list = header;
|
heap_free_list = header;
|
||||||
current = header;
|
current = header;
|
||||||
}
|
}
|
||||||
|
|
@ -94,8 +99,12 @@ void *kmalloc(size_t size) {
|
||||||
}
|
}
|
||||||
new_header->size = current->size - size - sizeof(HeapHeader);
|
new_header->size = current->size - size - sizeof(HeapHeader);
|
||||||
new_header->is_free = 1;
|
new_header->is_free = 1;
|
||||||
new_header->next = current->next;
|
|
||||||
|
|
||||||
|
new_header->next = current->next;
|
||||||
|
new_header->prev = current;
|
||||||
|
if(current->next) {
|
||||||
|
current->next->prev = new_header;
|
||||||
|
}
|
||||||
current->size = size;
|
current->size = size;
|
||||||
current->next = new_header;
|
current->next = new_header;
|
||||||
}
|
}
|
||||||
|
|
@ -112,22 +121,27 @@ void kfree(void *ptr) {
|
||||||
}
|
}
|
||||||
header->is_free = 1;
|
header->is_free = 1;
|
||||||
|
|
||||||
HeapHeader *temp = heap_free_list;
|
kcoalesce(header);
|
||||||
while (temp != NULL) {
|
|
||||||
if (temp->is_free) {
|
|
||||||
kcoalesce(temp);
|
|
||||||
}
|
|
||||||
temp = temp->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kcoalesce(HeapHeader *header) {
|
void kcoalesce(HeapHeader *header) {
|
||||||
if(!header || !header->next || !header->is_free) return;
|
if(!header || !header->is_free) return;
|
||||||
|
//merge backward
|
||||||
|
while (header->prev && header->prev->is_free) {
|
||||||
|
header = header->prev;
|
||||||
|
}
|
||||||
|
//merge forward
|
||||||
|
while (header->next && header->next->is_free){
|
||||||
uintptr_t current_end = (uintptr_t)header + sizeof(HeapHeader) + header->size;
|
uintptr_t current_end = (uintptr_t)header + sizeof(HeapHeader) + header->size;
|
||||||
if (current_end == (uintptr_t)header->next && header->next->is_free) {
|
if (current_end == (uintptr_t)header->next) {
|
||||||
header->size += sizeof(HeapHeader) + header->next->size;
|
header->size += sizeof(HeapHeader) + header->next->size;
|
||||||
header->next = header->next->next;
|
header->next = header->next->next;
|
||||||
kcoalesce(header);
|
if(header->next) {
|
||||||
|
header->next->prev = header;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,13 +178,13 @@ void test_memory_alignment() {
|
||||||
void test_memory_stress() {
|
void test_memory_stress() {
|
||||||
kprintf("Starting Stress Test...\n");
|
kprintf("Starting Stress Test...\n");
|
||||||
heap_stats();
|
heap_stats();
|
||||||
void *ptrs[50] = {0}; // Track allocated pointers
|
void *ptrs[100] = {0}; // Track allocated pointers
|
||||||
uint32_t seed = 0xACE2026; // Example seed
|
uint32_t seed = 0xACE2026; // Example seed
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
kprintf("Iteration %d\n", i);
|
kprintf("Iteration %d\n", i);
|
||||||
// 1. Randomly allocate or free
|
// 1. Randomly allocate or free
|
||||||
int idx = i % 50;
|
int idx = (seed >> 16) % 50;
|
||||||
if (ptrs[idx] == NULL) {
|
if (ptrs[idx] == NULL) {
|
||||||
size_t size = (seed % 256) + 1;
|
size_t size = (seed % 256) + 1;
|
||||||
ptrs[idx] = kmalloc(size);
|
ptrs[idx] = kmalloc(size);
|
||||||
|
|
@ -183,6 +197,15 @@ void test_memory_stress() {
|
||||||
seed = (seed * 1103515245 + 12345) & 0x7fffffff;
|
seed = (seed * 1103515245 + 12345) & 0x7fffffff;
|
||||||
}
|
}
|
||||||
kprintf("Stress Test Finished. Check heap_stats() for sanity.\n");
|
kprintf("Stress Test Finished. Check heap_stats() for sanity.\n");
|
||||||
|
kprintf("HeadHeader size: %d bytes\n", sizeof(HeapHeader));
|
||||||
|
heap_stats();
|
||||||
|
kprintf("Cleaning up remaining allocations...\n");
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
if (ptrs[i] != NULL) {
|
||||||
|
kfree(ptrs[i]);
|
||||||
|
ptrs[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
heap_stats();
|
heap_stats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ typedef struct HeapHeader {
|
||||||
size_t size;
|
size_t size;
|
||||||
int is_free;
|
int is_free;
|
||||||
struct HeapHeader *next;
|
struct HeapHeader *next;
|
||||||
|
struct HeapHeader *prev;
|
||||||
} HeapHeader;
|
} HeapHeader;
|
||||||
|
|
||||||
static struct Page *free_list = NULL;
|
static struct Page *free_list = NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue