1
0
Fork 0

fix/kernel: Fixed kfree to be more safe

This commit is contained in:
Kevin Alavik 2025-05-26 21:22:46 +02:00
parent d0e4149de5
commit b41cc11e39
No known key found for this signature in database
GPG key ID: 47AAEA397DB76AD0
4 changed files with 81 additions and 36 deletions

View file

@ -6,6 +6,7 @@
#include <boot/emk.h>
#include <util/align.h>
#include <sys/kpanic.h>
#include <util/log.h>
void *pool;
block_t *freelist = NULL;
@ -18,6 +19,7 @@ void heap_init()
freelist = (block_t *)pool;
freelist->size = (FF_POOL_SIZE * PAGE_SIZE) - sizeof(block_t);
freelist->next = NULL;
log_early("Initialized heap with a pool of %d pages (~%dMB)", FF_POOL_SIZE, DIV_ROUND_UP(FF_POOL_SIZE * PAGE_SIZE, 1024 * 1024));
}
void *kmalloc(size_t size)
@ -73,10 +75,35 @@ void kfree(void *ptr)
if (!ptr)
return;
/* get block header */
block_t *block = (block_t *)((uint8_t *)ptr - sizeof(block_t));
/* insert freed block at head of freelist */
block->next = freelist;
freelist = block;
}
/* insert block sorted by address in freelist */
block_t **cur = &freelist;
while (*cur && *cur < block)
{
cur = &(*cur)->next;
}
block->next = *cur;
*cur = block;
/* coalesce with next block if adjacent */
if (block->next && (uint8_t *)block + sizeof(block_t) + block->size == (uint8_t *)block->next)
{
block->size += sizeof(block_t) + block->next->size;
block->next = block->next->next;
}
/* coalesce with previous block if adjacent */
if (cur != &freelist)
{
block_t *prev = freelist;
while (prev->next != block)
prev = prev->next;
if ((uint8_t *)prev + sizeof(block_t) + prev->size == (uint8_t *)block)
{
prev->size += sizeof(block_t) + block->size;
prev->next = block->next;
}
}
}

View file

@ -7,7 +7,9 @@
#include <stdint.h>
#include <stddef.h>
#define FF_POOL_SIZE 512 // 2MB, in pages
#ifndef FF_POOL_SIZE
#define FF_POOL_SIZE 512
#endif // FF_POOL_SIZE
typedef struct block
{