2b00e3a8874a7f5636e7e1abc3f885bd1fa2c11d
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Event test
5 * PROGRAMMER: Thomas Faber <thfabba@gmx.de>
10 /* TODO: more thread testing, exports vs macros */
12 #define CheckEvent(Event, ExpectedType, State, ExpectedWaitNext, Irql) do \
14 ok_eq_uint((Event)->Header.Type, ExpectedType); \
15 ok_eq_uint((Event)->Header.Hand, sizeof *(Event) / sizeof(ULONG)); \
16 ok_eq_long((Event)->Header.Lock & 0xFF00FF00L, 0x55005500L); \
17 ok_eq_long((Event)->Header.SignalState, State); \
18 ok_eq_pointer((Event)->Header.WaitListHead.Flink, \
19 &(Event)->Header.WaitListHead); \
20 ok_eq_pointer((Event)->Header.WaitListHead.Blink, \
21 &(Event)->Header.WaitListHead); \
22 ok_eq_long(KeReadStateEvent(Event), State); \
23 ok_eq_bool(Thread->WaitNext, ExpectedWaitNext); \
32 IN KIRQL OriginalIrql
)
35 PKTHREAD Thread
= KeGetCurrentThread();
37 memset(Event
, 0x55, sizeof *Event
);
38 KeInitializeEvent(Event
, Type
, FALSE
);
39 CheckEvent(Event
, Type
, 0L, FALSE
, OriginalIrql
);
41 memset(Event
, 0x55, sizeof *Event
);
42 KeInitializeEvent(Event
, Type
, TRUE
);
43 CheckEvent(Event
, Type
, 1L, FALSE
, OriginalIrql
);
45 Event
->Header
.SignalState
= 0x12345678L
;
46 CheckEvent(Event
, Type
, 0x12345678L
, FALSE
, OriginalIrql
);
48 State
= KePulseEvent(Event
, 0, FALSE
);
49 CheckEvent(Event
, Type
, 0L, FALSE
, OriginalIrql
);
50 ok_eq_long(State
, 0x12345678L
);
52 Event
->Header
.SignalState
= 0x12345678L
;
54 CheckEvent(Event
, Type
, 0L, FALSE
, OriginalIrql
);
56 State
= KeSetEvent(Event
, 0, FALSE
);
57 CheckEvent(Event
, Type
, 1L, FALSE
, OriginalIrql
);
58 ok_eq_long(State
, 0L);
60 State
= KeResetEvent(Event
);
61 CheckEvent(Event
, Type
, 0L, FALSE
, OriginalIrql
);
62 ok_eq_long(State
, 1L);
64 Event
->Header
.SignalState
= 0x23456789L
;
65 State
= KeSetEvent(Event
, 0, FALSE
);
66 CheckEvent(Event
, Type
, 1L, FALSE
, OriginalIrql
);
67 ok_eq_long(State
, 0x23456789L
);
69 Event
->Header
.SignalState
= 0x3456789AL
;
70 State
= KeResetEvent(Event
);
71 CheckEvent(Event
, Type
, 0L, FALSE
, OriginalIrql
);
72 ok_eq_long(State
, 0x3456789AL
);
74 if (OriginalIrql
<= DISPATCH_LEVEL
|| !KmtIsCheckedBuild
)
76 Event
->Header
.SignalState
= 0x456789ABL
;
77 State
= KeSetEvent(Event
, 0, TRUE
);
78 CheckEvent(Event
, Type
, 1L, TRUE
, DISPATCH_LEVEL
);
79 ok_eq_long(State
, 0x456789ABL
);
80 ok_eq_uint(Thread
->WaitIrql
, OriginalIrql
);
81 /* repair the "damage" */
82 Thread
->WaitNext
= FALSE
;
83 KmtSetIrql(OriginalIrql
);
85 Event
->Header
.SignalState
= 0x56789ABCL
;
86 State
= KePulseEvent(Event
, 0, TRUE
);
87 CheckEvent(Event
, Type
, 0L, TRUE
, DISPATCH_LEVEL
);
88 ok_eq_long(State
, 0x56789ABCL
);
89 ok_eq_uint(Thread
->WaitIrql
, OriginalIrql
);
90 /* repair the "damage" */
91 Thread
->WaitNext
= FALSE
;
92 KmtSetIrql(OriginalIrql
);
95 ok_irql(OriginalIrql
);
96 KmtSetIrql(OriginalIrql
);
105 volatile BOOLEAN Signal
;
106 } THREAD_DATA
, *PTHREAD_DATA
;
112 IN OUT PVOID Context
)
115 PTHREAD_DATA ThreadData
= Context
;
117 ok_irql(PASSIVE_LEVEL
);
118 ThreadData
->Signal
= TRUE
;
119 Status
= KeWaitForSingleObject(ThreadData
->Event1
, Executive
, KernelMode
, FALSE
, NULL
);
120 ok_irql(PASSIVE_LEVEL
);
121 ok_eq_hex(Status
, STATUS_SUCCESS
);
122 ThreadData
->Signal
= TRUE
;
123 Status
= KeWaitForSingleObject(ThreadData
->Event2
, Executive
, KernelMode
, FALSE
, NULL
);
124 ok_irql(PASSIVE_LEVEL
);
125 ok_eq_hex(Status
, STATUS_SUCCESS
);
126 ok_irql(PASSIVE_LEVEL
);
134 IN KIRQL OriginalIrql
)
137 THREAD_DATA Threads
[5];
138 LARGE_INTEGER Timeout
;
141 KEVENT TerminateEvent
;
143 Timeout
.QuadPart
= -1000 * 10;
145 KeInitializeEvent(Event
, Type
, FALSE
);
146 KeInitializeEvent(&WaitEvent
, NotificationEvent
, FALSE
);
147 KeInitializeEvent(&TerminateEvent
, SynchronizationEvent
, FALSE
);
149 for (i
= 0; i
< sizeof Threads
/ sizeof Threads
[0]; ++i
)
151 Threads
[i
].Event1
= Event
;
152 Threads
[i
].Event2
= &TerminateEvent
;
153 Threads
[i
].Signal
= FALSE
;
154 Status
= PsCreateSystemThread(&Threads
[i
].Handle
, GENERIC_ALL
, NULL
, NULL
, NULL
, WaitForEventThread
, &Threads
[i
]);
155 ok_eq_hex(Status
, STATUS_SUCCESS
);
156 Status
= ObReferenceObjectByHandle(Threads
[i
].Handle
, SYNCHRONIZE
, PsThreadType
, KernelMode
, (PVOID
*)&Threads
[i
].Thread
, NULL
);
157 ok_eq_hex(Status
, STATUS_SUCCESS
);
158 Priority
= KeQueryPriorityThread(Threads
[i
].Thread
);
159 ok_eq_long(Priority
, 8L);
160 while (!Threads
[i
].Signal
)
162 Status
= KeWaitForSingleObject(&WaitEvent
, Executive
, KernelMode
, FALSE
, &Timeout
);
163 ok_eq_hex(Status
, STATUS_TIMEOUT
);
165 Threads
[i
].Signal
= FALSE
;
168 for (i
= 0; i
< sizeof Threads
/ sizeof Threads
[0]; ++i
)
170 KeSetEvent(Event
, 1, FALSE
);
171 while (!Threads
[i
].Signal
)
173 Status
= KeWaitForSingleObject(&WaitEvent
, Executive
, KernelMode
, FALSE
, &Timeout
);
174 ok_eq_hex(Status
, STATUS_TIMEOUT
);
176 Priority
= KeQueryPriorityThread(Threads
[i
].Thread
);
177 ok_eq_long(Priority
, 9L);
178 KeSetEvent(&TerminateEvent
, 0, FALSE
);
179 Status
= KeWaitForSingleObject(Threads
[i
].Thread
, Executive
, KernelMode
, FALSE
, NULL
);
180 ok_eq_hex(Status
, STATUS_SUCCESS
);
182 ObDereferenceObject(Threads
[i
].Thread
);
183 Status
= ZwClose(Threads
[i
].Handle
);
184 ok_eq_hex(Status
, STATUS_SUCCESS
);
192 KIRQL Irqls
[] = { PASSIVE_LEVEL
, APC_LEVEL
, DISPATCH_LEVEL
, HIGH_LEVEL
};
195 for (i
= 0; i
< sizeof Irqls
/ sizeof Irqls
[0]; ++i
)
197 KeRaiseIrql(Irqls
[i
], &Irql
);
198 TestEventFunctional(&Event
, NotificationEvent
, Irqls
[i
]);
199 TestEventFunctional(&Event
, SynchronizationEvent
, Irqls
[i
]);
203 TestEventThreads(&Event
, NotificationEvent
, PASSIVE_LEVEL
);
205 ok_irql(PASSIVE_LEVEL
);
206 KmtSetIrql(PASSIVE_LEVEL
);