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);