memory testing and robustness
This commit is contained in:
parent
2296179bf8
commit
9f833ca32c
4 changed files with 95 additions and 9 deletions
|
|
@ -17,6 +17,7 @@ void kmain() {
|
||||||
//}
|
//}
|
||||||
|
|
||||||
test_memory_integrity();
|
test_memory_integrity();
|
||||||
|
test_memory_alignment();
|
||||||
|
test_memory_stress();
|
||||||
poweroff();
|
poweroff();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,13 +72,8 @@ void *kmalloc(size_t size) {
|
||||||
HeapHeader* header = (HeapHeader *)page_alloc();
|
HeapHeader* header = (HeapHeader *)page_alloc();
|
||||||
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 = heap_free_list;
|
||||||
|
heap_free_list = header;
|
||||||
if (prev) {
|
|
||||||
prev->next = header;
|
|
||||||
} else {
|
|
||||||
heap_free_list = header;
|
|
||||||
}
|
|
||||||
current = header;
|
current = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,6 +88,10 @@ void *kmalloc(size_t size) {
|
||||||
size_t min_split_size = sizeof(HeapHeader) + 16;
|
size_t min_split_size = sizeof(HeapHeader) + 16;
|
||||||
if (current->size >= size + min_split_size) {
|
if (current->size >= size + min_split_size) {
|
||||||
HeapHeader *new_header = (HeapHeader *)((uint8_t *)current + sizeof(HeapHeader) + size);
|
HeapHeader *new_header = (HeapHeader *)((uint8_t *)current + sizeof(HeapHeader) + size);
|
||||||
|
// Safety check: if new_header address is wild, abort!
|
||||||
|
if ((uintptr_t)new_header < 0x80000000 || (uintptr_t)new_header > 0x88000000) {
|
||||||
|
kpanic("Splitting created invalid pointer!");
|
||||||
|
}
|
||||||
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;
|
||||||
|
|
@ -113,7 +112,13 @@ void kfree(void *ptr) {
|
||||||
}
|
}
|
||||||
header->is_free = 1;
|
header->is_free = 1;
|
||||||
|
|
||||||
kcoalesce(header);
|
HeapHeader *temp = heap_free_list;
|
||||||
|
while (temp != NULL) {
|
||||||
|
if (temp->is_free) {
|
||||||
|
kcoalesce(temp);
|
||||||
|
}
|
||||||
|
temp = temp->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void kcoalesce(HeapHeader *header) {
|
void kcoalesce(HeapHeader *header) {
|
||||||
|
|
@ -141,4 +146,76 @@ void test_memory_integrity() {
|
||||||
}
|
}
|
||||||
kfree(a);
|
kfree(a);
|
||||||
kfree(b);
|
kfree(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_memory_alignment() {
|
||||||
|
kprint("Running Alignment Test...\n");
|
||||||
|
for (int i = 1; i <= 64; i++) {
|
||||||
|
void *ptr = kmalloc(i);
|
||||||
|
if (((uintptr_t)ptr % 8) != 0) {
|
||||||
|
kprint("Misaligned allocation detected!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
kfree(ptr);
|
||||||
|
}
|
||||||
|
kprint("All allocations are properly aligned!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_memory_stress() {
|
||||||
|
kprintf("Starting Stress Test...\n");
|
||||||
|
heap_stats();
|
||||||
|
void *ptrs[50] = {0}; // Track allocated pointers
|
||||||
|
uint32_t seed = 0xACE2026; // Example seed
|
||||||
|
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
kprintf("Iteration %d\n", i);
|
||||||
|
// 1. Randomly allocate or free
|
||||||
|
int idx = i % 50;
|
||||||
|
if (ptrs[idx] == NULL) {
|
||||||
|
size_t size = (seed % 256) + 1;
|
||||||
|
ptrs[idx] = kmalloc(size);
|
||||||
|
// Optional: fill with data to check integrity later
|
||||||
|
} else {
|
||||||
|
kfree(ptrs[idx]);
|
||||||
|
ptrs[idx] = NULL;
|
||||||
|
}
|
||||||
|
// Simple LCG to "randomize" seed
|
||||||
|
seed = (seed * 1103515245 + 12345) & 0x7fffffff;
|
||||||
|
}
|
||||||
|
kprintf("Stress Test Finished. Check heap_stats() for sanity.\n");
|
||||||
|
heap_stats();
|
||||||
|
}
|
||||||
|
|
||||||
|
void heap_stats() {
|
||||||
|
size_t free_size = 0;
|
||||||
|
size_t used_size = 0;
|
||||||
|
size_t free_blocks = 0;
|
||||||
|
size_t used_blocks = 0;
|
||||||
|
|
||||||
|
HeapHeader *current = heap_free_list;
|
||||||
|
|
||||||
|
while (current != NULL) {
|
||||||
|
if (current->is_free) {
|
||||||
|
free_size += current->size;
|
||||||
|
free_blocks++;
|
||||||
|
} else {
|
||||||
|
used_size += current->size;
|
||||||
|
used_blocks++;
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
kprint("--- Kernel Heap Stats ---\n");
|
||||||
|
kprint("Used: "); kprint_hex(used_size); kprint(" bytes in "); kprint_int(used_blocks); kprint(" blocks\n");
|
||||||
|
kprint("Free: "); kprint_hex(free_size); kprint(" bytes in "); kprint_int(free_blocks); kprint(" blocks\n");
|
||||||
|
kprint("Total metadata overhead: "); kprint_int((used_blocks + free_blocks) * sizeof(HeapHeader)); kprint(" bytes\n");
|
||||||
|
kprint("-------------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memset(void *s, int c, size_t n) {
|
||||||
|
unsigned char *p = s;
|
||||||
|
while (n--) {
|
||||||
|
*p++ = (unsigned char)c;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
@ -22,5 +22,8 @@ void *kmalloc(size_t size);
|
||||||
void kfree(void *ptr);
|
void kfree(void *ptr);
|
||||||
void kcoalesce(HeapHeader *header);
|
void kcoalesce(HeapHeader *header);
|
||||||
void test_memory_integrity();
|
void test_memory_integrity();
|
||||||
|
void test_memory_alignment();
|
||||||
|
void test_memory_stress();
|
||||||
|
void heap_stats();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ void handle_trap() {
|
||||||
unsigned long cause;
|
unsigned long cause;
|
||||||
__asm__ volatile("csrr %0, mcause" : "=r"(cause));
|
__asm__ volatile("csrr %0, mcause" : "=r"(cause));
|
||||||
|
|
||||||
|
// fault address (if applicable)
|
||||||
|
uintptr_t mtval;
|
||||||
|
asm volatile("csrr %0, mtval" : "=r"(mtval));
|
||||||
|
|
||||||
switch(cause) {
|
switch(cause) {
|
||||||
case 0: kprint("Reason: Instruction Address Misaligned\n"); break;
|
case 0: kprint("Reason: Instruction Address Misaligned\n"); break;
|
||||||
case 1: kprint("Reason: Instruction Access Fault\n"); break;
|
case 1: kprint("Reason: Instruction Access Fault\n"); break;
|
||||||
|
|
@ -44,6 +48,7 @@ void handle_trap() {
|
||||||
default:
|
default:
|
||||||
kprintf("Reason: Unknown Exception Code %d\n", cause);
|
kprintf("Reason: Unknown Exception Code %d\n", cause);
|
||||||
}
|
}
|
||||||
|
kprintf("Faulting Address (if applicable): 0x%p\n", mtval);
|
||||||
|
|
||||||
poweroff();
|
poweroff();
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue