[ros-diffs] [sir_richard] 49521: [NTOS]: KiDispatchInterrupt (the DPC handler) in C, instead of ASM.

sir_richard at svn.reactos.org sir_richard at svn.reactos.org
Mon Nov 8 02:37:17 UTC 2010


Author: sir_richard
Date: Mon Nov  8 02:37:17 2010
New Revision: 49521

URL: http://svn.reactos.org/svn/reactos?rev=49521&view=rev
Log:
[NTOS]: KiDispatchInterrupt (the DPC handler) in C, instead of ASM.

Modified:
    trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
    trunk/reactos/ntoskrnl/ke/i386/thrdini.c

Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S?rev=49521&r1=49520&r2=49521&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S [iso-8859-1] Mon Nov  8 02:37:17 2010
@@ -112,121 +112,18 @@
     ret
 .endfunc
 
-/* DPC INTERRUPT HANDLER ******************************************************/
+.globl @KiRetireDpcListInDpcStack at 8
+.func @KiRetireDpcListInDpcStack at 8, @KiRetireDpcListInDpcStack at 8
+ at KiRetireDpcListInDpcStack@8:
 
-.globl _KiDispatchInterrupt at 0
-.func KiDispatchInterrupt at 0
-_KiDispatchInterrupt at 0:
-
-    /* Preserve EBX */
-    push ebx
-
-    /* Get the PCR  and disable interrupts */
-    mov ebx, PCR[KPCR_SELF]
-    cli
-
-    /* Check if we have to deliver DPCs, timers, or deferred threads */
-    mov eax, [ebx+KPCR_PRCB_DPC_QUEUE_DEPTH]
-    or eax, [ebx+KPCR_PRCB_TIMER_REQUEST]
-    or eax, [ebx+KPCR_PRCB_DEFERRED_READY_LIST_HEAD]
-    jz CheckQuantum
-
-    /* Save stack pointer and exception list, then clear it */
-    push ebp
-    push dword ptr [ebx+KPCR_EXCEPTION_LIST]
-    mov dword ptr [ebx+KPCR_EXCEPTION_LIST], -1
-
-    /* Save the stack and switch to the DPC Stack */
-    mov edx, esp
-    mov esp, [ebx+KPCR_PRCB_DPC_STACK]
-    push edx
-
-    /* Deliver DPCs */
-    mov ecx, [ebx+KPCR_PRCB]
+    /* Switch stacks and retire DPCs */
+    mov eax, esp
+    mov esp, edx
+    push eax
     call @KiRetireDpcList at 4
 
-    /* Restore stack and exception list */
+    /* Return on original stack */
     pop esp
-    pop dword ptr [ebx+KPCR_EXCEPTION_LIST]
-    pop ebp
-
-CheckQuantum:
-
-    /* Re-enable interrupts */
-    sti
-
-    /* Check if we have quantum end */
-    cmp byte ptr [ebx+KPCR_PRCB_QUANTUM_END], 0
-    jnz QuantumEnd
-
-    /* Check if we have a thread to swap to */
-    cmp byte ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
-    je Return
-
-    /* Make space on the stack to save registers */
-    sub esp, 3 * 4
-    mov [esp+8], esi
-    mov [esp+4], edi
-    mov [esp+0], ebp
-
-    /* Get the current thread */
-    mov edi, [ebx+KPCR_CURRENT_THREAD]
-
-#ifdef CONFIG_SMP
-    /* Raise to synch level */
-    call _KeRaiseIrqlToSynchLevel at 0
-
-    /* Set context swap busy */
-    mov byte ptr [edi+KTHREAD_SWAP_BUSY], 1
-
-    /* Acquire the PRCB Lock */
-    lock bts dword ptr [ebx+KPCR_PRCB_PRCB_LOCK], 0
-    jnb GetNext
-    lea ecx, [ebx+KPCR_PRCB_PRCB_LOCK]
-    call @KefAcquireSpinLockAtDpcLevel at 4
-#endif
-
-GetNext:
-    /* Get the next thread and clear it */
-    mov esi, [ebx+KPCR_PRCB_NEXT_THREAD]
-    and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
-
-    /* Set us as the current running thread */
-    mov [ebx+KPCR_CURRENT_THREAD], esi
-    mov byte ptr [esi+KTHREAD_STATE_], Running
-    mov byte ptr [edi+KTHREAD_WAIT_REASON], WrDispatchInt
-
-    /* Put thread in ECX and get the PRCB in EDX */
-    mov ecx, edi
-    lea edx, [ebx+KPCR_PRCB_DATA]
-    call @KiQueueReadyThread at 8
-
-    /* Set APC_LEVEL and do the swap */
-    mov cl, APC_LEVEL
-    call @KiSwapContextInternal at 0
-
-#ifdef CONFIG_SMP
-    /* Lower IRQL back to dispatch */
-    mov cl, DISPATCH_LEVEL
-    call @KfLowerIrql at 4
-#endif
-
-    /* Restore registers */
-    mov ebp, [esp+0]
-    mov edi, [esp+4]
-    mov esi, [esp+8]
-    add esp, 3*4
-
-Return:
-    /* All done */
-    pop ebx
-    ret
-
-QuantumEnd:
-    /* Disable quantum end and process it */
-    mov byte ptr [ebx+KPCR_PRCB_QUANTUM_END], 0
-    call _KiQuantumEnd at 0
-    pop ebx
     ret
 .endfunc
 

