17#define WIN9X_COMPAT_SPINLOCK
30*pKeTryToAcquireSpinLockAtDpcLevel)(
38*pKeAcquireInStackQueuedSpinLockForDpc)(
45*pKeReleaseInStackQueuedSpinLockForDpc)(
58typedef
struct _CHECK_DATA CHECK_DATA, *PCHECK_DATA;
72 KIRQL IrqlWhenAcquired;
75 PTRY_FUNCTION TryAcquire;
77 PRELEASE_FUNCTION ReleaseNoLower;
78 PTRY_FUNCTION TryAcquireNoRaise;
92#define DEFINE_ACQUIRE(LocalName, SetIsAcquired, DoCall) \
93static VOID LocalName(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData) \
95 ASSERT(!CheckData->IsAcquired); \
97 if (SetIsAcquired) CheckData->IsAcquired = TRUE; \
100#define DEFINE_RELEASE(LocalName, SetIsAcquired, DoCall) \
101static VOID LocalName(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData) \
104 if (SetIsAcquired) CheckData->IsAcquired = FALSE; \
141DEFINE_RELEASE(ReleaseInStackForDpc,
FALSE, pKeReleaseInStackQueuedSpinLockForDpc(&CheckData->QueueHandle))
153 CheckData->IsAcquired =
TRUE;
159 CheckData->IsAcquired =
TRUE;
167#define CheckSpinLockLock(SpinLock, CheckData, Value) do \
169 PKTHREAD Thread = KeGetCurrentThread(); \
171 if (KmtIsMultiProcessorBuild || KmtIsCheckedBuild) \
173 ok_eq_bool(Ret, (Value) == 0); \
176 if (KmtIsCheckedBuild) \
177 ok_eq_ulongptr(*(SpinLock), (Value) ? (ULONG_PTR)Thread | 1 : 0); \
179 ok_eq_ulongptr(*(SpinLock), (Value) ? 1 : 0); \
184 ok_bool_true(Ret, "KeTestSpinLock returned"); \
186 ok_eq_ulongptr(*(SpinLock), 0); \
188 ok_eq_uint((CheckData)->Irql, (CheckData)->OriginalIrql); \
191#define CheckSpinLockQueue(SpinLock, CheckData, Value) do \
193 ok_eq_pointer((CheckData)->Queue->Next, NULL); \
194 ok_eq_pointer((CheckData)->Queue->Lock, NULL); \
195 ok_eq_uint((CheckData)->Irql, (CheckData)->OriginalIrql); \
198#define CheckSpinLockQueueHandle(SpinLock, CheckData, Value) do \
200 if (KmtIsMultiProcessorBuild || KmtIsCheckedBuild) \
202 ok_eq_bool(Ret, (Value) == 0); \
204 ok_eq_ulongptr(*(SpinLock), \
205 (Value) ? &(CheckData)->QueueHandle : 0); \
206 ok_eq_pointer((CheckData)->QueueHandle.LockQueue.Next, NULL); \
207 ok_eq_pointer((CheckData)->QueueHandle.LockQueue.Lock, \
208 (PVOID)((ULONG_PTR)SpinLock | ((Value) ? 2 : 0))); \
212 ok_bool_true(Ret, "KeTestSpinLock returned"); \
214 ok_eq_ulongptr(*(SpinLock), 0); \
215 ok_eq_pointer((CheckData)->QueueHandle.LockQueue.Next, (CheckData)->UntouchedValue); \
216 ok_eq_pointer((CheckData)->QueueHandle.LockQueue.Lock, (CheckData)->UntouchedValue); \
218 ok_eq_uint((CheckData)->QueueHandle.OldIrql, (CheckData)->OriginalIrql); \
221#define CheckSpinLock(SpinLock, CheckData, Value) do \
223 BOOLEAN Ret = SpinLock && pKeTestSpinLock ? pKeTestSpinLock(SpinLock) : TRUE; \
224 KIRQL ExpectedIrql = (CheckData)->OriginalIrql; \
226 switch ((CheckData)->Check) \
229 CheckSpinLockLock(SpinLock, CheckData, Value); \
232 CheckSpinLockQueue(SpinLock, CheckData, Value); \
234 case CheckQueueHandle: \
235 CheckSpinLockQueueHandle(SpinLock, CheckData, Value); \
239 if ((CheckData)->IsAcquired) \
240 ExpectedIrql = (CheckData)->IrqlWhenAcquired; \
241 ok_irql(ExpectedIrql); \
242 ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); \
243 ok_bool_true(KmtAreInterruptsEnabled(), "Interrupts enabled:"); \
250 PCHECK_DATA CheckData)
253 trace(
"Test SpinLock run %d\n",
Run++);
255 ok_irql(CheckData->OriginalIrql);
259 CheckData->Acquire(
SpinLock, CheckData);
261 CheckData->Release(
SpinLock, CheckData);
264 if (CheckData->TryAcquire)
281 ok_eq_uint(CheckData->Irql, CheckData->IrqlWhenAcquired);
282 CheckData->Irql = CheckData->OriginalIrql;
286 CheckData->Release(
SpinLock, CheckData);
290 if (CheckData->AcquireNoRaise &&
292 (CheckData->AcquireNoRaise != AcquireInStackForDpc ||
293 !
skip(pKeAcquireInStackQueuedSpinLockForDpc &&
294 pKeReleaseInStackQueuedSpinLockForDpc,
"No DPC spinlock functions\n")))
297 CheckData->AcquireNoRaise(
SpinLock, CheckData);
299 CheckData->ReleaseNoLower(
SpinLock, CheckData);
303 CheckData->AcquireNoRaise(
SpinLock, CheckData);
305 CheckData->Release(
SpinLock, CheckData);
309 CheckData->Acquire(
SpinLock, CheckData);
311 CheckData->ReleaseNoLower(
SpinLock, CheckData);
313 CheckData->IsAcquired =
FALSE;
316 if (CheckData->TryAcquireNoRaise &&
317 !
skip(pKeTryToAcquireSpinLockAtDpcLevel !=
NULL,
"KeTryToAcquireSpinLockAtDpcLevel unavailable\n"))
336 CheckData->ReleaseNoLower(
SpinLock, CheckData);
341 ok_irql(CheckData->OriginalIrql);
359 { CheckLock, SynchIrql, AcquireSynch, ReleaseNormal,
NULL,
NULL,
NULL,
NULL },
360 { CheckQueueHandle,
DISPATCH_LEVEL, AcquireInStackQueued, ReleaseInStackQueued,
NULL, AcquireInStackNoRaise, ReleaseInStackNoRaise,
NULL },
361 { CheckQueueHandle, SynchIrql, AcquireInStackSynch, ReleaseInStackQueued,
NULL,
NULL,
NULL,
NULL },
362 { CheckQueueHandle,
DISPATCH_LEVEL, AcquireInStackQueued, ReleaseInStackQueued,
NULL, AcquireInStackForDpc, ReleaseInStackForDpc,
NULL },
382 if (!
skip(pKeTestSpinLock !=
NULL,
"KeTestSpinLock unavailable\n"))
415 for (iIrql = 0; iIrql <
sizeof OriginalIrqls /
sizeof OriginalIrqls[0]; ++iIrql)
420 TestData[
i].OriginalIrql = OriginalIrqls[iIrql];
BOOLEAN(NTAPI * PACQUIRE_FUNCTION)(PERESOURCE, BOOLEAN)
static VOID TestSpinLock(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData)
BOOLEAN TryNoRaise(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData)
#define DEFINE_RELEASE(LocalName, SetIsAcquired, DoCall)
#define DEFINE_ACQUIRE(LocalName, SetIsAcquired, DoCall)
#define CheckSpinLock(SpinLock, CheckData, Value)
BOOLEAN TryQueuedSynch(PKSPIN_LOCK SpinLock, PCHECK_DATA CheckData)
#define ok_bool_false(value, desc)
#define ok_eq_uint(value, expected)
#define ok_bool_true(value, desc)
#define ok_eq_ulongptr(value, expected)
#define _Acquires_lock_(lock)
#define _Requires_lock_not_held_(lock)
#define _IRQL_requires_min_(irql)
#define KeRaiseIrql(irql, oldIrql)
#define KeReleaseSpinLock(sl, irql)
#define KeLowerIrql(oldIrql)
#define KeAcquireSpinLock(sl, irql)
#define KeInitializeSpinLock(sl)
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
VOID FASTCALL KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle)
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
KIRQL FASTCALL KeAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
VOID FASTCALL KeAcquireInStackQueuedSpinLockRaiseToSynch(IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle)
VOID FASTCALL KeReleaseInStackQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle)
BOOLEAN FASTCALL KeTryToAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN PKIRQL OldIrql)
KIRQL FASTCALL KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock)
LOGICAL FASTCALL KeTryToAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, OUT PKIRQL OldIrql)
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
VOID KmtSetIrql(IN KIRQL NewIrql)
BOOLEAN KmtIsCheckedBuild
BOOLEAN KmtIsMultiProcessorBuild
#define _Must_inspect_result_
#define _When_(expr, annos)
#define _Post_satisfies_(cond)
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
VOID FASTCALL KeAcquireInStackQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle)
VOID FASTCALL KeReleaseInStackQueuedSpinLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle)
VOID FASTCALL KeReleaseSpinLockForDpc(IN PKSPIN_LOCK SpinLock, IN KIRQL OldIrql)
VOID FASTCALL KiAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
VOID FASTCALL KiReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
KIRQL FASTCALL KeAcquireSpinLockForDpc(IN PKSPIN_LOCK SpinLock)
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
KSPIN_LOCK_QUEUE LockQueue[LockQueueMaximumLock]
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFSPINLOCK * SpinLock
*LockHandle LockHandle _Out_ PKLOCK_QUEUE_HANDLE LockHandle
enum _KSPIN_LOCK_QUEUE_NUMBER KSPIN_LOCK_QUEUE_NUMBER