mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
Make KeFlushQueueApc return a standard cyclic linked list to save a few CPU cycles.
svn path=/trunk/; revision=17408
This commit is contained in:
parent
19f76e91c6
commit
51cbaf1419
2 changed files with 38 additions and 39 deletions
|
@ -469,29 +469,23 @@ KeFlushQueueApc(IN PKTHREAD Thread,
|
|||
{
|
||||
KIRQL OldIrql;
|
||||
PKAPC Apc;
|
||||
PLIST_ENTRY ApcEntry, CurrentEntry;
|
||||
PLIST_ENTRY FirstEntry, CurrentEntry;
|
||||
|
||||
/* Lock the Dispatcher Database and APC Queue */
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
|
||||
|
||||
ApcEntry = CurrentEntry = NULL;
|
||||
while (!IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode]))
|
||||
{
|
||||
if (ApcEntry == NULL)
|
||||
{
|
||||
ApcEntry = CurrentEntry = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentEntry->Flink = RemoveHeadList(&Thread->ApcState.ApcListHead[PreviousMode]);
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
CurrentEntry->Flink = NULL;
|
||||
|
||||
/* Get the APC */
|
||||
Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
|
||||
Apc->Inserted = FALSE;
|
||||
if (IsListEmpty(&Thread->ApcState.ApcListHead[PreviousMode])) {
|
||||
FirstEntry = NULL;
|
||||
} else {
|
||||
FirstEntry = Thread->ApcState.ApcListHead[PreviousMode].Flink;
|
||||
RemoveEntryList(&Thread->ApcState.ApcListHead[PreviousMode]);
|
||||
CurrentEntry = FirstEntry;
|
||||
do {
|
||||
Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
|
||||
Apc->Inserted = FALSE;
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
} while (CurrentEntry != FirstEntry);
|
||||
}
|
||||
|
||||
/* Release the locks */
|
||||
|
@ -499,7 +493,7 @@ KeFlushQueueApc(IN PKTHREAD Thread,
|
|||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
|
||||
/* Return the first entry */
|
||||
return ApcEntry;
|
||||
return FirstEntry;
|
||||
}
|
||||
|
||||
/*++
|
||||
|
|
|
@ -214,7 +214,7 @@ PspExitThread(NTSTATUS ExitStatus)
|
|||
PTERMINATION_PORT TerminationPort;
|
||||
PTEB Teb;
|
||||
KIRQL oldIrql;
|
||||
PLIST_ENTRY ApcEntry;
|
||||
PLIST_ENTRY FirstEntry, CurrentEntry;
|
||||
PKAPC Apc;
|
||||
|
||||
DPRINT("PspExitThread(ExitStatus %x), Current: 0x%x\n", ExitStatus, PsGetCurrentThread());
|
||||
|
@ -340,37 +340,42 @@ PspExitThread(NTSTATUS ExitStatus)
|
|||
KeDisableThreadApcQueueing(&CurrentThread->Tcb);
|
||||
|
||||
/* Flush the User APCs */
|
||||
ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode);
|
||||
while(ApcEntry)
|
||||
FirstEntry = KeFlushQueueApc(&CurrentThread->Tcb, UserMode);
|
||||
if (FirstEntry != NULL)
|
||||
{
|
||||
/* Get the APC */
|
||||
Apc = CONTAINING_RECORD(ApcEntry, KAPC, ApcListEntry);
|
||||
CurrentEntry = FirstEntry;
|
||||
do
|
||||
{
|
||||
/* Get the APC */
|
||||
Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);
|
||||
|
||||
/* Move to the next one */
|
||||
ApcEntry = ApcEntry->Flink;
|
||||
/* Move to the next one */
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
|
||||
/* Rundown the APC or de-allocate it */
|
||||
if (Apc->RundownRoutine)
|
||||
{
|
||||
/* Call its own routine */
|
||||
(Apc->RundownRoutine)(Apc);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do it ourselves */
|
||||
ExFreePool(Apc);
|
||||
}
|
||||
/* Rundown the APC or de-allocate it */
|
||||
if (Apc->RundownRoutine)
|
||||
{
|
||||
/* Call its own routine */
|
||||
(Apc->RundownRoutine)(Apc);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do it ourselves */
|
||||
ExFreePool(Apc);
|
||||
}
|
||||
}
|
||||
while (CurrentEntry != FirstEntry);
|
||||
}
|
||||
|
||||
/* Call the Lego routine */
|
||||
if (CurrentThread->Tcb.LegoData) PspRunLegoRoutine(&CurrentThread->Tcb);
|
||||
|
||||
/* Flush the APC queue, which should be empty */
|
||||
if ((ApcEntry = KeFlushQueueApc(&CurrentThread->Tcb, KernelMode)))
|
||||
if ((FirstEntry = KeFlushQueueApc(&CurrentThread->Tcb, KernelMode)))
|
||||
{
|
||||
/* Bugcheck time */
|
||||
KEBUGCHECKEX(KERNEL_APC_PENDING_DURING_EXIT,
|
||||
(ULONG_PTR)ApcEntry,
|
||||
(ULONG_PTR)FirstEntry,
|
||||
CurrentThread->Tcb.KernelApcDisable,
|
||||
oldIrql,
|
||||
0);
|
||||
|
|
Loading…
Reference in a new issue