diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 379bee14d50..cc0419312cb 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -110,7 +110,7 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, IN struct _KEXCEPTION_FRAME* ExceptionFrame); VOID -KiIpiSendRequest(ULONG TargetSet, +KiIpiSendRequest(KAFFINITY TargetSet, ULONG IpiRequest); VOID diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index b76c82af0f8..242c4248d41 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -315,9 +315,39 @@ KiInsertQueueApc(PKAPC Apc, /* 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) || diff --git a/reactos/ntoskrnl/ke/ipi.c b/reactos/ntoskrnl/ke/ipi.c index 4c01fbe8b0f..2fb603ddb0e 100644 --- a/reactos/ntoskrnl/ke/ipi.c +++ b/reactos/ntoskrnl/ke/ipi.c @@ -22,14 +22,15 @@ KSPIN_LOCK KiIpiLock; /* 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 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, 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 @@ KiIpiSendPacket(ULONG TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID Argu 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 @@ KiIpiSendPacket(ULONG TargetSet, VOID (STDCALL*WorkerRoutine)(PVOID), PVOID Argu 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 @@ VOID KeIpiGenericCall(VOID (STDCALL *Function)(PVOID), PVOID Argument) { KIRQL oldIrql; - ULONG TargetSet; + KAFFINITY TargetSet; DPRINT("KeIpiGenericCall on CPU%d\n", KeGetCurrentProcessorNumber());