Author: ion
Date: Sat Sep 2 23:53:24 2006
New Revision: 23889
URL:
http://svn.reactos.org/svn/reactos?rev=23889&view=rev
Log:
- Part 2 of 2: Implement KiDispatchInterrupt in assembly since it's 1) Perf-critical
2) Requires us to switch the stack to the DPC stack, which is unsafe (and impossible,
unless inlining) in C.
Modified:
trunk/reactos/include/ndk/asm.h
trunk/reactos/ntoskrnl/ke/dpc.c
trunk/reactos/ntoskrnl/ke/i386/trap.s
Modified: trunk/reactos/include/ndk/asm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/asm.h?rev=2388…
==============================================================================
--- trunk/reactos/include/ndk/asm.h (original)
+++ trunk/reactos/include/ndk/asm.h Sat Sep 2 23:53:24 2006
@@ -148,6 +148,7 @@
#define KPCR_SET_MEMBER 0x48
#define KPCR_NUMBER 0x51
#define KPCR_CURRENT_THREAD 0x124
+#define KPCR_PRCB_NEXT_THREAD 0x128
#define KPCR_PRCB_IDLE_THREAD 0x12C
#define KPCR_PROCESSOR_NUMBER 0x130
#define KPCR_PRCB_SET_MEMBER 0x134
@@ -165,12 +166,15 @@
#define KPCR_SYSTEM_CALLS 0x6B8
#define KPCR_PRCB_DPC_QUEUE_DEPTH 0xA4C
#define KPCR_PRCB_DPC_COUNT 0xA50
+#define KPCR_PRCB_DPC_STACK 0xA68
#define KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH 0xA6C
#define KPCR_PRCB_DPC_REQUEST_RATE 0xA70
#define KPCR_PRCB_DPC_INTERRUPT_REQUESTED 0xA78
#define KPCR_PRCB_DPC_ROUTINE_ACTIVE 0xA7A
#define KPCR_PRCB_DPC_LAST_COUNT 0xA80
+#define KPCR_PRCB_TIMER_REQUEST 0xA88
#define KPCR_PRCB_QUANTUM_END 0xAA1
+#define KPCR_PRCB_DEFERRED_READY_LIST_HEAD 0xC10
//
// KINTERRUPT Offsets
Modified: trunk/reactos/ntoskrnl/ke/dpc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/dpc.c?rev=2388…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/dpc.c (original)
+++ trunk/reactos/ntoskrnl/ke/dpc.c Sat Sep 2 23:53:24 2006
@@ -441,9 +441,22 @@
{
PAGED_CODE();
- /* Request an interrupt if needed */
- DPRINT1("%s - FIXME!!!\n", __FUNCTION__);
- if (KeGetCurrentPrcb()->DpcData[0].DpcQueueDepth)
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+ /* Check if this is an UP machine */
+ if (KeActiveProcessors == 1)
+ {
+ /* Check if there are DPCs on either queues */
+ if ((KeGetCurrentPrcb()->DpcData[DPC_NORMAL].DpcQueueDepth) ||
+ (KeGetCurrentPrcb()->DpcData[DPC_THREADED].DpcQueueDepth))
+ {
+ /* Request an interrupt */
+ HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+ }
+ }
+ else
+ {
+ /* FIXME: SMP support required */
+ ASSERT(FALSE);
+ }
}
/*
@@ -483,53 +496,4 @@
Dpc->Number = Number + MAXIMUM_PROCESSORS;
}
-/*
- * @implemented
- */
-VOID
-NTAPI
-KiDispatchInterrupt(VOID)
-{
- PKIPCR Pcr = (PKIPCR)KeGetPcr();
- PVOID ExceptionList;
-
- /* Disable interrupts */
- Ke386DisableInterrupts();
-
- /* Check if we have to deliver DPCs, timers, or deferred threads */
- if ((Pcr->PrcbData.DpcData[DPC_NORMAL].DpcQueueDepth) ||
- (Pcr->PrcbData.TimerRequest) ||
- (Pcr->PrcbData.DeferredReadyListHead.Next))
- {
- /* Save the exception list and clear it */
- ExceptionList = Pcr->NtTib.ExceptionList;
- Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
-
- /* FIXME: Switch to DPC Stack */
-
- /* Deliver DPCs */
- KiRetireDpcList(Pcr->Prcb);
-
- /* FIXME: Restore stack */
-
- /* Restore exception list */
- Pcr->NtTib.ExceptionList = ExceptionList;
- }
-
- /* Re-enable interrupts */
- Ke386EnableInterrupts();
-
- /* Check if we have quantum end */
- if (Pcr->PrcbData.QuantumEnd)
- {
- /* Process it */
- Pcr->PrcbData.QuantumEnd = FALSE;
- KiQuantumEnd();
- }
- else if (Pcr->PrcbData.NextThread)
- {
- /* FIXME: Schedule new thread */
- }
-}
-
/* EOF */
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s Sat Sep 2 23:53:24 2006
@@ -56,6 +56,7 @@
.globl _NtRaiseException@12
.globl _NtContinue@8
.globl _KiCoprocessorError@0
+.globl _KiDispatchInterrupt@0
/* Interrupt template entrypoints */
.globl _KiInterruptTemplate
@@ -1558,6 +1559,65 @@
/* INTERRUPT HANDLERS ********************************************************/
+.func KiDispatchInterrupt@0
+_KiDispatchInterrupt@0:
+
+ /* Get the PCR and disable interrupts */
+ mov ebx, [fs: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]
+ call @KiRetireDpcList@4
+
+ /* Restore stack and exception list */
+ pop esp
+ pop dword ptr [ebx]
+ 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
+ jz Return
+
+ /* FIXME: Schedule new thread */
+ int 3
+
+Return:
+ /* All done */
+ ret
+
+QuantumEnd:
+ /* Disable quantum end and process it */
+ mov byte ptr [ebx+KPCR_PRCB_QUANTUM_END], 0
+ call _KiQuantumEnd@0
+ ret
+.endfunc
+
.func KiInterruptTemplate
_KiInterruptTemplate: