modified rbtree code to not need the local key value; also set compiler to treat all warnings as errors
This commit is contained in:
parent
0a31211d96
commit
3f4e807025
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user