[ros-diffs] [ros-arm-bringup] 34088: - Save and restore the trap frame for the current thread when we take an interrupt, so that ISRs can read it. - We use this in the clock ISR, that can now actually send the trap frame to KeUpdateSystemTime. - Implement KeUpdateRunTime to handle time accounting and DPC rescheduling as well as Quantum End. - Ignore quantum end for now. - We now have a working timebase, and we're back to our earlier checkpoint around CmInitSystem1!.

ros-arm-bringup at svn.reactos.org ros-arm-bringup at svn.reactos.org
Thu Jun 26 07:56:35 CEST 2008


Author: ros-arm-bringup
Date: Thu Jun 26 00:56:35 2008
New Revision: 34088

URL: http://svn.reactos.org/svn/reactos?rev=34088&view=rev
Log:
- Save and restore the trap frame for the current thread when we take an interrupt, so that ISRs can read it.
- We use this in the clock ISR, that can now actually send the trap frame to KeUpdateSystemTime.
- Implement KeUpdateRunTime to handle time accounting and DPC rescheduling as well as Quantum End.
- Ignore quantum end for now.
- We now have a working timebase, and we're back to our earlier checkpoint around CmInitSystem1!.


Modified:
    trunk/reactos/hal/halarm/generic/hal.c
    trunk/reactos/ntoskrnl/ke/arm/stubs.c
    trunk/reactos/ntoskrnl/ke/arm/trapc.c

Modified: trunk/reactos/hal/halarm/generic/hal.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halarm/generic/hal.c?rev=34088&r1=34087&r2=34088&view=diff
==============================================================================
--- trunk/reactos/hal/halarm/generic/hal.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halarm/generic/hal.c [iso-8859-1] Thu Jun 26 00:56:35 2008
@@ -485,7 +485,9 @@
     //
     // Call the kernel
     //
-    KeUpdateSystemTime(NULL, CLOCK2_LEVEL, HalpCurrentTimeIncrement);
+    KeUpdateSystemTime(KeGetCurrentThread()->TrapFrame,
+                       CLOCK2_LEVEL,
+                       HalpCurrentTimeIncrement);
     
     //
     // We're done

Modified: trunk/reactos/ntoskrnl/ke/arm/stubs.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/stubs.c?rev=34088&r1=34087&r2=34088&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/arm/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/arm/stubs.c [iso-8859-1] Thu Jun 26 00:56:35 2008
@@ -39,10 +39,6 @@
     PKPRCB Prcb = KeGetPcr()->Prcb;
     ULARGE_INTEGER SystemTime, InterruptTime;
     ULONG Hand;
-    DPRINT1("TIMEBASE: %I64d %I64d %I64d\n",
-            *(PLARGE_INTEGER)&SharedUserData->InterruptTime,
-            *(PLARGE_INTEGER)&SharedUserData->SystemTime,
-            *(PLARGE_INTEGER)&SharedUserData->TickCount);
     
     //
     // Do nothing if this tick is being skipped
@@ -143,7 +139,7 @@
         //
         // Update system runtime
         //
