modified rbtree code to not need the local key value; also set compiler to treat all warnings as errors

This commit is contained in:
Eric J. Bowersox 2013-06-07 21:31:32 -06:00
parent 0a31211d96
commit 3f4e807025
6 changed files with 195 additions and 80 deletions

View File

@ -44,9 +44,9 @@ OBJCOPY := $(ARMDIR)/$(ARMPREFIX)-objcopy
# Define the default flags for compilation.
DEFS := -D__COMROGUE_INTERNALS__
INCLUDES := -I$(CRBASEDIR)/include -I$(CRBASEDIR)/idl
CFLAGS := $(INCLUDES) -mabi=aapcs -mfloat-abi=hard -mcpu=arm1176jzf-s -Wall -O2 \
CFLAGS := $(INCLUDES) -mabi=aapcs -mfloat-abi=hard -mcpu=arm1176jzf-s -Wall -Werror -O2 \
-nostdlib -nostartfiles -ffreestanding $(DEFS)
AFLAGS := -mcpu=arm1176jzf-s -mfloat-abi=hard
AFLAGS := -mcpu=arm1176jzf-s -mfloat-abi=hard --fatal-warnings
ASM_CPP_FLAGS := $(INCLUDES) $(DEFS) -D__ASM__
# Standard rule for pre-processing linker script files.

View File

@ -49,7 +49,8 @@
/* Nodes in the page table tree. */
typedef struct tagPAGENODE {
RBTREENODE rbtn; /* RBT node containing physical address as key */
RBTREENODE rbtn; /* RBT node */
PHYSADDR paPageTable; /* physical address of page table */
PPAGETAB ppt; /* pointer to page table */
} PAGENODE, *PPAGENODE;

View File

