[KMTESTS]
[reactos.git] / kmtests / ntos_ex / ExDoubleList.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Doubly-linked list test
5 * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
6 */
7
8 struct _LIST_ENTRY;
9 struct _LIST_ENTRY *__stdcall ExInterlockedInsertHeadList(struct _LIST_ENTRY *, struct _LIST_ENTRY *, unsigned long *);
10 struct _LIST_ENTRY *__stdcall ExInterlockedInsertTailList(struct _LIST_ENTRY *, struct _LIST_ENTRY *, unsigned long *);
11 struct _LIST_ENTRY *__stdcall ExInterlockedRemoveHeadList(struct _LIST_ENTRY *, unsigned long *);
12
13 #include <kmt_test.h>
14
15 LIST_ENTRY Entries[5];
16
17 #define ok_eq_free(Value, Expected) do \
18 { \
19 if (KmtIsCheckedBuild) \
20 ok_eq_pointer(Value, (PVOID)0x0BADD0FF); \
21 else \
22 ok_eq_pointer(Value, Expected); \
23 } while (0)
24
25 #define ok_eq_free2(Value, Expected) do \
26 { \
27 if (KmtIsCheckedBuild) \
28 ok_eq_pointer(Value, (PVOID)0xBADDD0FF); \
29 else \
30 ok_eq_pointer(Value, Expected); \
31 } while (0)
32
33 START_TEST(ExDoubleList)
34 {
35 KSPIN_LOCK SpinLock;
36 LIST_ENTRY ListHead;
37 PLIST_ENTRY Ret;
38
39 KeInitializeSpinLock(&SpinLock);
40
41 memset(&ListHead, 0x55, sizeof ListHead);
42 InitializeListHead(&ListHead);
43 ok_eq_pointer(ListHead.Flink, &ListHead);
44 ok_eq_pointer(ListHead.Blink, &ListHead);
45 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
46 ok_irql(PASSIVE_LEVEL);
47
48 Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[0], &SpinLock);
49 ok_eq_pointer(Ret, NULL);
50 ok_eq_pointer(ListHead.Flink, &Entries[0]);
51 ok_eq_pointer(ListHead.Blink, &Entries[0]);
52 ok_eq_pointer(Entries[0].Flink, &ListHead);
53 ok_eq_pointer(Entries[0].Blink, &ListHead);
54 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
55 ok_irql(PASSIVE_LEVEL);
56
57 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
58 ok_eq_pointer(Ret, &Entries[0]);
59 ok_eq_pointer(ListHead.Flink, &ListHead);
60 ok_eq_pointer(ListHead.Blink, &ListHead);
61 ok_eq_free(Entries[0].Flink, &ListHead);
62 ok_eq_free(Entries[0].Blink, &ListHead);
63 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
64 ok_irql(PASSIVE_LEVEL);
65
66 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
67 ok_eq_pointer(Ret, NULL);
68 ok_eq_pointer(ListHead.Flink, &ListHead);
69 ok_eq_pointer(ListHead.Blink, &ListHead);
70 ok_eq_free(Entries[0].Flink, &ListHead);
71 ok_eq_free(Entries[0].Blink, &ListHead);
72 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
73 ok_irql(PASSIVE_LEVEL);
74
75 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock);
76 ok_eq_pointer(Ret, NULL);
77 ok_eq_pointer(ListHead.Flink, &Entries[0]);
78 ok_eq_pointer(ListHead.Blink, &Entries[0]);
79 ok_eq_pointer(Entries[0].Flink, &ListHead);
80 ok_eq_pointer(Entries[0].Blink, &ListHead);
81 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
82 ok_irql(PASSIVE_LEVEL);
83
84 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
85 ok_eq_pointer(Ret, &Entries[0]);
86 ok_eq_pointer(ListHead.Flink, &ListHead);
87 ok_eq_pointer(ListHead.Blink, &ListHead);
88 ok_eq_free(Entries[0].Flink, &ListHead);
89 ok_eq_free(Entries[0].Blink, &ListHead);
90 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
91 ok_irql(PASSIVE_LEVEL);
92
93 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
94 ok_eq_pointer(Ret, NULL);
95 ok_eq_pointer(ListHead.Flink, &ListHead);
96 ok_eq_pointer(ListHead.Blink, &ListHead);
97 ok_eq_free(Entries[0].Flink, &ListHead);
98 ok_eq_free(Entries[0].Blink, &ListHead);
99 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
100 ok_irql(PASSIVE_LEVEL);
101
102 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock);
103 ok_eq_pointer(Ret, NULL);
104 ok_eq_pointer(ListHead.Flink, &Entries[0]);
105 ok_eq_pointer(ListHead.Blink, &Entries[0]);
106 ok_eq_pointer(Entries[0].Flink, &ListHead);
107 ok_eq_pointer(Entries[0].Blink, &ListHead);
108 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
109 ok_irql(PASSIVE_LEVEL);
110
111 Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[1], &SpinLock);
112 ok_eq_pointer(Ret, &Entries[0]);
113 ok_eq_pointer(ListHead.Flink, &Entries[1]);
114 ok_eq_pointer(ListHead.Blink, &Entries[0]);
115 ok_eq_pointer(Entries[0].Flink, &ListHead);
116 ok_eq_pointer(Entries[0].Blink, &Entries[1]);
117 ok_eq_pointer(Entries[1].Flink, &Entries[0]);
118 ok_eq_pointer(Entries[1].Blink, &ListHead);
119 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
120 ok_irql(PASSIVE_LEVEL);
121
122 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[2], &SpinLock);
123 ok_eq_pointer(Ret, &Entries[0]);
124 ok_eq_pointer(ListHead.Flink, &Entries[1]);
125 ok_eq_pointer(ListHead.Blink, &Entries[2]);
126 ok_eq_pointer(Entries[0].Flink, &Entries[2]);
127 ok_eq_pointer(Entries[0].Blink, &Entries[1]);
128 ok_eq_pointer(Entries[1].Flink, &Entries[0]);
129 ok_eq_pointer(Entries[1].Blink, &ListHead);
130 ok_eq_pointer(Entries[2].Flink, &ListHead);
131 ok_eq_pointer(Entries[2].Blink, &Entries[0]);
132 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
133 ok_irql(PASSIVE_LEVEL);
134
135 memset(Entries, 0x55, sizeof Entries);
136 #undef ExInterlockedInsertHeadList
137 #undef ExInterlockedInsertTailList
138 #undef ExInterlockedRemoveHeadList
139
140 memset(&ListHead, 0x55, sizeof ListHead);
141 InitializeListHead(&ListHead);
142 ok_eq_pointer(ListHead.Flink, &ListHead);
143 ok_eq_pointer(ListHead.Blink, &ListHead);
144 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
145 ok_irql(PASSIVE_LEVEL);
146
147 Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[0], &SpinLock);
148 ok_eq_pointer(Ret, NULL);
149 ok_eq_pointer(ListHead.Flink, &Entries[0]);
150 ok_eq_pointer(ListHead.Blink, &Entries[0]);
151 ok_eq_pointer(Entries[0].Flink, &ListHead);
152 ok_eq_pointer(Entries[0].Blink, &ListHead);
153 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
154 ok_irql(PASSIVE_LEVEL);
155
156 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
157 ok_eq_pointer(Ret, &Entries[0]);
158 ok_eq_pointer(ListHead.Flink, &ListHead);
159 ok_eq_pointer(ListHead.Blink, &ListHead);
160 ok_eq_free2(Entries[0].Flink, &ListHead);
161 ok_eq_free2(Entries[0].Blink, &ListHead);
162 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
163 ok_irql(PASSIVE_LEVEL);
164
165 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
166 ok_eq_pointer(Ret, NULL);
167 ok_eq_pointer(ListHead.Flink, &ListHead);
168 ok_eq_pointer(ListHead.Blink, &ListHead);
169 ok_eq_free2(Entries[0].Flink, &ListHead);
170 ok_eq_free2(Entries[0].Blink, &ListHead);
171 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
172 ok_irql(PASSIVE_LEVEL);
173
174 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock);
175 ok_eq_pointer(Ret, NULL);
176 ok_eq_pointer(ListHead.Flink, &Entries[0]);
177 ok_eq_pointer(ListHead.Blink, &Entries[0]);
178 ok_eq_pointer(Entries[0].Flink, &ListHead);
179 ok_eq_pointer(Entries[0].Blink, &ListHead);
180 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
181 ok_irql(PASSIVE_LEVEL);
182
183 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
184 ok_eq_pointer(Ret, &Entries[0]);
185 ok_eq_pointer(ListHead.Flink, &ListHead);
186 ok_eq_pointer(ListHead.Blink, &ListHead);
187 ok_eq_free2(Entries[0].Flink, &ListHead);
188 ok_eq_free2(Entries[0].Blink, &ListHead);
189 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
190 ok_irql(PASSIVE_LEVEL);
191
192 Ret = ExInterlockedRemoveHeadList(&ListHead, &SpinLock);
193 ok_eq_pointer(Ret, NULL);
194 ok_eq_pointer(ListHead.Flink, &ListHead);
195 ok_eq_pointer(ListHead.Blink, &ListHead);
196 ok_eq_free2(Entries[0].Flink, &ListHead);
197 ok_eq_free2(Entries[0].Blink, &ListHead);
198 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
199 ok_irql(PASSIVE_LEVEL);
200
201 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[0], &SpinLock);
202 ok_eq_pointer(Ret, NULL);
203 ok_eq_pointer(ListHead.Flink, &Entries[0]);
204 ok_eq_pointer(ListHead.Blink, &Entries[0]);
205 ok_eq_pointer(Entries[0].Flink, &ListHead);
206 ok_eq_pointer(Entries[0].Blink, &ListHead);
207 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
208 ok_irql(PASSIVE_LEVEL);
209
210 Ret = ExInterlockedInsertHeadList(&ListHead, &Entries[1], &SpinLock);
211 ok_eq_pointer(Ret, &Entries[0]);
212 ok_eq_pointer(ListHead.Flink, &Entries[1]);
213 ok_eq_pointer(ListHead.Blink, &Entries[0]);
214 ok_eq_pointer(Entries[0].Flink, &ListHead);
215 ok_eq_pointer(Entries[0].Blink, &Entries[1]);
216 ok_eq_pointer(Entries[1].Flink, &Entries[0]);
217 ok_eq_pointer(Entries[1].Blink, &ListHead);
218 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
219 ok_irql(PASSIVE_LEVEL);
220
221 Ret = ExInterlockedInsertTailList(&ListHead, &Entries[2], &SpinLock);
222 ok_eq_pointer(Ret, &Entries[0]);
223 ok_eq_pointer(ListHead.Flink, &Entries[1]);
224 ok_eq_pointer(ListHead.Blink, &Entries[2]);
225 ok_eq_pointer(Entries[0].Flink, &Entries[2]);
226 ok_eq_pointer(Entries[0].Blink, &Entries[1]);
227 ok_eq_pointer(Entries[1].Flink, &Entries[0]);
228 ok_eq_pointer(Entries[1].Blink, &ListHead);
229 ok_eq_pointer(Entries[2].Flink, &ListHead);
230 ok_eq_pointer(Entries[2].Blink, &Entries[0]);
231 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:");
232 ok_irql(PASSIVE_LEVEL);
233
234 KmtSetIrql(PASSIVE_LEVEL);
235 }