18*pKeAreAllApcsDisabled)(
VOID);
28*pKeAcquireGuardedMutex)(
38*pKeAcquireGuardedMutexUnsafe)(
46*pKeEnterGuardedRegion)(
VOID);
53*pKeLeaveGuardedRegion)(
VOID);
60*pKeInitializeGuardedMutex)(
69*pKeReleaseGuardedMutexUnsafe)(
79*pKeReleaseGuardedMutex)(
89*pKeTryToAcquireGuardedMutex)(
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); \
117 SHORT KernelApcsDisabled,
118 SHORT SpecialApcsDisabled,
119 SHORT AllApcsDisabled,
124 ok_irql(OriginalIrql);
125 CheckMutex(
Mutex, 1L,
NULL, 0LU, 0x5555, 0x5555, KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, OriginalIrql);
131 pKeAcquireGuardedMutex(
Mutex);
132 CheckMutex(
Mutex, 0
L,
Thread, 0LU, 0x5555, SpecialApcsDisabled - 1, KernelApcsDisabled, SpecialApcsDisabled - 1,
TRUE, OriginalIrql);
133 ok_bool_false(pKeTryToAcquireGuardedMutex(
Mutex),
"KeTryToAcquireGuardedMutex returned");
134 CheckMutex(
Mutex, 0
L,
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, 0
L,
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);
146 Mutex->SpecialApcDisable = SpecialApcsDisabled - 1;
152 pKeAcquireGuardedMutexUnsafe(
Mutex);
153 CheckMutex(
Mutex, 0
L,
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);
162 pKeAcquireGuardedMutex(
Mutex);
163 CheckMutex(
Mutex, 0
L,
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, 0
L,
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);
177 pKeReleaseGuardedMutexUnsafe(
Mutex);
178 CheckMutex(
Mutex, 0
L,
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);
183 CheckMutex(
Mutex, 0
L,
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;
193 Thread->KernelApcDisable = KernelApcsDisabled;
195 Thread->SpecialApcDisable = SpecialApcsDisabled;
196 ok_irql(OriginalIrql);
228 DPRINT(
"Thread starting\n");
240 DPRINT(
"Thread now waiting\n");
242 DPRINT(
"Thread done waiting\n");
249 DPRINT(
"Thread exiting\n");
323 Timeout.QuadPart = -50 * 1000 * 10;
385 SHORT KernelApcsDisabled;
386 SHORT SpecialApcsDisabled;
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)
447 Thread->KernelApcDisable = TestIterations[
i].KernelApcsDisabled;
448 Thread->SpecialApcDisable = TestIterations[
i].SpecialApcsDisabled;
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;
460 trace(
"Concurrent test\n");
462 pKeInitializeGuardedMutex(&
Mutex);
static NTSTATUS StartThread(PTHREAD_DATA ThreadData, PLARGE_INTEGER Timeout, KIRQL Irql, BOOLEAN Try, BOOLEAN RetExpected)
#define CheckMutex(Mutex, ExpectedCount, ExpectedOwner, ExpectedContention, ExpectedKernelApcDisable, ExpectedSpecialApcDisable, KernelApcsDisabled, SpecialApcsDisabled, AllApcsDisabled, ExpectedIrql)
static VOID NTAPI AcquireMutexThread(PVOID Parameter)
static VOID InitThreadData(PTHREAD_DATA ThreadData, PKGUARDED_MUTEX Mutex, PMUTEX_FUNCTION Acquire, PMUTEX_TRY_FUNCTION TryAcquire, PMUTEX_FUNCTION Release)
static VOID FinishThread(PTHREAD_DATA ThreadData)
static VOID TestGuardedMutexConcurrent(PKGUARDED_MUTEX Mutex)
struct THREAD_DATA * PTHREAD_DATA
VOID(FASTCALL * PMUTEX_FUNCTION)(PKGUARDED_MUTEX)
BOOLEAN(FASTCALL * PMUTEX_TRY_FUNCTION)(PKGUARDED_MUTEX)
#define ok_eq_hex(value, expected)
#define ok_eq_long(value, expected)
#define ok_bool_false(value, desc)
#define ok_bool_true(value, desc)
#define ok_eq_int(value, expected)
#define ok_eq_bool(value, expected)
#define _Acquires_lock_(lock)
#define _Requires_lock_held_(lock)
#define _Acquires_exclusive_lock_(lock)
#define _Requires_lock_not_held_(lock)
#define _Releases_lock_(lock)
#define _IRQL_requires_min_(irql)
#define _IRQL_requires_max_(irql)
#define KeRaiseIrql(irql, oldIrql)
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
#define KeInitializeEvent(pEvt, foo, foo2)
#define KeLowerIrql(oldIrql)
#define KeSetEvent(pEvt, foo, foo2)
VOID NTAPI KeClearEvent(IN PKEVENT Event)
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define KeGetCurrentThread
#define OBJ_KERNEL_HANDLE
#define RtlFillMemory(Dest, Length, Fill)
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
BOOLEAN KmtIsCheckedBuild
#define InitializeObjectAttributes(p, n, a, r, s)
#define _Must_inspect_result_
#define _When_(expr, annos)
#define _Post_satisfies_(cond)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
POBJECT_TYPE PsThreadType
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
struct _KGUARDED_MUTEX * PKGUARDED_MUTEX
#define ObDereferenceObject
_Inout_opt_ PVOID Parameter