stos: pool: Handle page chaining while under pressure
Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
+55
-3
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user