mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 04:53:31 +08:00
161 lines
4.3 KiB
C
161 lines
4.3 KiB
C
/*
|
|
* PROJECT: ReactOS Kernel
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
* FILE: ntoskrnl/mm/ARM3/miavl.h
|
|
* PURPOSE: ARM Memory Manager VAD Node Algorithms
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
/*
|
|
* This is the glue code for the Memory Manager version of AVL Trees that is used
|
|
* to store the MM_AVL_TABLE for Virtual Address Descriptors (VAD) in the VadRoot
|
|
* field in EPROCESS.
|
|
*
|
|
* In this version of the package, the balance and parent pointers are stored in
|
|
* the same field as a union (since we know the parent will be at least 8-byte
|
|
* aligned), saving some space, but requiring special logic to handle setting and
|
|
* querying the parent and balance.
|
|
*
|
|
* The other difference is that the AVL package for Rtl has custom callbacks for
|
|
* comparison purposes (which would access some internal, opaque, user data) while
|
|
* the Mm package stores the user-data inline as StartingVpn and EndingVpn. So
|
|
* when a compare is being made, RtlpAvlCompareRoutine is called, which will either
|
|
* perform the Mm work, or call the user-specified callback in the Rtl case.
|
|
*/
|
|
#define PRTL_AVL_TABLE PMM_AVL_TABLE
|
|
#define PRTL_BALANCED_LINKS PMMADDRESS_NODE
|
|
#define MI_ASSERT(x) ASSERT(x)
|
|
|
|
/* We need to rename the functions to prevent conflicts when not inlined! */
|
|
#define RtlpFindAvlTableNodeOrParent MiFindAvlTableNodeOrParent
|
|
#define RtlpPromoteAvlTreeNode MiPromoteAvlTreeNode
|
|
#define RtlpRebalanceAvlTreeNode MiRebalanceAvlTreeNode
|
|
#define RtlpInsertAvlTreeNode MiInsertAvlTreeNode
|
|
#define RtlpDeleteAvlTreeNode MiDeleteAvlTreeNode
|
|
|
|
/* These are implementation specific */
|
|
#define RtlpCopyAvlNodeData MiCopyAvlNodeData
|
|
#define RtlpAvlCompareRoutine MiAvlCompareRoutine
|
|
#define RtlSetParent MiSetParent
|
|
#define RtlSetBalance MiSetBalance
|
|
#define RtlBalance MiBalance
|
|
#define RtlParentAvl MiParentAvl
|
|
#define RtlRightChildAvl MiRightChildAvl
|
|
#define RtlLeftChildAvl MiLeftChildAvl
|
|
#define RtlIsLeftChildAvl MiIsLeftChildAvl
|
|
#define RtlIsRightChildAvl MiIsRightChildAvl
|
|
#define RtlInsertAsLeftChildAvl MiInsertAsLeftChildAvl
|
|
#define RtlInsertAsRightChildAvl MiInsertAsRightChildAvl
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
MiCopyAvlNodeData(IN PRTL_BALANCED_LINKS Node1,
|
|
IN PRTL_BALANCED_LINKS Node2)
|
|
{
|
|
Node1->u1.Parent = Node2->u1.Parent;
|
|
Node1->LeftChild = Node2->LeftChild;
|
|
Node1->RightChild = Node2->RightChild;
|
|
}
|
|
|
|
FORCEINLINE
|
|
RTL_GENERIC_COMPARE_RESULTS
|
|
MiAvlCompareRoutine(IN PRTL_AVL_TABLE Table,
|
|
IN PVOID Buffer,
|
|
IN PVOID UserData)
|
|
{
|
|
PRTL_BALANCED_LINKS CurrentNode = (PVOID)((ULONG_PTR)UserData - sizeof(RTL_BALANCED_LINKS));
|
|
ULONG_PTR StartingVpn = (ULONG_PTR)Buffer;
|
|
if (StartingVpn < CurrentNode->StartingVpn)
|
|
{
|
|
return GenericLessThan;
|
|
}
|
|
else if (StartingVpn <= CurrentNode->EndingVpn)
|
|
{
|
|
return GenericEqual;
|
|
}
|
|
else
|
|
{
|
|
return GenericGreaterThan;
|
|
}
|
|
}
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
MiSetParent(IN PRTL_BALANCED_LINKS Node,
|
|
IN PRTL_BALANCED_LINKS Parent)
|
|
{
|
|
Node->u1.Parent = (PRTL_BALANCED_LINKS)((ULONG_PTR)Parent | (Node->u1.Balance & 0x3));
|
|
}
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
MiSetBalance(IN PRTL_BALANCED_LINKS Node,
|
|
IN SCHAR Balance)
|
|
{
|
|
Node->u1.Balance = Balance;
|
|
}
|
|
|
|
FORCEINLINE
|
|
SCHAR
|
|
MiBalance(IN PRTL_BALANCED_LINKS Node)
|
|
{
|
|
return (SCHAR)Node->u1.Balance;
|
|
}
|
|
|
|
FORCEINLINE
|
|
PRTL_BALANCED_LINKS
|
|
MiParentAvl(IN PRTL_BALANCED_LINKS Node)
|
|
{
|
|
return (PRTL_BALANCED_LINKS)((ULONG_PTR)Node->u1.Parent & ~3);
|
|
}
|
|
|
|
FORCEINLINE
|
|
PRTL_BALANCED_LINKS
|
|
MiRightChildAvl(IN PRTL_BALANCED_LINKS Node)
|
|
{
|
|
return Node->RightChild;
|
|
}
|
|
|
|
FORCEINLINE
|
|
PRTL_BALANCED_LINKS
|
|
MiLeftChildAvl(IN PRTL_BALANCED_LINKS Node)
|
|
{
|
|
return Node->LeftChild;
|
|
}
|
|
|
|
FORCEINLINE
|
|
BOOLEAN
|
|
MiIsLeftChildAvl(IN PRTL_BALANCED_LINKS Node)
|
|
{
|
|
return (RtlLeftChildAvl(RtlParentAvl(Node)) == Node);
|
|
}
|
|
|
|
FORCEINLINE
|
|
BOOLEAN
|
|
MiIsRightChildAvl(IN PRTL_BALANCED_LINKS Node)
|
|
{
|
|
return (RtlRightChildAvl(RtlParentAvl(Node)) == Node);
|
|
}
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
MiInsertAsLeftChildAvl(IN PRTL_BALANCED_LINKS Parent,
|
|
IN PRTL_BALANCED_LINKS Node)
|
|
{
|
|
Parent->LeftChild = Node;
|
|
RtlSetParent(Node, Parent);
|
|
}
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
MiInsertAsRightChildAvl(IN PRTL_BALANCED_LINKS Parent,
|
|
IN PRTL_BALANCED_LINKS Node)
|
|
{
|
|
Parent->RightChild = Node;
|
|
RtlSetParent(Node, Parent);
|
|
}
|
|
|
|
/* EOF */
|