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
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 /* We need to rename the functions to prevent conflicts when not inlined! */
32 #define RtlpFindAvlTableNodeOrParent MiFindAvlTableNodeOrParent
33 #define RtlpPromoteAvlTreeNode MiPromoteAvlTreeNode
34 #define RtlpRebalanceAvlTreeNode MiRebalanceAvlTreeNode
35 #define RtlpInsertAvlTreeNode MiInsertAvlTreeNode
36 #define RtlpDeleteAvlTreeNode MiDeleteAvlTreeNode
38 /* These are implementation specific */
39 #define RtlpCopyAvlNodeData MiCopyAvlNodeData
40 #define RtlpAvlCompareRoutine MiAvlCompareRoutine
41 #define RtlSetParent MiSetParent
42 #define RtlSetBalance MiSetBalance
43 #define RtlBalance MiBalance
44 #define RtlParentAvl MiParentAvl
45 #define RtlRightChildAvl MiRightChildAvl
46 #define RtlLeftChildAvl MiLeftChildAvl
47 #define RtlIsLeftChildAvl MiIsLeftChildAvl
48 #define RtlIsRightChildAvl MiIsRightChildAvl
49 #define RtlInsertAsLeftChildAvl MiInsertAsLeftChildAvl
50 #define RtlInsertAsRightChildAvl MiInsertAsRightChildAvl
54 MiCopyAvlNodeData(IN PRTL_BALANCED_LINKS Node1
,
55 IN PRTL_BALANCED_LINKS Node2
)
57 Node1
->u1
.Parent
= Node2
->u1
.Parent
;
58 Node1
->LeftChild
= Node2
->LeftChild
;
59 Node1
->RightChild
= Node2
->RightChild
;
63 RTL_GENERIC_COMPARE_RESULTS
64 MiAvlCompareRoutine(IN PRTL_AVL_TABLE Table
,
68 PRTL_BALANCED_LINKS CurrentNode
= (PVOID
)((ULONG_PTR
)UserData
- sizeof(RTL_BALANCED_LINKS
));
69 ULONG_PTR StartingVpn
= (ULONG_PTR
)Buffer
;
70 if (StartingVpn
< CurrentNode
->StartingVpn
)
72 return GenericLessThan
;
74 else if (StartingVpn
<= CurrentNode
->EndingVpn
)
80 return GenericGreaterThan
;
86 MiSetParent(IN PRTL_BALANCED_LINKS Node
,
87 IN PRTL_BALANCED_LINKS Parent
)
89 Node
->u1
.Parent
= (PRTL_BALANCED_LINKS
)((ULONG_PTR
)Parent
| (Node
->u1
.Balance
& 0x3));
94 MiSetBalance(IN PRTL_BALANCED_LINKS Node
,
97 Node
->u1
.Balance
= Balance
;
102 MiBalance(IN PRTL_BALANCED_LINKS Node
)
104 return (SCHAR
)Node
->u1
.Balance
;
109 MiParentAvl(IN PRTL_BALANCED_LINKS Node
)
111 return (PRTL_BALANCED_LINKS
)((ULONG_PTR
)Node
->u1
.Parent
& ~3);
116 MiRightChildAvl(IN PRTL_BALANCED_LINKS Node
)
118 return Node
->RightChild
;
123 MiLeftChildAvl(IN PRTL_BALANCED_LINKS Node
)
125 return Node
->LeftChild
;
130 MiIsLeftChildAvl(IN PRTL_BALANCED_LINKS Node
)
132 return (RtlLeftChildAvl(RtlParentAvl(Node
)) == Node
);
137 MiIsRightChildAvl(IN PRTL_BALANCED_LINKS Node
)
139 return (RtlRightChildAvl(RtlParentAvl(Node
)) == Node
);
144 MiInsertAsLeftChildAvl(IN PRTL_BALANCED_LINKS Parent
,
145 IN PRTL_BALANCED_LINKS Node
)
147 Parent
->LeftChild
= Node
;
148 RtlSetParent(Node
, Parent
);
153 MiInsertAsRightChildAvl(IN PRTL_BALANCED_LINKS Parent
,
154 IN PRTL_BALANCED_LINKS Node
)
156 Parent
->RightChild
= Node
;
157 RtlSetParent(Node
, Parent
);