2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Guarded Mutex test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
14 _IRQL_requires_min_(PASSIVE_LEVEL
)
15 _IRQL_requires_max_(DISPATCH_LEVEL
)
18 *pKeAreAllApcsDisabled
)(VOID
);
21 _Acquires_lock_(_Global_critical_region_
)
22 _Requires_lock_not_held_(*Mutex
)
23 _Acquires_lock_(*Mutex
)
24 _IRQL_requires_max_(APC_LEVEL
)
25 _IRQL_requires_min_(PASSIVE_LEVEL
)
28 *pKeAcquireGuardedMutex
)(
29 _Inout_ PKGUARDED_MUTEX GuardedMutex
);
32 _Requires_lock_not_held_(*FastMutex
)
33 _Acquires_lock_(*FastMutex
)
34 _IRQL_requires_max_(APC_LEVEL
)
35 _IRQL_requires_min_(PASSIVE_LEVEL
)
38 *pKeAcquireGuardedMutexUnsafe
)(
39 _Inout_ PKGUARDED_MUTEX GuardedMutex
);
42 _Acquires_lock_(_Global_critical_region_
)
43 _IRQL_requires_max_(APC_LEVEL
)
46 *pKeEnterGuardedRegion
)(VOID
);
49 _Releases_lock_(_Global_critical_region_
)
50 _IRQL_requires_max_(APC_LEVEL
)
53 *pKeLeaveGuardedRegion
)(VOID
);
56 _IRQL_requires_max_(APC_LEVEL
)
57 _IRQL_requires_min_(PASSIVE_LEVEL
)
60 *pKeInitializeGuardedMutex
)(
61 _Out_ PKGUARDED_MUTEX GuardedMutex
);
64 _Requires_lock_held_(*FastMutex
)
65 _Releases_lock_(*FastMutex
)
66 _IRQL_requires_max_(APC_LEVEL
)
69 *pKeReleaseGuardedMutexUnsafe
)(
70 _Inout_ PKGUARDED_MUTEX GuardedMutex
);
73 _Releases_lock_(_Global_critical_region_
)
74 _Requires_lock_held_(*Mutex
)
75 _Releases_lock_(*Mutex
)
76 _IRQL_requires_max_(APC_LEVEL
)
79 *pKeReleaseGuardedMutex
)(
80 _Inout_ PKGUARDED_MUTEX GuardedMutex
);
84 _Success_(return != FALSE
)
85 _IRQL_requires_max_(APC_LEVEL
)
86 _Post_satisfies_(return == 1 || return == 0)
89 *pKeTryToAcquireGuardedMutex
)(
90 _When_ (return, _Requires_lock_not_held_(*_Curr_
) _Acquires_exclusive_lock_(*_Curr_
)) _Acquires_lock_(_Global_critical_region_
)
91 _Inout_ PKGUARDED_MUTEX GuardedMutex
);
93 #define CheckMutex(Mutex, ExpectedCount, ExpectedOwner, ExpectedContention, \
94 ExpectedKernelApcDisable, ExpectedSpecialApcDisable, \
95 KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, \
98 ok_eq_long((Mutex)->Count, ExpectedCount); \
99 ok_eq_pointer((Mutex)->Owner, ExpectedOwner); \
100 ok_eq_ulong((Mutex)->Contention, ExpectedContention); \
101 ok_eq_int((Mutex)->KernelApcDisable, ExpectedKernelApcDisable); \
102 if (KmtIsCheckedBuild) \
103 ok_eq_int((Mutex)->SpecialApcDisable, ExpectedSpecialApcDisable); \
105 ok_eq_int((Mutex)->SpecialApcDisable, 0x5555); \
106 ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
107 ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
108 ok_eq_bool(pKeAreAllApcsDisabled(), AllApcsDisabled); \
109 ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
110 ok_irql(ExpectedIrql); \
116 PKGUARDED_MUTEX Mutex
,
117 SHORT KernelApcsDisabled
,
118 SHORT SpecialApcsDisabled
,
119 SHORT AllApcsDisabled
,
122 PKTHREAD Thread
= KeGetCurrentThread();
124 ok_irql(OriginalIrql
);
125 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, 0x5555, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
128 if (!KmtIsCheckedBuild
|| OriginalIrql
<= APC_LEVEL
)
130 /* acquire/release normally */
131 pKeAcquireGuardedMutex(Mutex
);
132 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
- 1, TRUE
, OriginalIrql
);
133 ok_bool_false(pKeTryToAcquireGuardedMutex(Mutex
), "KeTryToAcquireGuardedMutex returned");
134 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
- 1, TRUE
, OriginalIrql
);
135 pKeReleaseGuardedMutex(Mutex
);
136 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
139 ok_bool_true(pKeTryToAcquireGuardedMutex(Mutex
), "KeTryToAcquireGuardedMutex returned");
140 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
- 1, TRUE
, OriginalIrql
);
141 pKeReleaseGuardedMutex(Mutex
);
142 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
145 /* Make the following test happy */
146 Mutex
->SpecialApcDisable
= SpecialApcsDisabled
- 1;
149 if (!KmtIsCheckedBuild
|| OriginalIrql
== APC_LEVEL
|| SpecialApcsDisabled
< 0)
151 /* acquire/release unsafe */
152 pKeAcquireGuardedMutexUnsafe(Mutex
);
153 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
154 pKeReleaseGuardedMutexUnsafe(Mutex
);
155 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
158 /* Bugchecks >= DISPATCH_LEVEL */
159 if (!KmtIsCheckedBuild
)
161 /* mismatched acquire/release */
162 pKeAcquireGuardedMutex(Mutex
);
163 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
- 1, TRUE
, OriginalIrql
);
164 pKeReleaseGuardedMutexUnsafe(Mutex
);
165 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
- 1, TRUE
, OriginalIrql
);
166 pKeLeaveGuardedRegion();
167 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
169 pKeAcquireGuardedMutexUnsafe(Mutex
);
170 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
171 pKeReleaseGuardedMutex(Mutex
);
172 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
+ 1, OriginalIrql
>= APC_LEVEL
|| SpecialApcsDisabled
!= -1, OriginalIrql
);
173 pKeEnterGuardedRegion();
174 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
176 /* release without acquire */
177 pKeReleaseGuardedMutexUnsafe(Mutex
);
178 CheckMutex(Mutex
, 0L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
179 pKeReleaseGuardedMutex(Mutex
);
180 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
, KernelApcsDisabled
, SpecialApcsDisabled
+ 1, OriginalIrql
>= APC_LEVEL
|| SpecialApcsDisabled
!= -1, OriginalIrql
);
181 pKeReleaseGuardedMutex(Mutex
);
182 /* TODO: here we see that Mutex->Count isn't actually just a count. Test the bits correctly! */
183 CheckMutex(Mutex
, 0L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
, KernelApcsDisabled
, SpecialApcsDisabled
+ 2, OriginalIrql
>= APC_LEVEL
|| SpecialApcsDisabled
!= -2, OriginalIrql
);
184 pKeReleaseGuardedMutex(Mutex
);
185 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
, KernelApcsDisabled
, SpecialApcsDisabled
+ 3, OriginalIrql
>= APC_LEVEL
|| SpecialApcsDisabled
!= -3, OriginalIrql
);
186 Thread
->SpecialApcDisable
-= 3;
189 /* make sure we survive this in case of error */
190 ok_eq_long(Mutex
->Count
, 1L);
192 ok_eq_int(Thread
->KernelApcDisable
, KernelApcsDisabled
);
193 Thread
->KernelApcDisable
= KernelApcsDisabled
;
194 ok_eq_int(Thread
->SpecialApcDisable
, SpecialApcsDisabled
);
195 Thread
->SpecialApcDisable
= SpecialApcsDisabled
;
196 ok_irql(OriginalIrql
);
199 typedef VOID (FASTCALL
*PMUTEX_FUNCTION
)(PKGUARDED_MUTEX
);
200 typedef BOOLEAN (FASTCALL
*PMUTEX_TRY_FUNCTION
)(PKGUARDED_MUTEX
);
207 PKGUARDED_MUTEX Mutex
;
208 PMUTEX_FUNCTION Acquire
;
209 PMUTEX_TRY_FUNCTION TryAcquire
;
210 PMUTEX_FUNCTION Release
;
215 } THREAD_DATA
, *PTHREAD_DATA
;
223 PTHREAD_DATA ThreadData
= Parameter
;
228 DPRINT("Thread starting\n");
229 KeRaiseIrql(ThreadData
->Irql
, &Irql
);
233 Ret
= ThreadData
->TryAcquire(ThreadData
->Mutex
);
234 ok_eq_bool(Ret
, ThreadData
->RetExpected
);
237 ThreadData
->Acquire(ThreadData
->Mutex
);
239 ok_bool_false(KeSetEvent(&ThreadData
->OutEvent
, 0, TRUE
), "KeSetEvent returned");
240 DPRINT("Thread now waiting\n");
241 Status
= KeWaitForSingleObject(&ThreadData
->InEvent
, Executive
, KernelMode
, FALSE
, NULL
);
242 DPRINT("Thread done waiting\n");
243 ok_eq_hex(Status
, STATUS_SUCCESS
);
245 if (!ThreadData
->Try
|| Ret
)
246 ThreadData
->Release(ThreadData
->Mutex
);
249 DPRINT("Thread exiting\n");
255 PTHREAD_DATA ThreadData
,
256 PKGUARDED_MUTEX Mutex
,
257 PMUTEX_FUNCTION Acquire
,
258 PMUTEX_TRY_FUNCTION TryAcquire
,
259 PMUTEX_FUNCTION Release
)
261 ThreadData
->Mutex
= Mutex
;
262 KeInitializeEvent(&ThreadData
->InEvent
, NotificationEvent
, FALSE
);
263 KeInitializeEvent(&ThreadData
->OutEvent
, NotificationEvent
, FALSE
);
264 ThreadData
->Acquire
= Acquire
;
265 ThreadData
->TryAcquire
= TryAcquire
;
266 ThreadData
->Release
= Release
;
272 PTHREAD_DATA ThreadData
,
273 PLARGE_INTEGER Timeout
,
278 NTSTATUS Status
= STATUS_SUCCESS
;
279 OBJECT_ATTRIBUTES Attributes
;
281 ThreadData
->Try
= Try
;
282 ThreadData
->Irql
= Irql
;
283 ThreadData
->RetExpected
= RetExpected
;
284 InitializeObjectAttributes(&Attributes
, NULL
, OBJ_KERNEL_HANDLE
, NULL
, NULL
);
285 Status
= PsCreateSystemThread(&ThreadData
->Handle
, GENERIC_ALL
, &Attributes
, NULL
, NULL
, AcquireMutexThread
, ThreadData
);
286 ok_eq_hex(Status
, STATUS_SUCCESS
);
287 Status
= ObReferenceObjectByHandle(ThreadData
->Handle
, SYNCHRONIZE
, *PsThreadType
, KernelMode
, (PVOID
*)&ThreadData
->Thread
, NULL
);
288 ok_eq_hex(Status
, STATUS_SUCCESS
);
290 return KeWaitForSingleObject(&ThreadData
->OutEvent
, Executive
, KernelMode
, FALSE
, Timeout
);
296 PTHREAD_DATA ThreadData
)
298 NTSTATUS Status
= STATUS_SUCCESS
;
300 KeSetEvent(&ThreadData
->InEvent
, 0, TRUE
);
301 Status
= KeWaitForSingleObject(ThreadData
->Thread
, Executive
, KernelMode
, FALSE
, NULL
);
302 ok_eq_hex(Status
, STATUS_SUCCESS
);
304 ObDereferenceObject(ThreadData
->Thread
);
305 Status
= ZwClose(ThreadData
->Handle
);
306 ok_eq_hex(Status
, STATUS_SUCCESS
);
307 KeClearEvent(&ThreadData
->InEvent
);
308 KeClearEvent(&ThreadData
->OutEvent
);
313 TestGuardedMutexConcurrent(
314 PKGUARDED_MUTEX Mutex
)
317 THREAD_DATA ThreadData
;
318 THREAD_DATA ThreadData2
;
319 THREAD_DATA ThreadDataUnsafe
;
320 THREAD_DATA ThreadDataTry
;
321 PKTHREAD Thread
= KeGetCurrentThread();
322 LARGE_INTEGER Timeout
;
323 Timeout
.QuadPart
= -50 * 1000 * 10; /* 50 ms */
325 InitThreadData(&ThreadData
, Mutex
, pKeAcquireGuardedMutex
, NULL
, pKeReleaseGuardedMutex
);
326 InitThreadData(&ThreadData2
, Mutex
, pKeAcquireGuardedMutex
, NULL
, pKeReleaseGuardedMutex
);
327 InitThreadData(&ThreadDataUnsafe
, Mutex
, pKeAcquireGuardedMutexUnsafe
, NULL
, pKeReleaseGuardedMutexUnsafe
);
328 InitThreadData(&ThreadDataTry
, Mutex
, NULL
, pKeTryToAcquireGuardedMutex
, pKeReleaseGuardedMutex
);
330 /* have a thread acquire the mutex */
331 Status
= StartThread(&ThreadData
, NULL
, PASSIVE_LEVEL
, FALSE
, FALSE
);
332 ok_eq_hex(Status
, STATUS_SUCCESS
);
333 CheckMutex(Mutex
, 0L, ThreadData
.Thread
, 0LU, 0x5555, -1, 0, 0, FALSE
, PASSIVE_LEVEL
);
334 /* have a second thread try to acquire it -- should fail */
335 Status
= StartThread(&ThreadDataTry
, NULL
, PASSIVE_LEVEL
, TRUE
, FALSE
);
336 ok_eq_hex(Status
, STATUS_SUCCESS
);
337 CheckMutex(Mutex
, 0L, ThreadData
.Thread
, 0LU, 0x5555, -1, 0, 0, FALSE
, PASSIVE_LEVEL
);
338 FinishThread(&ThreadDataTry
);
340 /* have another thread acquire it -- should block */
341 Status
= StartThread(&ThreadData2
, &Timeout
, APC_LEVEL
, FALSE
, FALSE
);
342 ok_eq_hex(Status
, STATUS_TIMEOUT
);
343 CheckMutex(Mutex
, 4L, ThreadData
.Thread
, 1LU, 0x5555, -1, 0, 0, FALSE
, PASSIVE_LEVEL
);
345 /* finish the first thread -- now the second should become available */
346 FinishThread(&ThreadData
);
347 Status
= KeWaitForSingleObject(&ThreadData2
.OutEvent
, Executive
, KernelMode
, FALSE
, NULL
);
348 ok_eq_hex(Status
, STATUS_SUCCESS
);
349 CheckMutex(Mutex
, 0L, ThreadData2
.Thread
, 1LU, 0x5555, -1, 0, 0, FALSE
, PASSIVE_LEVEL
);
351 /* block two more threads */
352 Status
= StartThread(&ThreadDataUnsafe
, &Timeout
, APC_LEVEL
, FALSE
, FALSE
);
353 ok_eq_hex(Status
, STATUS_TIMEOUT
);
354 CheckMutex(Mutex
, 4L, ThreadData2
.Thread
, 2LU, 0x5555, -1, 0, 0, FALSE
, PASSIVE_LEVEL
);
356 Status
= StartThread(&ThreadData
, &Timeout
, PASSIVE_LEVEL
, FALSE
, FALSE
);
357 ok_eq_hex(Status
, STATUS_TIMEOUT
);
358 CheckMutex(Mutex
, 8L, ThreadData2
.Thread
, 3LU, 0x5555, -1, 0, 0, FALSE
, PASSIVE_LEVEL
);
361 FinishThread(&ThreadData2
);
362 Status
= KeWaitForSingleObject(&ThreadDataUnsafe
.OutEvent
, Executive
, KernelMode
, FALSE
, NULL
);
363 ok_eq_hex(Status
, STATUS_SUCCESS
);
364 CheckMutex(Mutex
, 4L, ThreadDataUnsafe
.Thread
, 3LU, 0x5555, -1, 0, 0, FALSE
, PASSIVE_LEVEL
);
367 FinishThread(&ThreadDataUnsafe
);
368 Status
= KeWaitForSingleObject(&ThreadData
.OutEvent
, Executive
, KernelMode
, FALSE
, NULL
);
369 ok_eq_hex(Status
, STATUS_SUCCESS
);
370 CheckMutex(Mutex
, 0L, ThreadData
.Thread
, 3LU, 0x5555, -1, 0, 0, FALSE
, PASSIVE_LEVEL
);
373 FinishThread(&ThreadData
);
375 CheckMutex(Mutex
, 1L, NULL
, 3LU, 0x5555, -1, 0, 0, FALSE
, PASSIVE_LEVEL
);
378 START_TEST(KeGuardedMutex
)
380 KGUARDED_MUTEX Mutex
;
382 PKTHREAD Thread
= KeGetCurrentThread();
385 SHORT KernelApcsDisabled
;
386 SHORT SpecialApcsDisabled
;
387 BOOLEAN AllApcsDisabled
;
390 { PASSIVE_LEVEL
, 0, 0, FALSE
},
391 { PASSIVE_LEVEL
, -1, 0, FALSE
},
392 { PASSIVE_LEVEL
, -3, 0, FALSE
},
393 { PASSIVE_LEVEL
, 0, -1, TRUE
},
394 { PASSIVE_LEVEL
, -1, -1, TRUE
},
395 { PASSIVE_LEVEL
, -3, -2, TRUE
},
397 { APC_LEVEL
, 0, 0, TRUE
},
398 { APC_LEVEL
, -1, 0, TRUE
},
399 { APC_LEVEL
, -3, 0, TRUE
},
400 { APC_LEVEL
, 0, -1, TRUE
},
401 { APC_LEVEL
, -1, -1, TRUE
},
402 { APC_LEVEL
, -3, -2, TRUE
},
404 { DISPATCH_LEVEL
, 0, 0, TRUE
},
405 { DISPATCH_LEVEL
, -1, 0, TRUE
},
406 { DISPATCH_LEVEL
, -3, 0, TRUE
},
407 { DISPATCH_LEVEL
, 0, -1, TRUE
},
408 { DISPATCH_LEVEL
, -1, -1, TRUE
},
409 { DISPATCH_LEVEL
, -3, -2, TRUE
},
411 { HIGH_LEVEL
, 0, 0, TRUE
},
412 { HIGH_LEVEL
, -1, 0, TRUE
},
413 { HIGH_LEVEL
, -3, 0, TRUE
},
414 { HIGH_LEVEL
, 0, -1, TRUE
},
415 { HIGH_LEVEL
, -1, -1, TRUE
},
416 { HIGH_LEVEL
, -3, -2, TRUE
},
420 pKeAreAllApcsDisabled
= KmtGetSystemRoutineAddress(L
"KeAreAllApcsDisabled");
421 pKeInitializeGuardedMutex
= KmtGetSystemRoutineAddress(L
"KeInitializeGuardedMutex");
422 pKeAcquireGuardedMutex
= KmtGetSystemRoutineAddress(L
"KeAcquireGuardedMutex");
423 pKeAcquireGuardedMutexUnsafe
= KmtGetSystemRoutineAddress(L
"KeAcquireGuardedMutexUnsafe");
424 pKeEnterGuardedRegion
= KmtGetSystemRoutineAddress(L
"KeEnterGuardedRegion");
425 pKeLeaveGuardedRegion
= KmtGetSystemRoutineAddress(L
"KeLeaveGuardedRegion");
426 pKeReleaseGuardedMutex
= KmtGetSystemRoutineAddress(L
"KeReleaseGuardedMutex");
427 pKeReleaseGuardedMutexUnsafe
= KmtGetSystemRoutineAddress(L
"KeReleaseGuardedMutexUnsafe");
428 pKeTryToAcquireGuardedMutex
= KmtGetSystemRoutineAddress(L
"KeTryToAcquireGuardedMutex");
430 if (skip(pKeAreAllApcsDisabled
&&
431 pKeInitializeGuardedMutex
&&
432 pKeAcquireGuardedMutex
&&
433 pKeAcquireGuardedMutexUnsafe
&&
434 pKeEnterGuardedRegion
&&
435 pKeLeaveGuardedRegion
&&
436 pKeReleaseGuardedMutex
&&
437 pKeReleaseGuardedMutexUnsafe
&&
438 pKeTryToAcquireGuardedMutex
, "No guarded mutexes\n"))
443 for (i
= 0; i
< sizeof TestIterations
/ sizeof TestIterations
[0]; ++i
)
445 trace("Run %d\n", i
);
446 KeRaiseIrql(TestIterations
[i
].Irql
, &OldIrql
);
447 Thread
->KernelApcDisable
= TestIterations
[i
].KernelApcsDisabled
;
448 Thread
->SpecialApcDisable
= TestIterations
[i
].SpecialApcsDisabled
;
450 RtlFillMemory(&Mutex
, sizeof Mutex
, 0x55);
451 pKeInitializeGuardedMutex(&Mutex
);
452 CheckMutex(&Mutex
, 1L, NULL
, 0LU, 0x5555, 0x5555, TestIterations
[i
].KernelApcsDisabled
, TestIterations
[i
].SpecialApcsDisabled
, TestIterations
[i
].AllApcsDisabled
, TestIterations
[i
].Irql
);
453 TestGuardedMutex(&Mutex
, TestIterations
[i
].KernelApcsDisabled
, TestIterations
[i
].SpecialApcsDisabled
, TestIterations
[i
].AllApcsDisabled
, TestIterations
[i
].Irql
);
455 Thread
->SpecialApcDisable
= 0;
456 Thread
->KernelApcDisable
= 0;
457 KeLowerIrql(OldIrql
);
460 trace("Concurrent test\n");
461 RtlFillMemory(&Mutex
, sizeof Mutex
, 0x55);
462 pKeInitializeGuardedMutex(&Mutex
);
463 TestGuardedMutexConcurrent(&Mutex
);