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