[ros-diffs] [sginsberg] 37133: - Implement the MP case for KiTimerExpiration and KiTimerListExpire

sginsberg at svn.reactos.org sginsberg at svn.reactos.org
Sat Nov 1 19:16:17 CET 2008


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&r1=37132&r2=37133&view=diff
==============================================================================
--- 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 */



More information about the Ros-diffs mailing list