Developing a memory manager and for some reason cli works normally even when memory manager doesnt give it memory? When memory manager is initialised cli retrieves a bit of memory from it and Memory Manager correctly recongises it as allocated memory.
Is there any explanation for this or is it a issue?
Adding Memory Manager below.
#include "memory.h"
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "snprintf.h"
#include "vga.h"
extern char __memory_pool_start;
extern char __memory_pool_end;
#define ALIGNMENT 8
#define ALIGN_MASK (ALIGNMENT - 1)
#define ERR_NO_MEMORY 1
#define KMALLOC_FLAG_RESERVED 0x1
typedef struct MemoryBlock {
size_t size;
bool is_free;
struct MemoryBlock* next;
struct MemoryBlock* prev;
} MemoryBlock;
static char* memory_pool_start;
static size_t memory_pool_size;
static MemoryBlock* free_list = NULL;
static MemoryBlock* allocated_list = NULL;
static MemoryBlock* reserved_free_list = NULL;
static MemoryBlock* reserved_allocated_list = NULL;
static int last_error;
static size_t align_size(size_t size) {
return (size + ALIGN_MASK) & ~ALIGN_MASK;
}
void initialize_memory_manager() {
memory_pool_start = &__memory_pool_start;
memory_pool_size = &__memory_pool_end - &__memory_pool_start;
size_t reserved_size = memory_pool_size / 4;
size_t general_size = memory_pool_size - reserved_size;
// Initialize general pool
free_list = (MemoryBlock*)memory_pool_start;
free_list->size = general_size - sizeof(MemoryBlock);
free_list->is_free = true;
free_list->next = NULL;
free_list->prev = NULL;
// Initialize reserved pool
reserved_free_list = (MemoryBlock*)(memory_pool_start + general_size);
reserved_free_list->size = reserved_size - sizeof(MemoryBlock);
reserved_free_list->is_free = true;
reserved_free_list->next = NULL;
reserved_free_list->prev = NULL;
}
static void split_block(MemoryBlock* block, size_t size) {
if (block->size >= size + sizeof(MemoryBlock) + ALIGNMENT) {
MemoryBlock* new_block = (MemoryBlock*)((char*)block + sizeof(MemoryBlock) + size);
new_block->size = block->size - size - sizeof(MemoryBlock);
new_block->is_free = true;
new_block->next = block->next;
new_block->prev = block;
if (block->next) {
block->next->prev = new_block;
}
block->next = new_block;
block->size = size;
}
}
static void coalesce_blocks(MemoryBlock* block) {
if (block->next && block->next->is_free) {
block->size += sizeof(MemoryBlock) + block->next->size;
block->next = block->next->next;
if (block->next) {
block->next->prev = block;
}
}
if (block->prev && block->prev->is_free) {
block->prev->size += sizeof(MemoryBlock) + block->size;
block->prev->next = block->next;
if (block->next) {
block->next->prev = block->prev;
}
}
}
void defragment_memory() {
MemoryBlock* current = free_list;
while (current && current->next) {
if (current->is_free && current->next->is_free) {
coalesce_blocks(current);
} else {
current = current->next;
}
}
current = reserved_free_list;
while (current && current->next) {
if (current->is_free && current->next->is_free) {
coalesce_blocks(current);
} else {
current = current->next;
}
}
}
void* kmalloc(size_t size, int flags) {
size = align_size(size);
MemoryBlock* current = (flags & KMALLOC_FLAG_RESERVED) ? reserved_free_list : free_list;
// Debugging output
char buffer[256];
snprintf(buffer, sizeof(buffer), "Requesting %zu bytes from kmalloc\n", size);
print_str(buffer);
while (current) {
if (current->is_free && current->size >= size) {
split_block(current, size);
current->is_free = false;
// Remove from free list
if (current->prev) {
current->prev->next = current->next;
} else {
if (flags & KMALLOC_FLAG_RESERVED) {
reserved_free_list = current->next;
} else {
free_list = current->next;
}
}
if (current->next) {
current->next->prev = current->prev;
}
// Add to allocated list
current->next = (flags & KMALLOC_FLAG_RESERVED) ? reserved_allocated_list : allocated_list;
if (flags & KMALLOC_FLAG_RESERVED) {
if (reserved_allocated_list) {
reserved_allocated_list->prev = current;
}
reserved_allocated_list = current;
} else {
if (allocated_list) {
allocated_list->prev = current;
}
allocated_list = current;
}
// Debugging output
snprintf(buffer, sizeof(buffer), "Allocated %zu bytes at %p\n", size, (void*)((char*)current + sizeof(MemoryBlock)));
print_str(buffer);
return (void*)((char*)current + sizeof(MemoryBlock));
}
current = current->next;
}
last_error = ERR_NO_MEMORY;
print_str("kmalloc failed: Out of memory\n");
return NULL;
}
void kfree(void* ptr) {
if (!ptr) return;
MemoryBlock* block = (MemoryBlock*)((char*)ptr - sizeof(MemoryBlock));
block->is_free = true;
// Remove from allocated list
if (block->prev) {
block->prev->next = block->next;
} else {
if (block >= (MemoryBlock*)memory_pool_start && block < (MemoryBlock*)(memory_pool_start + memory_pool_size / 4 * 3)) {
allocated_list = block->next;
} else {
reserved_allocated_list = block->next;
}
}
if (block->next) {
block->next->prev = block->prev;
}
coalesce_blocks(block);
}
const char* get_error_message(int error_code) {
switch (error_code) {
case ERR_NO_MEMORY:
return "Out of memory";
default:
return "Unknown error";
}
}
void check_memory_leaks() {
if (allocated_list || reserved_allocated_list) {
print_str("Memory Leak Warning: The following blocks were not freed:\n");
MemoryBlock* current = allocated_list;
while (current) {
char buffer[256];
snprintf(buffer, sizeof(buffer), "Leaked Block: Size = %zu bytes\n", current->size);
print_str(buffer);
current = current->next;
}
current = reserved_allocated_list;
while (current) {
char buffer[256];
snprintf(buffer, sizeof(buffer), "Leaked Block: Size = %zu bytes\n", current->size);
print_str(buffer);
current = current->next;
}
} else {
print_str("No memory leaks detected.\n");
}
}
void print_memory_stats() {
size_t total_memory = memory_pool_size;
size_t used_memory = 0;
size_t free_memory = 0;
size_t reserved_free_memory = 0;
MemoryBlock* current = free_list;
while (current) {
if (current->is_free) {
free_memory += current->size + sizeof(MemoryBlock);
}
current = current->next;
}
current = allocated_list;
while (current) {
if (!current->is_free) {
used_memory += current->size + sizeof(MemoryBlock);
}
current = current->next;
}
current = reserved_free_list;
while (current) {
if (current->is_free) {
reserved_free_memory += current->size + sizeof(MemoryBlock);
}
current = current->next;
}
current = reserved_allocated_list;
while (current) {
if (!current->is_free) {
used_memory += current->size + sizeof(MemoryBlock);
}
current = current->next;
}
char buffer[256];
snprintf(buffer, sizeof(buffer), "Total Memory: %zu bytes\n", total_memory);
print_str(buffer);
snprintf(buffer, sizeof(buffer), "Used Memory: %zu bytes\n", used_memory);
print_str(buffer);
snprintf(buffer, sizeof(buffer), "Free Memory: %zu bytes\n", free_memory);
print_str(buffer);
snprintf(buffer, sizeof(buffer), "Reserved Free Memory: %zu bytes\n", reserved_free_memory);
print_str(buffer);
}
__attribute__((constructor))
static void setup_memory() {
initialize_memory_manager();
}
__attribute__((destructor))
static void cleanup_memory() {
check_memory_leaks();
}
And the part of cli.
#define MAX_COMMAND_LENGTH 256 // Requested memory
char *command_buffer = NULL;
void init_cli() {
command_buffer = (char *)kmalloc(MAX_COMMAND_LENGTH, 0); // Allocate memory for command_buffer
if (command_buffer == NULL) {
print_set_color(PRINT_COLOR_RED, PRINT_COLOR_BLACK);
print_str("Failed to allocate memory for command buffer\n");
return;
}
set_cursor_position(CLI_PROMPT_LENGTH);
print_clear();
print_prompt();
}
Added some debug prints and everything seems to be correct.But for some reason location of the allocated memory isnt printed.
You need to sign in to view this answers
Leave feedback about this