@ -57,48 +57,56 @@ typedef INT32 (*PFNTREECOMPARE)(TREEKEY, TREEKEY);
/* The basic tree node. */
typedef struct tagRBTREENODE {
struct tagRBTREENODE *ptnLeft; /* pointer to left child */
UINT_PTR ptnRightColor; /* pointer to right child AND color stored in low-order bit */
TREEKEY treekey; /* key value */
struct tagRBTREENODE *ptnLeft; /* pointer to left child */
UINT_PTR ptnRightColor; /* pointer to right child AND color stored in low-order bit */
} RBTREENODE, *PRBTREENODE;
/* Tree node macros, mostly to access either color or pointer or both from the ptnRightColor field */
/* Tree node macros, mostly to access either color or pointer or both from the pRightColor field */
#define rbtNodeRight(ptn) ((PRBTREENODE)((ptn)->ptnRightColor & ~1))
#define rbtNodeColor(ptn) ((ptn)->ptnRightColor & 1)
#define rbtIsRed(ptn) ((ptn) ? rbtNodeColor(ptn) : FALSE)
#define rbtSetNodeRight(ptn, ptnR) \
do { (ptn)->ptnRightColor = (((UINT_PTR)(ptnR)) & ~1) | ((ptn)->ptnRightColor & 1); } while (0)
do { (ptn)->ptnRightColor = (((UINT_PTR)(ptnR)) & ~1) | ((ptn)->ptnRightColor & 1); } while (0)
#define rbtSetNodeColor(ptn, clr) \
do { (ptn)->ptnRightColor = ((ptn)->ptnRightColor & ~1) | ((clr) ? 1 : 0); } while (0)
#define rbtToggleColor(ptn) do { if (ptn) (ptn)->ptnRightColor ^= 1; } while (0)
#define rbtInitNode(ptn, ptnL, ptnR, clr, key) \
do { (ptn)->ptnLeft = (ptnL); (ptn)->ptnRightColor = (((UINT_PTR)(ptnR)) & ~1) | ((clr) ? 1 : 0); \
(ptn)->treekey = (TREEKEY)(key); } while (0)
#define rbtNewNode(ptn, key) rbtInitNode(ptn, NULL, NULL, RED, key)
#define rbtInitNode(ptn, ptnL, ptnR, clr) \
do { (ptn)->ptnLeft = (ptnL); (ptn)->ptnRightColor = (((UINT_PTR)(ptnR)) & ~1) | ((clr) ? 1 : 0); } while (0)
#define rbtNewNode(ptn) rbtInitNode(ptn, NULL, NULL, RED)
/* Accessor functions common to tree instances. */
typedef TREEKEY (*PFNGETTREEKEY)(PVOID);
typedef PRBTREENODE (*PFNGETTREENODEPTR)(PVOID);
typedef PVOID (*PFNGETFROMTREENODEPTR)(PRBTREENODE);
/* The head-of-tree structure. */
typedef struct tagRBTREE {
PFNTREECOMPARE pfnTreeCompare; /* pointer to comparison function */
PRBTREENODE ptnRoot; /* pointer to root of tree */
PFNTREECOMPARE pfnTreeCompare; /* pointer to comparison function */
PFNGETTREEKEY pfnGetTreeKey; /* pointer to key-retrieval function */
PFNGETTREENODEPTR pfnGetNodePtr; /* pointer to node-pointer retrieval function */
PFNGETFROMTREENODEPTR pfnGetFromNodePtr; /* pointer to func to get the tree node from node pointer */
PRBTREENODE ptnRoot; /* pointer to root of tree */
} RBTREE, *PRBTREE;
/* Tree macros. */
#define rbtInitTree(ptree, pfnCompare) \
do { (ptree)->pfnTreeCompare = (pfnCompare); (ptree)->ptnRoot = NULL; } while (0)
#define rbtInitTree(ptree, pfnCompare, pfnGetKey, pfnToNodePtr, pfnFromNodePtr) \
do { (ptree)->pfnTreeCompare = (pfnCompare); (ptree)->pfnGetTreeKey = (pfnGetKey); \
(ptree)->pfnGetNodePtr = (pfnToNodePtr); (ptree)->pfnGetFromNodePtr = (pfnFromNodePtr); \
(ptree)->ptnRoot = NULL; } while (0)
#define rbtIsEmpty(ptree) MAKEBOOL(!((ptree)->ptnRoot))
/* Type of function used by RbtWalk. */
typedef BOOL (*PFNRBTWALK)(PRBTREE, PRBTREENODE, PVOID);
typedef BOOL (*PFNRBTWALK)(PRBTREE, PVOID, PVOID);
/* Function prototypes. */
CDECL_BEGIN
extern INT32 RbtStdCompareByValue(TREEKEY k1, TREEKEY k2);
extern void RbtInsert(PRBTREE ptree, PRBTREENODE ptnNew);
extern PRBTREENODE RbtFind(PRBTREE ptree, TREEKEY key);
extern PRBTREENODE RbtFindPredecessor(PRBTREE ptree, TREEKEY key);
extern PRBTREENODE RbtFindSuccessor(PRBTREE ptree, TREEKEY key);
extern PRBTREENODE RbtFindMin(PRBTREE ptree);
extern void RbtInsert(PRBTREE ptree, PVOID ptnNew);
extern PVOID RbtFind(PRBTREE ptree, TREEKEY key);
extern PVOID RbtFindPredecessor(PRBTREE ptree, TREEKEY key);
extern PVOID RbtFindSuccessor(PRBTREE ptree, TREEKEY key);
extern PVOID RbtFindMin(PRBTREE ptree);
extern void RbtDelete(PRBTREE ptree, TREEKEY key);
extern BOOL RbtWalk(PRBTREE ptree, PFNRBTWALK pfnWalk, PVOID pData);

View File

