Author: sginsberg Date: Sat Nov 1 13:16:17 2008 New Revision: 37133
URL: http://svn.reactos.org/svn/reactos?rev=37133&view=rev Log: - Implement the MP case for KiTimerExpiration and KiTimerListExpire
Modified: trunk/reactos/ntoskrnl/ke/dpc.c
Modified: trunk/reactos/ntoskrnl/ke/dpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/dpc.c?rev=37133... ============================================================================== --- trunk/reactos/ntoskrnl/ke/dpc.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/dpc.c [iso-8859-1] Sat Nov 1 13:16:17 2008 @@ -92,6 +92,9 @@ ULONG Period; DPC_QUEUE_ENTRY DpcEntry[MAX_TIMER_DPCS]; PKSPIN_LOCK_QUEUE LockQueue; +#ifdef CONFIG_SMP + PKPRCB Prcb = KeGetCurrentPrcb(); +#endif
/* Disable interrupts */ _disable(); @@ -182,19 +185,38 @@ }
/* Check if we have a DPC */ -#ifndef CONFIG_SMP if (TimerDpc) { - /* Setup the DPC Entry */ - DpcEntry[DpcCalls].Dpc = TimerDpc; - DpcEntry[DpcCalls].Routine = TimerDpc->DeferredRoutine; - DpcEntry[DpcCalls].Context = TimerDpc->DeferredContext; - DpcCalls++; - ASSERT(DpcCalls < MAX_TIMER_DPCS); +#ifdef CONFIG_SMP + /* + * If the DPC is targeted to another processor, + * then insert it into that processor's DPC queue + * instead of delivering it now. + * If the DPC is a threaded DPC, and the current CPU + * has threaded DPCs enabled (KiExecuteDpc is actively parsing DPCs), + * then also insert it into the DPC queue for threaded delivery, + * instead of doing it here. + */ + if (((TimerDpc->Number >= MAXIMUM_PROCESSORS) && + ((TimerDpc->Number - MAXIMUM_PROCESSORS) != Prcb->Number)) || + ((TimerDpc->Type == ThreadedDpcObject) && (Prcb->ThreadDpcEnable))) + { + /* Queue it */ + KeInsertQueueDpc(TimerDpc, + UlongToPtr(SystemTime.LowPart), + UlongToPtr(SystemTime.HighPart)); + } + else +#endif + { + /* Setup the DPC Entry */ + DpcEntry[DpcCalls].Dpc = TimerDpc; + DpcEntry[DpcCalls].Routine = TimerDpc->DeferredRoutine; + DpcEntry[DpcCalls].Context = TimerDpc->DeferredContext; + DpcCalls++; + ASSERT(DpcCalls < MAX_TIMER_DPCS); + } } -#else -#error MP Case: Need to check the DPC target CPU so see if we can piggyback -#endif
/* Check if we're done processing */ if (!(ActiveTimers) || !(Timers)) @@ -311,7 +333,10 @@ PKDPC TimerDpc; ULONG Period; DPC_QUEUE_ENTRY DpcEntry[MAX_TIMER_DPCS]; - +#ifdef CONFIG_SMP + PKPRCB Prcb = KeGetCurrentPrcb(); +#endif + /* Query system */ KeQuerySystemTime((PLARGE_INTEGER)&SystemTime);
@@ -357,21 +382,40 @@ Interval.QuadPart = Int32x32To64(Period, -10000); while (!KiInsertTreeTimer(Timer, Interval)); } - + /* Check if we have a DPC */ -#ifndef CONFIG_SMP if (TimerDpc) { - /* Setup the DPC Entry */ - DpcEntry[DpcCalls].Dpc = TimerDpc; - DpcEntry[DpcCalls].Routine = TimerDpc->DeferredRoutine; - DpcEntry[DpcCalls].Context = TimerDpc->DeferredContext; - DpcCalls++; - ASSERT(DpcCalls < MAX_TIMER_DPCS); - } -#else -#error MP Case: Need to check the DPC target CPU so see if we can piggyback +#ifdef CONFIG_SMP + /* + * If the DPC is targeted to another processor, + * then insert it into that processor's DPC queue + * instead of delivering it now. + * If the DPC is a threaded DPC, and the current CPU + * has threaded DPCs enabled (KiExecuteDpc is actively parsing DPCs), + * then also insert it into the DPC queue for threaded delivery, + * instead of doing it here. + */ + if (((TimerDpc->Number >= MAXIMUM_PROCESSORS) && + ((TimerDpc->Number - MAXIMUM_PROCESSORS) != Prcb->Number)) || + ((TimerDpc->Type == ThreadedDpcObject) && (Prcb->ThreadDpcEnable))) + { + /* Queue it */ + KeInsertQueueDpc(TimerDpc, + UlongToPtr(SystemTime.LowPart), + UlongToPtr(SystemTime.HighPart)); + } + else #endif + { + /* Setup the DPC Entry */ + DpcEntry[DpcCalls].Dpc = TimerDpc; + DpcEntry[DpcCalls].Routine = TimerDpc->DeferredRoutine; + DpcEntry[DpcCalls].Context = TimerDpc->DeferredContext; + DpcCalls++; + ASSERT(DpcCalls < MAX_TIMER_DPCS); + } + } }
/* Check if we still have DPC entries */