2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/mm/ARM3/miavl.h
5 * PURPOSE: ARM Memory Manager VAD Node Algorithms
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES ******************************************************************/
12 * This is the glue code for the Memory Manager version of AVL Trees that is used
13 * to store the MM_AVL_TABLE for Virtual Address Descriptors (VAD) in the VadRoot
16 * In this version of the package, the balance and parent pointers are stored in
17 * the same field as a union (since we know the parent will be at least 8-byte
18 * aligned), saving some space, but requiring special logic to handle setting and
19 * querying the parent and balance.
21 * The other difference is that the AVL package for Rtl has custom callbacks for
22 * comparison purposes (which would access some internal, opaque, user data) while
23 * the Mm package stores the user-data inline as StartingVpn and EndingVpn. So
24 * when a compare is being made, RtlpAvlCompareRoutine is called, which will either
25 * perform the Mm work, or call the user-specified callback in the Rtl case.
27 #define PRTL_AVL_TABLE PMM_AVL_TABLE
28 #define PRTL_BALANCED_LINKS PMMADDRESS_NODE
29 #define MI_ASSERT(x) ASSERT(x)
31 RTL_GENERIC_COMPARE_RESULTS
33 RtlpAvlCompareRoutine(IN PRTL_AVL_TABLE Table
,
37 PRTL_BALANCED_LINKS CurrentNode
= (PVOID
)((ULONG_PTR
)UserData
- sizeof(LIST_ENTRY
) - sizeof(RTL_BALANCED_LINKS
));
38 ULONG_PTR StartingVpn
= (ULONG_PTR
)Buffer
;
39 if (StartingVpn
< CurrentNode
->StartingVpn
)
41 return GenericLessThan
;
43 else if (StartingVpn
<= CurrentNode
->EndingVpn
)
49 return GenericGreaterThan
;
55 RtlSetParent(IN PRTL_BALANCED_LINKS Node
,
56 IN PRTL_BALANCED_LINKS Parent
)
58 Node
->u1
.Parent
= (PRTL_BALANCED_LINKS
)((ULONG_PTR
)Parent
| (Node
->u1
.Balance
& 0x3));
63 RtlSetBalance(IN PRTL_BALANCED_LINKS Node
,
66 Node
->u1
.Balance
= Balance
;
71 RtlBalance(IN PRTL_BALANCED_LINKS Node
)
73 return Node
->u1
.Balance
;
78 RtlParentAvl(IN PRTL_BALANCED_LINKS Node
)
80 return (PRTL_BALANCED_LINKS
)((ULONG_PTR
)Node
->u1
.Parent
& ~3);
85 RtlIsRootAvl(IN PRTL_BALANCED_LINKS Node
)
87 return (RtlParentAvl(Node
) == Node
);
92 RtlRightChildAvl(IN PRTL_BALANCED_LINKS Node
)
94 return Node
->RightChild
;
99 RtlLeftChildAvl(IN PRTL_BALANCED_LINKS Node
)
101 return Node
->LeftChild
;
106 RtlIsLeftChildAvl(IN PRTL_BALANCED_LINKS Node
)
108 return (RtlLeftChildAvl(RtlParentAvl(Node
)) == Node
);
113 RtlIsRightChildAvl(IN PRTL_BALANCED_LINKS Node
)
115 return (RtlRightChildAvl(RtlParentAvl(Node
)) == Node
);
120 RtlInsertAsLeftChildAvl(IN PRTL_BALANCED_LINKS Parent
,
121 IN PRTL_BALANCED_LINKS Node
)
123 Parent
->LeftChild
= Node
;
124 RtlSetParent(Node
, Parent
);
129 RtlInsertAsRightChildAvl(IN PRTL_BALANCED_LINKS Parent
,
130 IN PRTL_BALANCED_LINKS Node
)
132 Parent
->RightChild
= Node
;
133 RtlSetParent(Node
, Parent
);