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=23889... ============================================================================== --- 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=23889... ============================================================================== --- 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?rev... ============================================================================== --- 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: