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)
33 RtlpCopyAvlNodeData(IN PRTL_BALANCED_LINKS Node1
,
34 IN PRTL_BALANCED_LINKS Node2
)
36 Node1
->u1
.Parent
= Node2
->u1
.Parent
;
37 Node1
->LeftChild
= Node2
->LeftChild
;
38 Node1
->RightChild
= Node2
->RightChild
;
41 RTL_GENERIC_COMPARE_RESULTS
43 RtlpAvlCompareRoutine(IN PRTL_AVL_TABLE Table
,
47 PRTL_BALANCED_LINKS CurrentNode
= (PVOID
)((ULONG_PTR
)UserData
- sizeof(LIST_ENTRY
) - sizeof(RTL_BALANCED_LINKS
));
48 ULONG_PTR StartingVpn
= (ULONG_PTR
)Buffer
;
49 if (StartingVpn
< CurrentNode
->StartingVpn
)
51 return GenericLessThan
;
53 else if (StartingVpn
<= CurrentNode
->EndingVpn
)
59 return GenericGreaterThan
;
65 RtlSetParent(IN PRTL_BALANCED_LINKS Node
,
66 IN PRTL_BALANCED_LINKS Parent
)
68 Node
->u1
.Parent
= (PRTL_BALANCED_LINKS
)((ULONG_PTR
)Parent
| (Node
->u1
.Balance
& 0x3));
73 RtlSetBalance(IN PRTL_BALANCED_LINKS Node
,
76 Node
->u1
.Balance
= Balance
;
81 RtlBalance(IN PRTL_BALANCED_LINKS Node
)
83 return Node
->u1
.Balance
;
88 RtlParentAvl(IN PRTL_BALANCED_LINKS Node
)
90 return (PRTL_BALANCED_LINKS
)((ULONG_PTR
)Node
->u1
.Parent
& ~3);
95 RtlIsRootAvl(IN PRTL_BALANCED_LINKS Node
)
97 return (RtlParentAvl(Node
) == Node
);
102 RtlRightChildAvl(IN PRTL_BALANCED_LINKS Node
)
104 return Node
->RightChild
;
109 RtlLeftChildAvl(IN PRTL_BALANCED_LINKS Node
)
111 return Node
->LeftChild
;
116 RtlIsLeftChildAvl(IN PRTL_BALANCED_LINKS Node
)
118 return (RtlLeftChildAvl(RtlParentAvl(Node
)) == Node
);
123 RtlIsRightChildAvl(IN PRTL_BALANCED_LINKS Node
)
125 return (RtlRightChildAvl(RtlParentAvl(Node
)) == Node
);
130 RtlInsertAsLeftChildAvl(IN PRTL_BALANCED_LINKS Parent
,
131 IN PRTL_BALANCED_LINKS Node
)
133 Parent
->LeftChild
= Node
;
134 RtlSetParent(Node
, Parent
);
139 RtlInsertAsRightChildAvl(IN PRTL_BALANCED_LINKS Parent
,
140 IN PRTL_BALANCED_LINKS Node
)
142 Parent
->RightChild
= Node
;
143 RtlSetParent(Node
, Parent
);