stos: pool: Handle page chaining while under pressure

Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
Chloe M.
2026-06-24 07:31:39 +00:00
parent 98bc156e51
commit 05c4c0b059
+55 -3
View File
@@ -11,6 +11,7 @@
#include <hal/kpcr.h> #include <hal/kpcr.h>
#include <mm/vmm.h> #include <mm/vmm.h>
#include <string.h> #include <string.h>
#include <bitops.h>
#define DTRACE(Fmt, ...) \ #define DTRACE(Fmt, ...) \
TRACE("[ POOL ]: " Fmt, ##__VA_ARGS__) TRACE("[ POOL ]: " Fmt, ##__VA_ARGS__)
@@ -42,9 +43,37 @@ PoolInitBlock(MEMORY_BLOCK *Block)
} }
/* /*
* Internally used by AllocatePoolWithTag() * Allocates a new memory page to a block and returns it
* *
* TODO: Handle running out of pages * @Block: Block to allocate page to
*/
static MEMORY_PAGE *
BlockNewPage(MEMORY_BLOCK *Block)
{
MEMORY_PAGE *Page, *Last;
if (Block == NULL) {
return NULL;
}
Last = Block->LastPage;
if (Last == NULL) {
return NULL;
}
Page = MmAllocPages(1);
if (Page == NULL) {
return NULL;
}
RtlMemSet(Page, 0, sizeof(*Page));
Last->Next = Page;
Block->LastPage = Page;
return Page;
}
/*
* Internally used by AllocatePoolWithTag()
*/ */
static VOID * static VOID *
AllocateFromBlock(UCHAR BlockIndex, MEMORY_BLOCK *Block, USIZE Count) AllocateFromBlock(UCHAR BlockIndex, MEMORY_BLOCK *Block, USIZE Count)
@@ -52,7 +81,10 @@ AllocateFromBlock(UCHAR BlockIndex, MEMORY_BLOCK *Block, USIZE Count)
USIZE Gran, Idx; USIZE Gran, Idx;
USIZE BitsNeeded, BitsFound = 0; USIZE BitsNeeded, BitsFound = 0;
SSIZE BitBase = -1; SSIZE BitBase = -1;
USIZE BitsSet, Occupied;
USIZE MaxOccupied;
MEMORY_PAGE *Page; MEMORY_PAGE *Page;
ST_STATUS Status;
if (Block == NULL || Count == 0) { if (Block == NULL || Count == 0) {
return NULL; return NULL;
@@ -60,7 +92,7 @@ AllocateFromBlock(UCHAR BlockIndex, MEMORY_BLOCK *Block, USIZE Count)
Gran = LEVEL_GRAN(BlockIndex); Gran = LEVEL_GRAN(BlockIndex);
BitsNeeded = Count / Gran; BitsNeeded = Count / Gran;
Page = Block->FirstPage; /* TODO: Handle many */ Page = Block->LastPage;
for (Idx = 0; Idx < sizeof(Page->Bitmap) * 8; ++Idx) { for (Idx = 0; Idx < sizeof(Page->Bitmap) * 8; ++Idx) {
if (!TESTBIT(&Page->Bitmap, Idx) && BitsFound < BitsNeeded) { if (!TESTBIT(&Page->Bitmap, Idx) && BitsFound < BitsNeeded) {
@@ -82,6 +114,26 @@ AllocateFromBlock(UCHAR BlockIndex, MEMORY_BLOCK *Block, USIZE Count)
SETBIT(&Page->Bitmap, Idx); SETBIT(&Page->Bitmap, Idx);
} }
BitsSet = PopCnt(Page->Bitmap);
Occupied = BitsSet * Gran;
MaxOccupied = PAGESIZE - sizeof(MEMORY_PAGE);
MaxOccupied = ALIGN_DOWN(MaxOccupied, Gran);
/*
* If there are no more bytes to grab in this page
*/
if (Occupied >= MaxOccupied || BitsFound < BitsNeeded) {
Page = BlockNewPage(Block);
if (Page == NULL) {
return NULL;
}
/* Need to allocate again? */
if (BitsFound < BitsNeeded) {
return AllocateFromBlock(BlockIndex, Block, Count);
}
}
return (BitsFound >= BitsNeeded) return (BitsFound >= BitsNeeded)
? PTR_OFFSET(Page, sizeof(MEMORY_PAGE) + (BitBase * Gran)) ? PTR_OFFSET(Page, sizeof(MEMORY_PAGE) + (BitBase * Gran))
: NULL; : NULL;