mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 08:30:21 +00:00
[NTOS:IO] Use a guarded region in IopQueueIrpToThread.
We're protecting against IopCompleteRequest, which is a special kernel APC. So this is a little bit faster than raising the IRQL.
This commit is contained in:
parent
8d10682307
commit
2e76fb9fe1
2 changed files with 29 additions and 24 deletions
|
@ -48,22 +48,27 @@ FORCEINLINE
|
|||
VOID
|
||||
IopQueueIrpToThread(IN PIRP Irp)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PETHREAD Thread = Irp->Tail.Overlay.Thread;
|
||||
|
||||
/* Raise to APC Level */
|
||||
KeRaiseIrql(APC_LEVEL, &OldIrql);
|
||||
/* Disable special kernel APCs so we can't race with IopCompleteRequest.
|
||||
* IRP's thread must be the current thread */
|
||||
KeEnterGuardedRegionThread(&Thread->Tcb);
|
||||
|
||||
/* Insert it into the list */
|
||||
InsertHeadList(&Irp->Tail.Overlay.Thread->IrpList, &Irp->ThreadListEntry);
|
||||
InsertHeadList(&Thread->IrpList, &Irp->ThreadListEntry);
|
||||
|
||||
/* Lower irql */
|
||||
KeLowerIrql(OldIrql);
|
||||
/* Leave the guarded region */
|
||||
KeLeaveGuardedRegionThread(&Thread->Tcb);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
IopUnQueueIrpFromThread(IN PIRP Irp)
|
||||
{
|
||||
/* Special kernel APCs must be disabled so we can't race with
|
||||
* IopCompleteRequest (or because we are called from there) */
|
||||
ASSERT(KeAreAllApcsDisabled());
|
||||
|
||||
/* Remove it from the list and reset it */
|
||||
if (IsListEmpty(&Irp->ThreadListEntry))
|
||||
return;
|
||||
|
|
|
@ -28,12 +28,12 @@ KeGetPreviousMode(VOID)
|
|||
{ \
|
||||
/* Sanity checks */ \
|
||||
ASSERT(KeGetCurrentIrql() <= APC_LEVEL); \
|
||||
ASSERT(_Thread == KeGetCurrentThread()); \
|
||||
ASSERT((_Thread->SpecialApcDisable <= 0) && \
|
||||
(_Thread->SpecialApcDisable != -32768)); \
|
||||
ASSERT((_Thread) == KeGetCurrentThread()); \
|
||||
ASSERT(((_Thread)->SpecialApcDisable <= 0) && \
|
||||
((_Thread)->SpecialApcDisable != -32768)); \
|
||||
\
|
||||
/* Disable Special APCs */ \
|
||||
_Thread->SpecialApcDisable--; \
|
||||
(_Thread)->SpecialApcDisable--; \
|
||||
}
|
||||
|
||||
#define KeEnterGuardedRegion() \
|
||||
|
@ -49,14 +49,14 @@ KeGetPreviousMode(VOID)
|
|||
{ \
|
||||
/* Sanity checks */ \
|
||||
ASSERT(KeGetCurrentIrql() <= APC_LEVEL); \
|
||||
ASSERT(_Thread == KeGetCurrentThread()); \
|
||||
ASSERT(_Thread->SpecialApcDisable < 0); \
|
||||
ASSERT((_Thread) == KeGetCurrentThread()); \
|
||||
ASSERT((_Thread)->SpecialApcDisable < 0); \
|
||||
\
|
||||
/* Leave region and check if APCs are OK now */ \
|
||||
if (!(++_Thread->SpecialApcDisable)) \
|
||||
if (!(++(_Thread)->SpecialApcDisable)) \
|
||||
{ \
|
||||
/* Check for Kernel APCs on the list */ \
|
||||
if (!IsListEmpty(&_Thread->ApcState. \
|
||||
if (!IsListEmpty(&(_Thread)->ApcState. \
|
||||
ApcListHead[KernelMode])) \
|
||||
{ \
|
||||
/* Check for APC Delivery */ \
|
||||
|
@ -77,12 +77,12 @@ KeGetPreviousMode(VOID)
|
|||
#define KeEnterCriticalRegionThread(_Thread) \
|
||||
{ \
|
||||
/* Sanity checks */ \
|
||||
ASSERT(_Thread == KeGetCurrentThread()); \
|
||||
ASSERT((_Thread->KernelApcDisable <= 0) && \
|
||||
(_Thread->KernelApcDisable != -32768)); \
|
||||
ASSERT((_Thread) == KeGetCurrentThread()); \
|
||||
ASSERT(((_Thread)->KernelApcDisable <= 0) && \
|
||||
((_Thread)->KernelApcDisable != -32768)); \
|
||||
\
|
||||
/* Disable Kernel APCs */ \
|
||||
_Thread->KernelApcDisable--; \
|
||||
(_Thread)->KernelApcDisable--; \
|
||||
}
|
||||
|
||||
#define KeEnterCriticalRegion() \
|
||||
|
@ -97,18 +97,18 @@ KeGetPreviousMode(VOID)
|
|||
#define KeLeaveCriticalRegionThread(_Thread) \
|
||||
{ \
|
||||
/* Sanity checks */ \
|
||||
ASSERT(_Thread == KeGetCurrentThread()); \
|
||||
ASSERT(_Thread->KernelApcDisable < 0); \
|
||||
ASSERT((_Thread) == KeGetCurrentThread()); \
|
||||
ASSERT((_Thread)->KernelApcDisable < 0); \
|
||||
\
|
||||
/* Enable Kernel APCs */ \
|
||||
_Thread->KernelApcDisable++; \
|
||||
(_Thread)->KernelApcDisable++; \
|
||||
\
|
||||
/* Check if Kernel APCs are now enabled */ \
|
||||
if (!(_Thread->KernelApcDisable)) \
|
||||
if (!((_Thread)->KernelApcDisable)) \
|
||||
{ \
|
||||
/* Check if we need to request an APC Delivery */ \
|
||||
if (!(IsListEmpty(&_Thread->ApcState.ApcListHead[KernelMode])) && \
|
||||
!(_Thread->SpecialApcDisable)) \
|
||||
if (!(IsListEmpty(&(_Thread)->ApcState.ApcListHead[KernelMode])) && \
|
||||
!((_Thread)->SpecialApcDisable)) \
|
||||
{ \
|
||||
/* Check for the right environment */ \
|
||||
KiCheckForKernelApcDelivery(); \
|
||||
|
|
Loading…
Reference in a new issue