Make KeFlushQueueApc return a standard cyclic linked list to save a few
CPU cycles.
Modified: trunk/reactos/ntoskrnl/ke/apc.c
Modified: trunk/reactos/ntoskrnl/ps/kill.c
_____
Modified: trunk/reactos/ntoskrnl/ke/apc.c
--- trunk/reactos/ntoskrnl/ke/apc.c 2005-08-15 22:44:32 UTC (rev
17407)
+++ trunk/reactos/ntoskrnl/ke/apc.c 2005-08-16 00:01:42 UTC (rev
17408)
@@ -469,29 +469,23 @@
{
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 @@
KeReleaseDispatcherDatabaseLock(OldIrql);
/* Return the first entry */
- return ApcEntry;
+ return FirstEntry;
}
/*++
_____
Modified: trunk/reactos/ntoskrnl/ps/kill.c
--- trunk/reactos/ntoskrnl/ps/kill.c 2005-08-15 22:44:32 UTC (rev
17407)
+++ trunk/reactos/ntoskrnl/ps/kill.c 2005-08-16 00:01:42 UTC (rev
17408)
@@ -214,7 +214,7 @@
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 @@
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);