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 <thfabba@gmx.de>
13 #define CheckMutex(Mutex, ExpectedCount, ExpectedOwner, ExpectedContention, \
14 ExpectedKernelApcDisable, ExpectedSpecialApcDisable, \
15 KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, \
18 ok_eq_long((Mutex)->Count, ExpectedCount); \
19 ok_eq_pointer((Mutex)->Owner, ExpectedOwner); \
20 ok_eq_ulong((Mutex)->Contention, ExpectedContention); \
21 ok_eq_int((Mutex)->KernelApcDisable, ExpectedKernelApcDisable); \
22 if (KmtIsCheckedBuild) \
23 ok_eq_int((Mutex)->SpecialApcDisable, ExpectedSpecialApcDisable); \
25 ok_eq_int((Mutex)->SpecialApcDisable, 0x5555); \
26 ok_eq_bool(KeAreApcsDisabled(), KernelApcsDisabled || SpecialApcsDisabled); \
27 ok_eq_int(Thread->KernelApcDisable, KernelApcsDisabled); \
28 ok_eq_bool(KeAreAllApcsDisabled(), AllApcsDisabled); \
29 ok_eq_int(Thread->SpecialApcDisable, SpecialApcsDisabled); \
30 ok_irql(ExpectedIrql); \
36 PKGUARDED_MUTEX Mutex
,
37 SHORT KernelApcsDisabled
,
38 SHORT SpecialApcsDisabled
,
39 SHORT AllApcsDisabled
,
42 PKTHREAD Thread
= KeGetCurrentThread();
44 ok_irql(OriginalIrql
);
45 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, 0x5555, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
48 if (!KmtIsCheckedBuild
|| OriginalIrql
<= APC_LEVEL
)
50 /* acquire/release normally */
51 KeAcquireGuardedMutex(Mutex
);
52 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
- 1, TRUE
, OriginalIrql
);
53 ok_bool_false(KeTryToAcquireGuardedMutex(Mutex
), "KeTryToAcquireGuardedMutex returned");
54 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
- 1, TRUE
, OriginalIrql
);
55 KeReleaseGuardedMutex(Mutex
);
56 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
59 ok_bool_true(KeTryToAcquireGuardedMutex(Mutex
), "KeTryToAcquireGuardedMutex returned");
60 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
- 1, TRUE
, OriginalIrql
);
61 KeReleaseGuardedMutex(Mutex
);
62 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
65 /* Make the following test happy */
66 Mutex
->SpecialApcDisable
= SpecialApcsDisabled
- 1;
69 if (!KmtIsCheckedBuild
|| OriginalIrql
== APC_LEVEL
|| SpecialApcsDisabled
< 0)
71 /* acquire/release unsafe */
72 KeAcquireGuardedMutexUnsafe(Mutex
);
73 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
74 KeReleaseGuardedMutexUnsafe(Mutex
);
75 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
78 /* Bugchecks >= DISPATCH_LEVEL */
79 if (!KmtIsCheckedBuild
)
81 /* mismatched acquire/release */
82 KeAcquireGuardedMutex(Mutex
);
83 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
- 1, TRUE
, OriginalIrql
);
84 KeReleaseGuardedMutexUnsafe(Mutex
);
85 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
- 1, TRUE
, OriginalIrql
);
86 KeLeaveGuardedRegion();
87 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
89 KeAcquireGuardedMutexUnsafe(Mutex
);
90 CheckMutex(Mutex
, 0L, Thread
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
91 KeReleaseGuardedMutex(Mutex
);
92 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
+ 1, OriginalIrql
>= APC_LEVEL
|| SpecialApcsDisabled
!= -1, OriginalIrql
);
93 KeEnterGuardedRegion();
94 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
96 /* release without acquire */
97 KeReleaseGuardedMutexUnsafe(Mutex
);
98 CheckMutex(Mutex
, 0L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
- 1, KernelApcsDisabled
, SpecialApcsDisabled
, AllApcsDisabled
, OriginalIrql
);
99 KeReleaseGuardedMutex(Mutex
);
100 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
, KernelApcsDisabled
, SpecialApcsDisabled
+ 1, OriginalIrql
>= APC_LEVEL
|| SpecialApcsDisabled
!= -1, OriginalIrql
);
101 KeReleaseGuardedMutex(Mutex
);
102 /* TODO: here we see that Mutex->Count isn't actually just a count. Test the bits correctly! */
103 CheckMutex(Mutex
, 0L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
, KernelApcsDisabled
, SpecialApcsDisabled
+ 2, OriginalIrql
>= APC_LEVEL
|| SpecialApcsDisabled
!= -2, OriginalIrql
);
104 KeReleaseGuardedMutex(Mutex
);
105 CheckMutex(Mutex
, 1L, NULL
, 0LU, 0x5555, SpecialApcsDisabled
, KernelApcsDisabled
, SpecialApcsDisabled
+ 3, OriginalIrql
>= APC_LEVEL
|| SpecialApcsDisabled
!= -3, OriginalIrql
);
106 Thread
->SpecialApcDisable
-= 3;
109 /* make sure we survive this in case of error */
110 ok_eq_long(Mutex
->Count
, 1L);
112 ok_eq_int(Thread
->KernelApcDisable
, KernelApcsDisabled
);
113 Thread
->KernelApcDisable
= KernelApcsDisabled
;
114 ok_eq_int(Thread
->SpecialApcDisable
, SpecialApcsDisabled
);
115 Thread
->SpecialApcDisable
= SpecialApcsDisabled
;
116 ok_irql(OriginalIrql
);
119 START_TEST(KeGuardedMutex
)
121 KGUARDED_MUTEX Mutex
;
123 PKTHREAD Thread
= KeGetCurrentThread();
126 SHORT KernelApcsDisabled
;
127 SHORT SpecialApcsDisabled
;
128 BOOLEAN AllApcsDisabled
;
131 { PASSIVE_LEVEL
, 0, 0, FALSE
},
132 { PASSIVE_LEVEL
, -1, 0, FALSE
},
133 { PASSIVE_LEVEL
, -3, 0, FALSE
},
134 { PASSIVE_LEVEL
, 0, -1, TRUE
},
135 { PASSIVE_LEVEL
, -1, -1, TRUE
},
136 { PASSIVE_LEVEL
, -3, -2, TRUE
},
138 { APC_LEVEL
, 0, 0, TRUE
},
139 { APC_LEVEL
, -1, 0, TRUE
},
140 { APC_LEVEL
, -3, 0, TRUE
},
141 { APC_LEVEL
, 0, -1, TRUE
},
142 { APC_LEVEL
, -1, -1, TRUE
},
143 { APC_LEVEL
, -3, -2, TRUE
},
145 { DISPATCH_LEVEL
, 0, 0, TRUE
},
146 { DISPATCH_LEVEL
, -1, 0, TRUE
},
147 { DISPATCH_LEVEL
, -3, 0, TRUE
},
148 { DISPATCH_LEVEL
, 0, -1, TRUE
},
149 { DISPATCH_LEVEL
, -1, -1, TRUE
},
150 { DISPATCH_LEVEL
, -3, -2, TRUE
},
152 { HIGH_LEVEL
, 0, 0, TRUE
},
153 { HIGH_LEVEL
, -1, 0, TRUE
},
154 { HIGH_LEVEL
, -3, 0, TRUE
},
155 { HIGH_LEVEL
, 0, -1, TRUE
},
156 { HIGH_LEVEL
, -1, -1, TRUE
},
157 { HIGH_LEVEL
, -3, -2, TRUE
},
161 for (i
= 0; i
< sizeof TestIterations
/ sizeof TestIterations
[0]; ++i
)
163 trace("Run %d\n", i
);
164 KeRaiseIrql(TestIterations
[i
].Irql
, &OldIrql
);
165 Thread
->KernelApcDisable
= TestIterations
[i
].KernelApcsDisabled
;
166 Thread
->SpecialApcDisable
= TestIterations
[i
].SpecialApcsDisabled
;
168 RtlFillMemory(&Mutex
, sizeof Mutex
, 0x55);
169 KeInitializeGuardedMutex(&Mutex
);
170 CheckMutex(&Mutex
, 1L, NULL
, 0LU, 0x5555, 0x5555, TestIterations
[i
].KernelApcsDisabled
, TestIterations
[i
].SpecialApcsDisabled
, TestIterations
[i
].AllApcsDisabled
, TestIterations
[i
].Irql
);
171 TestGuardedMutex(&Mutex
, TestIterations
[i
].KernelApcsDisabled
, TestIterations
[i
].SpecialApcsDisabled
, TestIterations
[i
].AllApcsDisabled
, TestIterations
[i
].Irql
);
173 Thread
->SpecialApcDisable
= 0;
174 Thread
->KernelApcDisable
= 0;
175 KeLowerIrql(OldIrql
);