mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 17:10:22 +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
|
VOID
|
||||||
IopQueueIrpToThread(IN PIRP Irp)
|
IopQueueIrpToThread(IN PIRP Irp)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
PETHREAD Thread = Irp->Tail.Overlay.Thread;
|
||||||
|
|
||||||
/* Raise to APC Level */
|
/* Disable special kernel APCs so we can't race with IopCompleteRequest.
|
||||||
KeRaiseIrql(APC_LEVEL, &OldIrql);
|
* IRP's thread must be the current thread */
|
||||||
|
KeEnterGuardedRegionThread(&Thread->Tcb);
|
||||||
|
|
||||||
/* Insert it into the list */
|
/* Insert it into the list */
|
||||||
InsertHeadList(&Irp->Tail.Overlay.Thread->IrpList, &Irp->ThreadListEntry);
|
InsertHeadList(&Thread->IrpList, &Irp->ThreadListEntry);
|
||||||
|
|
||||||
/* Lower irql */
|
/* Leave the guarded region */
|
||||||
KeLowerIrql(OldIrql);
|
KeLeaveGuardedRegionThread(&Thread->Tcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
IopUnQueueIrpFromThread(IN PIRP Irp)
|
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 */
|
/* Remove it from the list and reset it */
|
||||||
if (IsListEmpty(&Irp->ThreadListEntry))
|
if (IsListEmpty(&Irp->ThreadListEntry))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -28,12 +28,12 @@ KeGetPreviousMode(VOID)
|
||||||
{ \
|
{ \
|
||||||
/* Sanity checks */ \
|
/* Sanity checks */ \
|
||||||
ASSERT(KeGetCurrentIrql() <= APC_LEVEL); \
|
ASSERT(KeGetCurrentIrql() <= APC_LEVEL); \
|
||||||
ASSERT(_Thread == KeGetCurrentThread()); \
|
ASSERT((_Thread) == KeGetCurrentThread()); \
|
||||||
ASSERT((_Thread->SpecialApcDisable <= 0) && \
|
ASSERT(((_Thread)->SpecialApcDisable <= 0) && \
|
||||||
(_Thread->SpecialApcDisable != -32768)); \
|
((_Thread)->SpecialApcDisable != -32768)); \
|
||||||
\
|
\
|
||||||
/* Disable Special APCs */ \
|
/* Disable Special APCs */ \
|
||||||
_Thread->SpecialApcDisable--; \
|
(_Thread)->SpecialApcDisable--; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define KeEnterGuardedRegion() \
|
#define KeEnterGuardedRegion() \
|
||||||
|
@ -49,14 +49,14 @@ KeGetPreviousMode(VOID)
|
||||||
{ \
|
{ \
|
||||||
/* Sanity checks */ \
|
/* Sanity checks */ \
|
||||||
ASSERT(KeGetCurrentIrql() <= APC_LEVEL); \
|
ASSERT(KeGetCurrentIrql() <= APC_LEVEL); \
|
||||||
ASSERT(_Thread == KeGetCurrentThread()); \
|
ASSERT((_Thread) == KeGetCurrentThread()); \
|
||||||
ASSERT(_Thread->SpecialApcDisable < 0); \
|
ASSERT((_Thread)->SpecialApcDisable < 0); \
|
||||||
\
|
\
|
||||||
/* Leave region and check if APCs are OK now */ \
|
/* Leave region and check if APCs are OK now */ \
|
||||||
if (!(++_Thread->SpecialApcDisable)) \
|
if (!(++(_Thread)->SpecialApcDisable)) \
|
||||||
{ \
|
{ \
|
||||||
/* Check for Kernel APCs on the list */ \
|
/* Check for Kernel APCs on the list */ \
|
||||||
if (!IsListEmpty(&_Thread->ApcState. \
|
if (!IsListEmpty(&(_Thread)->ApcState. \
|
||||||
ApcListHead[KernelMode])) \
|
ApcListHead[KernelMode])) \
|
||||||
{ \
|
{ \
|
||||||
/* Check for APC Delivery */ \
|
/* Check for APC Delivery */ \
|
||||||
|
@ -77,12 +77,12 @@ KeGetPreviousMode(VOID)
|
||||||
#define KeEnterCriticalRegionThread(_Thread) \
|
#define KeEnterCriticalRegionThread(_Thread) \
|
||||||
{ \
|
{ \
|
||||||
/* Sanity checks */ \
|
/* Sanity checks */ \
|
||||||
ASSERT(_Thread == KeGetCurrentThread()); \
|
ASSERT((_Thread) == KeGetCurrentThread()); \
|
||||||
ASSERT((_Thread->KernelApcDisable <= 0) && \
|
ASSERT(((_Thread)->KernelApcDisable <= 0) && \
|
||||||
(_Thread->KernelApcDisable != -32768)); \
|
((_Thread)->KernelApcDisable != -32768)); \
|
||||||
\
|
\
|
||||||
/* Disable Kernel APCs */ \
|
/* Disable Kernel APCs */ \
|
||||||
_Thread->KernelApcDisable--; \
|
(_Thread)->KernelApcDisable--; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define KeEnterCriticalRegion() \
|
#define KeEnterCriticalRegion() \
|
||||||
|
@ -97,18 +97,18 @@ KeGetPreviousMode(VOID)
|
||||||
#define KeLeaveCriticalRegionThread(_Thread) \
|
#define KeLeaveCriticalRegionThread(_Thread) \
|
||||||
{ \
|
{ \
|
||||||
/* Sanity checks */ \
|
/* Sanity checks */ \
|
||||||
ASSERT(_Thread == KeGetCurrentThread()); \
|
ASSERT((_Thread) == KeGetCurrentThread()); \
|
||||||
ASSERT(_Thread->KernelApcDisable < 0); \
|
ASSERT((_Thread)->KernelApcDisable < 0); \
|
||||||
\
|
\
|
||||||
/* Enable Kernel APCs */ \
|
/* Enable Kernel APCs */ \
|
||||||
_Thread->KernelApcDisable++; \
|
(_Thread)->KernelApcDisable++; \
|
||||||
\
|
\
|
||||||
/* Check if Kernel APCs are now enabled */ \
|
/* Check if Kernel APCs are now enabled */ \
|
||||||
if (!(_Thread->KernelApcDisable)) \
|
if (!((_Thread)->KernelApcDisable)) \
|
||||||
{ \
|
{ \
|
||||||
/* Check if we need to request an APC Delivery */ \
|
/* Check if we need to request an APC Delivery */ \
|
||||||
if (!(IsListEmpty(&_Thread->ApcState.ApcListHead[KernelMode])) && \
|
if (!(IsListEmpty(&(_Thread)->ApcState.ApcListHead[KernelMode])) && \
|
||||||
!(_Thread->SpecialApcDisable)) \
|
!((_Thread)->SpecialApcDisable)) \
|
||||||
{ \
|
{ \
|
||||||
/* Check for the right environment */ \
|
/* Check for the right environment */ \
|
||||||
KiCheckForKernelApcDelivery(); \
|
KiCheckForKernelApcDelivery(); \
|
||||||
|
|
Loading…
Reference in a new issue