@ -31,12 +31,6 @@
*/
#include <comrogue/types.h>
#include <comrogue/internals/rbtree.h>
#include <comrogue/internals/trace.h>
#ifdef THIS_FILE
#undef THIS_FILE
DECLARE_THIS_FILE
#endif
/*------------------------------------------------------------------------------------------------------
* An implementation of left-leaning red-black 2-3 trees as detailed in "Left-leaning Red-Black Trees,"
@ -155,8 +149,9 @@ static PRBTREENODE fix_up(PRBTREENODE ptn)
* - ptree = Pointer to the tree head structure, containing the compare function.
* - ptnCurrent = Pointer to the current subtree we're inserting into.
* - ptnNew = Pointer to the new tree node to be inserted. This node must have been initialized with
* the rbtInitNode macro to contain a key, NULL left and right pointers, and be red. It is
* the rbtInitNode macro to contain NULL left and right pointers and be red. It is
* assumed that the node's key does NOT already exist in the tree.
* - keyNew = Tree key for the new node.
*
* Returns:
* The pointer to the new subtree after the insertion is performed.
@ -165,18 +160,20 @@ static PRBTREENODE fix_up(PRBTREENODE ptn)
* This function is recursive; however, the nature of the tree guarantees that the stack space consumed
* by its stack frames will be O(log n).
*/
static PRBTREENODE insert_under(PRBTREE ptree, PRBTREENODE ptnCurrent, PRBTREENODE ptnNew)
static PRBTREENODE insert_under(PRBTREE ptree, PRBTREENODE ptnCurrent, PRBTREENODE ptnNew, TREEKEY keyNew)
{
register int cmp; /* compare result */
register TREEKEY keyCurrent;
if (!ptnCurrent)
return ptnNew; /* degenerate case */
cmp = (*(ptree->pfnTreeCompare))(ptnNew->treekey, ptnCurrent->treekey);
keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent));
cmp = (*(ptree->pfnTreeCompare))(keyNew, keyCurrent);
//ASSERT(cmp != 0);
if (cmp < 0)
ptnCurrent->ptnLeft = insert_under(ptree, ptnCurrent->ptnLeft, ptnNew);
ptnCurrent->ptnLeft = insert_under(ptree, ptnCurrent->ptnLeft, ptnNew, keyNew);
else
rbtSetNodeRight(ptnCurrent, insert_under(ptree, rbtNodeRight(ptnCurrent), ptnNew));
rbtSetNodeRight(ptnCurrent, insert_under(ptree, rbtNodeRight(ptnCurrent), ptnNew, keyNew));
return fix_up(ptnCurrent);
}
@ -185,16 +182,17 @@ static PRBTREENODE insert_under(PRBTREE ptree, PRBTREENODE ptnCurrent, PRBTREENO
*
* Parameters:
* - ptree = Pointer to the tree head structure.
* - ptnNew = Pointer to the new tree node to be inserted. This node must have been initialized with
* the rbtInitNode macro to contain a key, NULL left and right pointers, and be red. It is
* assumed that the node's key does NOT already exist in the tree.
* - pNew = Pointer to the new tree node to be inserted. This node must have been initialized with
* the rbtInitNode macro to contain NULL left and right pointers, and be red. It is
* assumed that the node's key does NOT already exist in the tree.
*
* Returns:
* Nothing.
*/
void RbtInsert(PRBTREE ptree, PRBTREENODE ptnNew)
void RbtInsert(PRBTREE ptree, PVOID pNew)
{
ptree->ptnRoot = insert_under(ptree, ptree->ptnRoot, ptnNew);
ptree->ptnRoot = insert_under(ptree, ptree->ptnRoot, (*(ptree->pfnGetNodePtr))(pNew),
(*(ptree->pfnGetTreeKey))(pNew));
rbtSetNodeColor(ptree->ptnRoot, BLACK);
}
@ -208,23 +206,25 @@ void RbtInsert(PRBTREE ptree, PRBTREENODE ptnNew)
* Returns:
* Pointer to the node where the key is found, or NULL if not found.
*/
PRBTREENODE RbtFind(PRBTREE ptree, TREEKEY key)
PVOID RbtFind(PRBTREE ptree, TREEKEY key)
{
register PVOID pCurrent; /* pointer to current node */
register PRBTREENODE ptn = ptree->ptnRoot; /* current node */
register int cmp; /* compare result */
while (ptn)
{
cmp = (*(ptree->pfnTreeCompare))(key, ptn->treekey);
pCurrent = (*(ptree->pfnGetFromNodePtr))(ptn);
cmp = (*(ptree->pfnTreeCompare))(key, (*(ptree->pfnGetTreeKey))(pCurrent));
if (cmp == 0)
break; /* found */
return pCurrent; /* found */
else if (cmp < 0)
ptn = ptn->ptnLeft;
else
ptn = rbtNodeRight(ptn);
}
return ptn;
return NULL;
}
/*
@ -239,27 +239,29 @@ PRBTREENODE RbtFind(PRBTREE ptree, TREEKEY key)
* Pointer to the node where the key is found, or pointer to the predecessor node, or NULL if the key
* is less than every key in the tree and hence has no predecessor.
*/
PRBTREENODE RbtFindPredecessor(PRBTREE ptree, TREEKEY key)
PVOID RbtFindPredecessor(PRBTREE ptree, TREEKEY key)
{
register PVOID pCurrent; /* pointer to current node */
register PRBTREENODE ptn = ptree->ptnRoot; /* current node */
register int cmp; /* compare result */
while (ptn)
{
cmp = (*(ptree->pfnTreeCompare))(key, ptn->treekey);
pCurrent = (*(ptree->pfnGetFromNodePtr))(ptn);
cmp = (*(ptree->pfnTreeCompare))(key, (*(ptree->pfnGetTreeKey))(pCurrent));
if (cmp == 0)
break; /* found */
return pCurrent; /* found */
else if (cmp > 0)
{
if (rbtNodeRight(ptn))
ptn = rbtNodeRight(ptn);
else
break; /* found predecessor */
return pCurrent; /* found predecessor */
}
else
ptn = ptn->ptnLeft;
}
return ptn;
return NULL; /* not found */
}
/*
@ -274,27 +276,29 @@ PRBTREENODE RbtFindPredecessor(PRBTREE ptree, TREEKEY key)
* Pointer to the node where the key is found, or pointer to the successor node, or NULL if the key
* is greater than every key in the tree and hence has no successor.
*/
PRBTREENODE RbtFindSuccessor(PRBTREE ptree, TREEKEY key)
PVOID RbtFindSuccessor(PRBTREE ptree, TREEKEY key)
{
register PVOID pCurrent; /* pointer to current node */
register PRBTREENODE ptn = ptree->ptnRoot; /* current node */
register int cmp; /* compare result */
while (ptn)
{
cmp = (*(ptree->pfnTreeCompare))(key, ptn->treekey);
pCurrent = (*(ptree->pfnGetFromNodePtr))(ptn);
cmp = (*(ptree->pfnTreeCompare))(key, (*(ptree->pfnGetTreeKey))(pCurrent));
if (cmp == 0)
break; /* found */
return pCurrent; /* found */
else if (cmp < 0)
{
if (ptn->ptnLeft)
ptn = ptn->ptnLeft;
else
break; /* found successor */
return pCurrent; /* found successor */
}
else
ptn = rbtNodeRight(ptn);
}
return ptn;
return NULL; /* not found */
}
/*
@ -322,9 +326,11 @@ static PRBTREENODE find_min(PRBTREENODE ptn)
* Returns:
* Pointer to the leftmost node in the tree. If the tree has no nodes, NULL is returned.
*/
PRBTREENODE RbtFindMin(PRBTREE ptree)
PVOID RbtFindMin(PRBTREE ptree)
{
return ptree->ptnRoot ? find_min(ptree->ptnRoot) : NULL;
if (ptree->ptnRoot)
return (*(ptree->pfnGetFromNodePtr))(find_min(ptree->ptnRoot));
return NULL;
}
/*
@ -412,7 +418,8 @@ static PRBTREENODE delete_min(PRBTREENODE ptn)
*/
static PRBTREENODE delete_from_under(PRBTREE ptree, PRBTREENODE ptnCurrent, TREEKEY key)
{
register int cmp = (*(ptree->pfnTreeCompare))(key, ptnCurrent->treekey);
register TREEKEY keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent));
register int cmp = (*(ptree->pfnTreeCompare))(key, keyCurrent);
if (cmp < 0)
{
/* hunt down the left subtree */
@ -425,7 +432,8 @@ static PRBTREENODE delete_from_under(PRBTREE ptree, PRBTREENODE ptnCurrent, TREE
if (rbtIsRed(ptnCurrent->ptnLeft))
{
ptnCurrent = rotate_right(ptnCurrent);
cmp = (*(ptree->pfnTreeCompare))(key, ptnCurrent->treekey);
keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent));
cmp = (*(ptree->pfnTreeCompare))(key, keyCurrent);
}
if ((cmp == 0) && !rbtNodeRight(ptnCurrent))
return ptnCurrent->ptnLeft; /* degenerate case */
@ -433,7 +441,8 @@ static PRBTREENODE delete_from_under(PRBTREE ptree, PRBTREENODE ptnCurrent, TREE
&& (!rbtNodeRight(ptnCurrent) || !rbtIsRed(rbtNodeRight(ptnCurrent)->ptnLeft)))
{
ptnCurrent = move_red_right(ptnCurrent);
cmp = (*(ptree->pfnTreeCompare))(key, ptnCurrent->treekey);
keyCurrent = (*(ptree->pfnGetTreeKey))((*(ptree->pfnGetFromNodePtr))(ptnCurrent));
cmp = (*(ptree->pfnTreeCompare))(key, keyCurrent);
}
if (cmp == 0)
{
@ -495,7 +504,7 @@ static BOOL do_walk(PRBTREE ptree, PRBTREENODE ptn, PFNRBTWALK pfnWalk, PVOID pD
if (ptn->ptnLeft)
rc = do_walk(ptree, ptn->ptnLeft, pfnWalk, pData);
if (rc)
rc = (*pfnWalk)(ptree, ptn, pData);
rc = (*pfnWalk)(ptree, (*(ptree->pfnGetFromNodePtr))(ptn), pData);
if (rc && rbtNodeRight(ptn))
rc = do_walk(ptree, rbtNodeRight(ptn), pfnWalk, pData);
return rc;

View File

@ -176,6 +176,48 @@ typedef struct tagALLOC_STRUC {
static RBTREE g_rbtFreeAddrs; /* free address tree */
static PMALLOC g_pMalloc = NULL; /* allocator we use */
/*
* Given a pointer to an ADDRTREENODE, returns its key value (pointer to its interval).
*
* Parameters:
* - patn = Pointer to the ADDRTREENODE.
*
* Returns:
* Pointer to its embedded address interval.
*/
static TREEKEY get_interval_from_addrtreenode(PVOID patn)
{
return (TREEKEY)(&(((PADDRTREENODE)patn)->ai));
}
/*
* Given a pointer to an ADDRTREENODE, returns a pointer to its embedded RBTREENODE.
*
* Parameters:
* - patn = Pointer to the ADDRTREENODE.
*
* Returns:
* Pointer to the embedded RBTREENODE.
*/
static PRBTREENODE get_rbtreenode_from_addrtreenode(PVOID patn)
{
return &(((PADDRTREENODE)patn)->rbtn);
}
/*
* Given a pointer to a RBTREENODE, returns a pointer to the ADDRTREENODE containing it.
*
* Parameters:
* - ptn = Pointer to the RBTREENODE.
*
* Returns:
* Pointer to the containing ADDRTREENODE.
*/
static PVOID get_addrtreenode_from_rbtreenode(PRBTREENODE ptn)
{
return (PVOID)(((PCHAR)ptn) - OFFSETOF(ADDRTREENODE, rbtn));
}
/*
* Inserts a kernel address range into the tree.
*
@ -193,8 +235,9 @@ static void insert_into_tree(KERNADDR kaFirst, KERNADDR kaLast)
{
PADDRTREENODE pnode = IMalloc_Alloc(g_pMalloc, sizeof(ADDRTREENODE));
ASSERT(pnode);
rbtNewNode(&(pnode->rbtn), init_interval(&(pnode->ai), kaFirst, kaLast));
RbtInsert(&g_rbtFreeAddrs, (PRBTREENODE)pnode);
rbtNewNode(&(pnode->rbtn));
init_interval(&(pnode->ai), kaFirst, kaLast);
RbtInsert(&g_rbtFreeAddrs, pnode);
}
/*
@ -288,8 +331,8 @@ void _MmFreeKernelAddr(KERNADDR kaBase, UINT32 cpgToFree)
init_interval_pages(&aiFree, kaBase, cpgToFree);
ASSERT(!RbtFind(&g_rbtFreeAddrs, (TREEKEY)(&aiFree)));
patnPred = (PADDRTREENODE)RbtFindPredecessor(&g_rbtFreeAddrs, (TREEKEY)(&aiFree));
patnSucc = (PADDRTREENODE)RbtFindSuccessor(&g_rbtFreeAddrs, (TREEKEY)(&aiFree));
patnPred = (PADDRTREENODE)RbtFindPredecessor(&g_rbtFreeAddrs, (&aiFree));
patnSucc = (PADDRTREENODE)RbtFindSuccessor(&g_rbtFreeAddrs, (&aiFree));
if (patnPred && intervals_adjacent(&(patnPred->ai), &aiFree))
{
if (patnSucc && intervals_adjacent(&aiFree, &(patnSucc->ai)))
@ -321,7 +364,8 @@ SEG_INIT_CODE void _MmInitKernelSpace(PSTARTUP_INFO pstartup, PMALLOC pmInitHeap
{
g_pMalloc = pmInitHeap;
IUnknown_AddRef(g_pMalloc);
rbtInitTree(&g_rbtFreeAddrs, (PFNTREECOMPARE)interval_compare);
rbtInitTree(&g_rbtFreeAddrs, (PFNTREECOMPARE)interval_compare, get_interval_from_addrtreenode,
get_rbtreenode_from_addrtreenode, get_addrtreenode_from_rbtreenode);
insert_into_tree(pstartup->vmaFirstFree, VMADDR_IO_BASE);
insert_into_tree(VMADDR_IO_BASE + (PAGE_COUNT_IO * SYS_PAGE_SIZE), VMADDR_KERNEL_NOMANS);
}

View File

@ -62,6 +62,53 @@ static VMCTXT g_vmctxtKernel = { /* kernel VM context */
static RBTREE g_rbtFreePageTables; /* tree containing free page tables */
static PFNSETPTEADDR g_pfnSetPTEAddr = NULL; /* hook function into page database */
/*-----------------------------------
* Red-black tree accessor functions
*-----------------------------------
*/
/*
* Given a pointer to a PAGENODE, returns its key (the physical address of the page table).
*
* Parameters:
* - ppgn = Pointer to a PAGENODE.
*
* Returns:
* The PAGENODE's key value (the physical address of the page table).
*/
static TREEKEY get_key_from_pagenode(PVOID ppgn)
{
return (TREEKEY)(((PPAGENODE)ppgn)->paPageTable);
}
/*
* Given a pointer to a PAGENODE, returns a pointer to the RBTREENODE contained within it.
*
* Parameters:
* - ppgn = Pointer to a PAGENODE.
*
* Returns:
* The PAGENODE's embedded RBTREENODE.
*/
static PRBTREENODE get_rbtreenode_from_pagenode(PVOID ppgn)
{
return &(((PPAGENODE)ppgn)->rbtn);
}
/*
* Given a pointer to a RBTREENODE, returns a pointer to the PAGENODE it's embedded in.
*
* Parameters:
* - ptn = Pointer to an RBTREENODE.
*
* Returns:
* The pointer to the PAGENODE the RBTREENODE is embedded in.
*/
static PVOID get_pagenode_from_rbtreenode(PRBTREENODE ptn)
{
return (PVOID)(((PCHAR)ptn) - OFFSETOF(PAGENODE, rbtn));
}
/*------------------------------
* Inline resolution operations
*------------------------------
@ -194,8 +241,8 @@ static void free_page_table(PVMCTXT pvmctxt, PPAGETAB ppgt)
if (ppgn)
{
RbtDelete(&(pvmctxt->rbtPageTables), (TREEKEY)pa);
rbtNewNode(&(ppgn->rbtn), ppgn->rbtn.treekey);
RbtInsert(&g_rbtFreePageTables, (PRBTREENODE)ppgn);
rbtNewNode(&(ppgn->rbtn));
RbtInsert(&g_rbtFreePageTables, ppgn);
}
}
@ -681,12 +728,14 @@ static HRESULT alloc_page_table(PVMCTXT pvmctxt, PTTB pttbEntry, PTTBAUX pttbAux
ppgn = IMalloc_Alloc(g_pMalloc, sizeof(PAGENODE));
if (ppgnFree && ppgn)
{ /* prepare the new nodes and insert them in their respective trees */
rbtNewNode(&(ppgnFree->rbtn), paNewPage + sizeof(PAGETAB));
rbtNewNode(&(ppgnFree->rbtn));
ppgnFree->paPageTable = paNewPage + sizeof(PAGETAB);
ppgnFree->ppt = ((PPAGETAB)kaNewPage) + 1;
RbtInsert(&g_rbtFreePageTables, (PRBTREENODE)ppgnFree);
rbtNewNode(&(ppgn->rbtn), paNewPage);
RbtInsert(&g_rbtFreePageTables, ppgnFree);
rbtNewNode(&(ppgn->rbtn));
ppgn->paPageTable = paNewPage;
ppgn->ppt = (PPAGETAB)kaNewPage;
RbtInsert(&(pvmctxt->rbtPageTables), (PRBTREENODE)ppgn);
RbtInsert(&(pvmctxt->rbtPageTables), ppgn);
}
else
{ /* could not allocate both, free one if was allocated */
@ -712,15 +761,15 @@ static HRESULT alloc_page_table(PVMCTXT pvmctxt, PTTB pttbEntry, PTTBAUX pttbAux
else
{ /* get the first item out of the free-pages tree and reinsert it into the current VM context */
ppgn = (PPAGENODE)RbtFindMin(&g_rbtFreePageTables);
RbtDelete(&g_rbtFreePageTables, ppgn->rbtn.treekey);
rbtNewNode(&(ppgn->rbtn), ppgn->rbtn.treekey);
RbtInsert(&(pvmctxt->rbtPageTables), (PRBTREENODE)ppgn);
RbtDelete(&g_rbtFreePageTables, (TREEKEY)(ppgn->paPageTable));
rbtNewNode(&(ppgn->rbtn));
RbtInsert(&(pvmctxt->rbtPageTables), ppgn);
}
if (SUCCEEDED(hr))
{ /* prepare new page table and insert it into the TTB */
StrSetMem(ppgn->ppt, 0, sizeof(PAGETAB));
pttbEntry->data = (PHYSADDR)(ppgn->rbtn.treekey) | uiTableFlags; /* poke new entry */
pttbEntry->data = ppgn->paPageTable | uiTableFlags; /* poke new entry */
pttbAuxEntry->data = TTBAUXFLAGS_PAGETABLE;
*pppt = ppgn->ppt;
}
@ -1066,8 +1115,10 @@ SEG_INIT_CODE void _MmInitVMMap(PSTARTUP_INFO pstartup, PMALLOC pmInitHeap)
g_vmctxtKernel.pTTB = (PTTB)(pstartup->kaTTB);
g_vmctxtKernel.pTTBAux = (PTTBAUX)(pstartup->kaTTBAux);
g_vmctxtKernel.paTTB = pstartup->paTTB;
rbtInitTree(&(g_vmctxtKernel.rbtPageTables), RbtStdCompareByValue);
rbtInitTree(&g_rbtFreePageTables, RbtStdCompareByValue);
rbtInitTree(&(g_vmctxtKernel.rbtPageTables), RbtStdCompareByValue, get_key_from_pagenode,
get_rbtreenode_from_pagenode, get_pagenode_from_rbtreenode);
rbtInitTree(&g_rbtFreePageTables, RbtStdCompareByValue, get_key_from_pagenode, get_rbtreenode_from_pagenode,
get_pagenode_from_rbtreenode);
/*
* Load all the page tables we know about. They all get mapped in as part of the kernel context, except if
@ -1084,19 +1135,21 @@ SEG_INIT_CODE void _MmInitVMMap(PSTARTUP_INFO pstartup, PMALLOC pmInitHeap)
/* allocate node for first page table on page */
ppgn = IMalloc_Alloc(g_pMalloc, sizeof(PAGENODE));
ASSERT(ppgn);
rbtNewNode(&(ppgn->rbtn), paPageTable);
rbtNewNode(&(ppgn->rbtn));
ppgn->paPageTable = paPageTable;
ppgn->ppt = (PPAGETAB)kaPageTable;
RbtInsert(&(g_vmctxtKernel.rbtPageTables), (PRBTREENODE)ppgn);
RbtInsert(&(g_vmctxtKernel.rbtPageTables), ppgn);
/* allocate node for second page table on page */
ppgn = IMalloc_Alloc(g_pMalloc, sizeof(PAGENODE));
ASSERT(ppgn);
rbtNewNode(&(ppgn->rbtn), paPageTable + sizeof(PAGETAB));
rbtNewNode(&(ppgn->rbtn));
ppgn->paPageTable = paPageTable + sizeof(PAGETAB);
ppgn->ppt = ((PPAGETAB)kaPageTable) + 1;
if ((i == (pstartup->cpgPageTables - 1)) && pstartup->ctblFreeOnLastPage)
RbtInsert(&g_rbtFreePageTables, (PRBTREENODE)ppgn);
RbtInsert(&g_rbtFreePageTables, ppgn);
else
RbtInsert(&(g_vmctxtKernel.rbtPageTables), (PRBTREENODE)ppgn);
RbtInsert(&(g_vmctxtKernel.rbtPageTables), ppgn);
paPageTable += SYS_PAGE_SIZE; /* advance to next page table page */
}