-        KeUpdateRunTime(NULL, CLOCK2_LEVEL);
+        KeUpdateRunTime(TrapFrame, CLOCK2_LEVEL);
     }
     else
     {
@@ -159,6 +155,138 @@
 KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
                 IN KIRQL Irql)
 {
-    UNIMPLEMENTED;
-    while (TRUE);  
+    PKTHREAD Thread = KeGetCurrentThread();
+    PKPROCESS Process = Thread->ApcState.Process;
+    PKPRCB Prcb = KeGetCurrentPrcb();
+
+    //
+    // Do nothing if this tick is being skipped
+    //
+    if (Prcb->SkipTick)
+    {
+        //
+        // Handle it next time
+        //
+        Prcb->SkipTick = FALSE;
+        return;
+    }
+
+    //
+    // Increase interrupt count
+    //
+    Prcb->InterruptCount++;
+    
+    //
+    // Check if we came from user mode
+    //
+    if (0) //(TrapFrame->PreviousMode != KernelMode)
+    {
+        //
+        // Increase process user time
+        //
+        InterlockedIncrement((PLONG)&Process->UserTime);
+        Prcb->UserTime++;
+        Thread->UserTime++;
+    }
+    else
+    {
+        //
+        // See if we were in an ISR
+        //
+        if (TrapFrame->OldIrql > DISPATCH_LEVEL)
+        {
+            //
+            // Handle that
+            //
+            Prcb->InterruptTime++;
+        }
+        else if ((TrapFrame->OldIrql < DISPATCH_LEVEL) ||
+                 !(Prcb->DpcRoutineActive))
+        {
+            //
+            // Handle being in kernel mode
+            //
+            Thread->KernelTime++;
+            InterlockedIncrement((PLONG)&Process->KernelTime);
+        }
+        else
+        {
+            //
+            // Handle being in a DPC
+            //
+            Prcb->DpcTime++;
+            
+            //
+            // FIXME: Handle DPC checks
+            //
+        }
+    }
+    
+    //
+    // Update DPC rates
+    //
+    Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) +
+                            Prcb->DpcRequestRate) >> 1;
+    Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount;
+    
+    //
+    // Check if the queue is large enough
+    //
+    if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive))
+    {
+        //
+        // Request a DPC
+        //
+        Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
+        HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+        
+        //
+        // Fix the maximum queue depth
+        //
+        if ((Prcb->DpcRequestRate < KiIdealDpcRate) &&
+            (Prcb->MaximumDpcQueueDepth > 1))
+        {
+            //
+            // Make it smaller
+            //
+            Prcb->MaximumDpcQueueDepth--;
+        }
+    }
+    else
+    {
+        //
+        // Check if we've reached the adjustment limit
+        //
+        if (!(--Prcb->AdjustDpcThreshold))
+        {
+            //
+            // Reset it, and check the queue maximum
+            //
+            Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
+            if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth)
+            {
+                //
+                // Increase it
+                //
+                Prcb->MaximumDpcQueueDepth++;
+            }
+        }
+    }
+    
+    //
+    // Decrement the thread quantum
+    //
+    Thread->Quantum -= CLOCK_QUANTUM_DECREMENT;
+    
+    //
+    // Check if the time expired
+    //
+    if ((Thread->Quantum <= 0) && (Thread != Prcb->IdleThread))
+    {
+        //
+        // Schedule a quantum end
+        //
+        Prcb->QuantumEnd = 1;
+        //HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+    }
 }

Modified: trunk/reactos/ntoskrnl/ke/arm/trapc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trapc.c?rev=34088&r1=34087&r2=34088&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] Thu Jun 26 00:56:35 2008
@@ -310,6 +310,7 @@
     KIRQL OldIrql, Irql;
     ULONG InterruptCause, InterruptMask;
     PKPCR Pcr;
+    PKTRAP_FRAME OldTrapFrame;
 
     //
     // Increment interrupt count
@@ -339,12 +340,18 @@
     // Raise to the new IRQL
     //
     KfRaiseIrql(Irql);
+    
+    //
+    // The clock ISR wants the trap frame as a parameter
+    //
+    OldTrapFrame = KeGetCurrentThread()->TrapFrame;
+    KeGetCurrentThread()->TrapFrame = TrapFrame;
 
     //
     // Check if this interrupt is at DISPATCH or higher
     //
     if (Irql > DISPATCH_LEVEL)
-    {        
+    {   
         //
         // FIXME: Switch to interrupt stack
         //
@@ -358,11 +365,13 @@
         //DPRINT1("[DPC/APC]\n");
         HalClearSoftwareInterrupt(Irql);
     }
-        
+
     //
     // Call the registered interrupt routine
     //
     Pcr->InterruptRoutine[Irql]();
+    ASSERT(KeGetCurrentThread()->TrapFrame == TrapFrame);
+    KeGetCurrentThread()->TrapFrame = OldTrapFrame;
 //    DPRINT1("[ISR RETURN]\n");
     
     //



More information about the Ros-diffs mailing list