Request the APC_INTERRUPT for the correct processor on smp machines.
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
Modified: trunk/reactos/ntoskrnl/ke/apc.c
Modified: trunk/reactos/ntoskrnl/ke/ipi.c

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
--- trunk/reactos/ntoskrnl/include/internal/ke.h	2005-07-17 18:11:08 UTC (rev 16624)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h	2005-07-17 18:27:46 UTC (rev 16625)
@@ -110,7 +110,7 @@
 		    IN struct _KEXCEPTION_FRAME* ExceptionFrame);
 
 VOID
-KiIpiSendRequest(ULONG TargetSet,
+KiIpiSendRequest(KAFFINITY TargetSet,
 		 ULONG IpiRequest);
 
 VOID

Modified: trunk/reactos/ntoskrnl/ke/apc.c
--- trunk/reactos/ntoskrnl/ke/apc.c	2005-07-17 18:11:08 UTC (rev 16624)
+++ trunk/reactos/ntoskrnl/ke/apc.c	2005-07-17 18:27:46 UTC (rev 16625)
@@ -315,9 +315,39 @@
         /* Check the Thread State */
         if (Thread->State == Running) {
 
-            /* FIXME: Use IPI */
+#ifdef CONFIG_SMP
+            PKPRCB Prcb, CurrentPrcb;
+            LONG i;
+            KIRQL oldIrql;
+#endif
+
             DPRINT ("Requesting APC Interrupt for Running Thread \n");
+
+#ifdef CONFIG_SMP
+            oldIrql = KeRaiseIrqlToDpcLevel();
+            CurrentPrcb = KeGetCurrentPrcb();
+            if (CurrentPrcb->CurrentThread == Thread)
+            {
+               HalRequestSoftwareInterrupt(APC_LEVEL);
+            }
+            else
+            {
+               for (i = 0; i < KeNumberProcessors; i++)
+               {
+                  Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb;
+                  if (Prcb->CurrentThread == Thread)
+                  {
+                     ASSERT (CurrentPrcb != Prcb);
+                     KiIpiSendRequest(Prcb->SetMember, IPI_REQUEST_APC);
+                     break;
+                  }
+               }
+               ASSERT (i < KeNumberProcessors);
+            }
+            KeLowerIrql(oldIrql);
+#else
             HalRequestSoftwareInterrupt(APC_LEVEL);
+#endif
 
         } else if ((Thread->State == Waiting) && (Thread->WaitIrql == PASSIVE_LEVEL) &&
                    ((Apc->NormalRoutine == NULL) ||

Modified: trunk/reactos/ntoskrnl/ke/ipi.c
--- trunk/reactos/ntoskrnl/ke/ipi.c	2005-07-17 18:11:08 UTC (rev 16624)
+++ trunk/reactos/ntoskrnl/ke/ipi.c	2005-07-17 18:27:46 UTC (rev 16625)
@@ -22,14 +22,15 @@
 /* FUNCTIONS *****************************************************************/
 
 VOID
-KiIpiSendRequest(ULONG TargetSet, ULONG IpiRequest)
+KiIpiSendRequest(KAFFINITY TargetSet, ULONG IpiRequest)
 {
    LONG i;
    PKPCR Pcr;
+   KAFFINITY Current;
 
-   for (i = 0; i < KeNumberProcessors; i++)
+   for (i = 0, Current = 1; i < KeNumberProcessors; i++, Current <<= 1)
    {
-      if (TargetSet & (1 << i))
+      if (TargetSet & Current)
       {
          Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
 	 Ke386TestAndSetBit(IpiRequest, &Pcr->Prcb->IpiFrozen);
@@ -116,9 +117,9 @@
 
 VOID
 STDCALL
-KiIpiSendPacket(ULONG TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID Argument, ULONG Count, BOOLEAN Synchronize)
+KiIpiSendPacket(KAFFINITY TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID Argument, ULONG Count, BOOLEAN Synchronize)
 {
-    ULONG Processor, CurrentProcessor;
+    KAFFINITY Processor;
     LONG i;
     PKPRCB Prcb, CurrentPrcb;
     KIRQL oldIrql;
@@ -133,8 +134,6 @@
     InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[1], Count);
     InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[2], Synchronize ? 1 : 0);
 
-    CurrentProcessor = 1 << KeGetCurrentProcessorNumber();
-
     for (i = 0, Processor = 1; i < KeNumberProcessors; i++, Processor <<= 1)
     {
        if (TargetSet & Processor)
@@ -142,13 +141,13 @@
 	  Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb;
 	  while(0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0));
 	  Ke386TestAndSetBit(IPI_REQUEST_FUNCTIONCALL, &Prcb->IpiFrozen);
-	  if (Processor != CurrentProcessor)
+	  if (Processor != CurrentPrcb->SetMember)
 	  {
 	     HalRequestIpi(i);
 	  }
        }
     }
-    if (TargetSet & CurrentProcessor)
+    if (TargetSet & CurrentPrcb->SetMember)
     {
        KeRaiseIrql(IPI_LEVEL, &oldIrql);
        KiIpiServiceRoutine(NULL, NULL);
@@ -160,7 +159,7 @@
 KeIpiGenericCall(VOID (STDCALL *Function)(PVOID), PVOID Argument)
 {
    KIRQL oldIrql;
-   ULONG TargetSet;
+   KAFFINITY TargetSet;
 
    DPRINT("KeIpiGenericCall on CPU%d\n", KeGetCurrentProcessorNumber());