Modified: trunk/reactos/ntoskrnl/ke/i386/thrdini.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/thrdini.c?rev=49521&r1=49520&r2=49521&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/thrdini.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/thrdini.c [iso-8859-1] Mon Nov  8 02:37:17 2010
@@ -47,6 +47,13 @@
 KiSwitchThreads(
     IN PKTHREAD OldThread,
     IN PKTHREAD NewThread
+);
+
+VOID
+FASTCALL
+KiRetireDpcListInDpcStack(
+    IN PKPRCB Prcb,
+    IN PVOID DpcStack
 );
 
 /* FUNCTIONS *****************************************************************/
@@ -447,4 +454,65 @@
     KiSwitchThreads(OldThread, NewThread);
 }
 
+VOID
+NTAPI
+KiDispatchInterrupt(VOID)
+{
+    PKIPCR Pcr = (PKIPCR)KeGetPcr();
+    PKPRCB Prcb = &Pcr->PrcbData;
+    PVOID OldHandler;
+    PKTHREAD NewThread, OldThread;
+    
+    /* Disable interrupts */
+    _disable();
+    
+    /* Check for pending timers, pending DPCs, or pending ready threads */
+    if ((Prcb->DpcData[0].DpcQueueDepth) ||
+        (Prcb->TimerRequest) ||
+        (Prcb->DeferredReadyListHead.Next))
+    {
+        /* Switch to safe execution context */
+        OldHandler = Pcr->NtTib.ExceptionList;
+        Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
+        
+        /* Retire DPCs while under the DPC stack */
+        KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack);
+        
+        /* Restore context */
+        Pcr->NtTib.ExceptionList = OldHandler;
+    }
+    
+    /* Re-enable interrupts */
+    _enable();
+    
+    /* Check for quantum end */
+    if (Prcb->QuantumEnd)
+    {
+        /* Handle quantum end */
+        Prcb->QuantumEnd = FALSE;
+        KiQuantumEnd();
+    }
+    else if (Prcb->NextThread)
+    {       
+        /* Capture current thread data */
+        OldThread = Prcb->CurrentThread;
+        NewThread = Prcb->NextThread;
+    
+        /* Set new thread data */
+        Prcb->NextThread = NULL;
+        Prcb->CurrentThread = NewThread;
+    
+        /* The thread is now running */
+        NewThread->State = Running;
+        OldThread->WaitReason = WrDispatchInt;
+        
+        /* Make the old thread ready */
+        KxQueueReadyThread(OldThread, Prcb);
+        
+        /* Swap to the new thread. FIXME: APC Bypass */
+        KiSwapContext(OldThread, NewThread);
+    }
+}
+
+
 /* EOF */




More information about the Ros-diffs mailing list