reactos/sdk/lib/drivers/wdf/shared/support/fxspinlock.cpp
Victor Perevertkin 8a978a179f
[WDF] Add Windows Driver Framework files
Takern from Microsoft GitHub repo:
d9c6040fe9

Licensed under MIT
2020-11-03 00:06:26 +03:00

143 lines
3.2 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Module Name:
FxSpinLock.cpp
Abstract:
This module implements FxSpinLock
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#include "FxSupportPch.hpp"
#include "FxSpinLock.hpp"
extern "C" {
#include "FxSpinLock.tmh"
}
FxSpinLock::FxSpinLock(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in USHORT ExtraSize
) :
FxObject(FX_TYPE_SPIN_LOCK, COMPUTE_OBJECT_SIZE(sizeof(FxSpinLock), ExtraSize), FxDriverGlobals)
{
FX_SPIN_LOCK_HISTORY* pHistory;
m_Irql = 0;
m_InterruptLock = FALSE;
pHistory = GetHistory();
if (pHistory != NULL) {
RtlZeroMemory(pHistory, sizeof(FX_SPIN_LOCK_HISTORY));
pHistory->CurrentHistory = &pHistory->History[0];
}
}
__drv_raisesIRQL(DISPATCH_LEVEL)
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
FxSpinLock::AcquireLock(
__in PVOID CallersAddress
)
{
PFX_SPIN_LOCK_HISTORY pHistory;
KIRQL irql;
m_SpinLock.Acquire(&irql);
m_Irql = irql;
pHistory = GetHistory();
if (pHistory != NULL) {
PFX_SPIN_LOCK_HISTORY_ENTRY pCur;
//
// This assert should never fire here, but this helps track ownership
// in the case of a release without an acquire.
//
ASSERT(pHistory->OwningThread == NULL);
pHistory->OwningThread = Mx::MxGetCurrentThread();
pCur = pHistory->CurrentHistory;
Mx::MxQueryTickCount(&pCur->AcquiredAtTime);
pCur->CallersAddress = CallersAddress;
}
}
__drv_requiresIRQL(DISPATCH_LEVEL)
VOID
FxSpinLock::ReleaseLock(
VOID
)
{
PFX_SPIN_LOCK_HISTORY pHistory;
pHistory = GetHistory();
if (pHistory != NULL) {
LARGE_INTEGER now;
PFX_SPIN_LOCK_HISTORY_ENTRY pCur;
if (pHistory->OwningThread != Mx::MxGetCurrentThread()) {
if (pHistory->OwningThread == NULL) {
DoTraceLevelMessage(
GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGERROR,
"WDFSPINLOCK %p being released by thread 0x%p, but was "
"never acquired!", GetObjectHandle(), Mx::MxGetCurrentThread());
}
else {
DoTraceLevelMessage(
GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGERROR,
"WDFSPINLOCK 0x%p not owned by thread 0x%p, owned by thread 0x%p",
GetObjectHandle(), Mx::MxGetCurrentThread(),
pHistory->OwningThread);
}
FxVerifierBugCheck(GetDriverGlobals(),
WDF_INVALID_LOCK_OPERATION,
(ULONG_PTR) GetObjectHandle(),
0x1);
//
// Will not get here
//
return;
}
ASSERT(pHistory->OwningThread != NULL);
Mx::MxQueryTickCount(&now);
pCur = pHistory->CurrentHistory;
pCur->LockedDuraction = now.QuadPart - pCur->AcquiredAtTime.QuadPart;
pHistory->CurrentHistory++;
if (pHistory->CurrentHistory >=
pHistory->History + FX_SPIN_LOCK_NUM_HISTORY_ENTRIES) {
pHistory->CurrentHistory = pHistory->History;
}
pHistory->OwningThread = NULL;
}
m_SpinLock.Release(m_Irql);
}