Alex Ionescu ionucu@videotron.ca - Fixed formatting mess in ke/dpc.c (which I had made when I wrote it due to MSVC). - Add more comments where needed. - Properly Initialize a Threaded DPC.
Thomas Weidenmueller w3seek@reactos.com - Use Prcb directly in KeInitDpc. Modified: trunk/reactos/ntoskrnl/include/internal/ke.h Modified: trunk/reactos/ntoskrnl/ke/dpc.c Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c _____
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h --- trunk/reactos/ntoskrnl/include/internal/ke.h 2005-03-12 19:23:04 UTC (rev 13974) +++ trunk/reactos/ntoskrnl/include/internal/ke.h 2005-03-12 19:45:37 UTC (rev 13975) @@ -41,6 +41,7 @@
struct _KTHREAD; struct _KIRQ_TRAPFRAME; struct _KPCR; +struct _KPRCB; struct _KEXCEPTION_FRAME;
#define IPI_REQUEST_FUNCTIONCALL 0 @@ -192,7 +193,7 @@ VOID KeInitExceptions(VOID); VOID KeInitInterrupts(VOID); VOID KeInitTimer(VOID); -VOID KeInitDpc(struct _KPCR* Pcr); +VOID KeInitDpc(struct _KPRCB* Prcb); VOID KeInitDispatcher(VOID); VOID KeInitializeDispatcher(VOID); VOID KiInitializeSystemClock(VOID); _____
Modified: trunk/reactos/ntoskrnl/ke/dpc.c --- trunk/reactos/ntoskrnl/ke/dpc.c 2005-03-12 19:23:04 UTC (rev 13974) +++ trunk/reactos/ntoskrnl/ke/dpc.c 2005-03-12 19:45:37 UTC (rev 13975) @@ -24,22 +24,22 @@
/* TYPES *******************************************************************/
#define MAX_QUANTUM 0x7F -/* GLOBALS ******************************************************************/
/* FUNCTIONS ****************************************************************/
-VOID INIT_FUNCTION -KeInitDpc(PKPCR Pcr) /* * FUNCTION: Initialize DPC handling */ +VOID +INIT_FUNCTION +KeInitDpc(PKPRCB Prcb) { - InitializeListHead(&Pcr->PrcbData.DpcData[0].DpcListHead); - KeInitializeEvent(Pcr->PrcbData.DpcEvent, 0, 0); - KeInitializeSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); - Pcr->PrcbData.MaximumDpcQueueDepth = 4; - Pcr->PrcbData.MinimumDpcRate = 3; - Pcr->PrcbData.DpcData[0].DpcQueueDepth = 0; + InitializeListHead(&Prcb->DpcData[0].DpcListHead); + KeInitializeEvent(Prcb->DpcEvent, 0, 0); + KeInitializeSpinLock(&Prcb->DpcData[0].DpcLock); + Prcb->MaximumDpcQueueDepth = 4; + Prcb->MinimumDpcRate = 3; + Prcb->DpcData[0].DpcQueueDepth = 0; }
/* @@ -47,9 +47,9 @@ */ VOID STDCALL -KeInitializeThreadedDpc(PKDPC Dpc, - PKDEFERRED_ROUTINE DeferredRoutine, - PVOID DeferredContext) +KeInitializeThreadedDpc(PKDPC Dpc, + PKDEFERRED_ROUTINE DeferredRoutine, + PVOID DeferredContext) /* * FUNCTION: * Initalizes a Threaded DPC and registers the DeferredRoutine for it. @@ -60,24 +60,18 @@ * NOTE: Callers can be running at any IRQL. */ { - DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine); - //Dpc->Type = KThreadedDpc; - Dpc->Number= 0; - Dpc->Importance= MediumImportance; - Dpc->DeferredRoutine = DeferredRoutine; - Dpc->DeferredContext = DeferredContext; - Dpc->DpcData = NULL; + DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine); + Dpc->Type = ThreadedDpcObject; + Dpc->Number= 0; + Dpc->Importance= MediumImportance; + Dpc->DeferredRoutine = DeferredRoutine; + Dpc->DeferredContext = DeferredContext; + Dpc->DpcData = NULL; }
/* * @implemented - */ -VOID -STDCALL -KeInitializeDpc (PKDPC Dpc, - PKDEFERRED_ROUTINE DeferredRoutine, - PVOID DeferredContext) -/* + * * FUNCTION: * Initalizes a DPC and registers the DeferredRoutine for it. * ARGUMENTS: @@ -86,24 +80,24 @@ * DeferredContext = Parameter to be passed to the callback routine. * NOTE: Callers can be running at any IRQL. */ +VOID +STDCALL +KeInitializeDpc(PKDPC Dpc, + PKDEFERRED_ROUTINE DeferredRoutine, + PVOID DeferredContext) { - DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine); - Dpc->Type = DpcObject; - Dpc->Number= 0; - Dpc->Importance= MediumImportance; - Dpc->DeferredRoutine = DeferredRoutine; - Dpc->DeferredContext = DeferredContext; - Dpc->DpcData = NULL; + DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine); + Dpc->Type = DpcObject; + Dpc->Number= 0; + Dpc->Importance= MediumImportance; + Dpc->DeferredRoutine = DeferredRoutine; + Dpc->DeferredContext = DeferredContext; + Dpc->DpcData = NULL; }
/* * @implemented - */ -BOOLEAN STDCALL -KeInsertQueueDpc (PKDPC Dpc, - PVOID SystemArgument1, - PVOID SystemArgument2) -/* + * * FUNCTION: * Queues a DPC for execution when the IRQL of a processor * drops below DISPATCH_LEVEL @@ -155,124 +149,141 @@ * is greater that the target depth or the minimum DPC rate is less than the * target rate. */ +BOOLEAN +STDCALL +KeInsertQueueDpc(PKDPC Dpc, + PVOID SystemArgument1, + PVOID SystemArgument2) { - KIRQL OldIrql; - PKPCR Pcr; + KIRQL OldIrql; + PKPRCB Prcb;
- DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n", - Dpc, SystemArgument1, SystemArgument2); + DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n", + Dpc, SystemArgument1, SystemArgument2);
- /* Check IRQL and Raise it to HIGH_LEVEL */ - ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL); - KeRaiseIrql(HIGH_LEVEL, &OldIrql); - - /* Check if this is a Thread DPC, which we don't support (yet) */ - //if (Dpc->Type == KThreadedDpc) { - // return FALSE; - // KeLowerIrql(OldIrql); - //} + /* Check IRQL and Raise it to HIGH_LEVEL */ + ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL); + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + + /* Check if this is a Thread DPC, which we don't support (yet) */ + if (Dpc->Type == ThreadedDpcObject) { + return FALSE; + KeLowerIrql(OldIrql); + }
#ifdef CONFIG_SMP - /* Get the right PCR for this CPU */ - if (Dpc->Number >= MAXIMUM_PROCESSORS) { - ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors); - Pcr = (PKPCR)(KPCR_BASE + (Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE); - } else { - ASSERT (Dpc->Number < KeNumberProcessors); - Pcr = KeGetCurrentKPCR(); - Dpc->Number = KeGetCurrentProcessorNumber(); - } - KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + /* Get the right PCR for this CPU */ + if (Dpc->Number >= MAXIMUM_PROCESSORS) { + + ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors); + Prcb = ((PKPCR)((ULONG_PTR)KPCR_BASE + ((Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE)))->Prcb; + + } else { + + ASSERT (Dpc->Number < KeNumberProcessors); + Prcb = KeGetCurrentPrcb(); + Dpc->Number = KeGetCurrentProcessorNumber(); + } + + KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock); #else - Pcr = (PKPCR)KPCR_BASE; + Prcb = ((PKPCR)KPCR_BASE)->Prcb; #endif
- /* Get the DPC Data */ - if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Pcr->PrcbData.DpcData[0].DpcLock, 0)) { - DPRINT("DPC Already Inserted"); + /* Get the DPC Data */ + if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Prcb->DpcData[0].DpcLock, 0)) { + + DPRINT("DPC Already Inserted"); #ifdef CONFIG_SMP - KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock); #endif - KeLowerIrql(OldIrql); - return(FALSE); - } - - /* Make sure the lists are free if the Queue is 0 */ - if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0) { - ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)); - } else { - ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)); - } + KeLowerIrql(OldIrql); + return(FALSE); + } + + /* Make sure the lists are free if the Queue is 0 */ + if (Prcb->DpcData[0].DpcQueueDepth == 0) { + + ASSERT(IsListEmpty(&Prcb->DpcData[0].DpcListHead)); + } else { + + ASSERT(!IsListEmpty(&Prcb->DpcData[0].DpcListHead)); + }
- /* Now we can play with the DPC safely */ - Dpc->SystemArgument1=SystemArgument1; - Dpc->SystemArgument2=SystemArgument2; - Pcr->PrcbData.DpcData[0].DpcQueueDepth++; - Pcr->PrcbData.DpcData[0].DpcCount++; - - /* Insert the DPC into the list. HighImportance DPCs go at the beginning */ - if (Dpc->Importance == HighImportance) { - InsertHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry); - } else { - InsertTailList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry); - } - DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink); + /* Now we can play with the DPC safely */ + Dpc->SystemArgument1=SystemArgument1; + Dpc->SystemArgument2=SystemArgument2; + Prcb->DpcData[0].DpcQueueDepth++; + Prcb->DpcData[0].DpcCount++; + + /* Insert the DPC into the list. HighImportance DPCs go at the beginning */ + if (Dpc->Importance == HighImportance) { + + InsertHeadList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry); + } else { + + InsertTailList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry); + } + DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
- /* Make sure a DPC isn't executing already and respect rules outlined above. */ - if ((!Pcr->PrcbData.DpcRoutineActive) && (!Pcr->PrcbData.DpcInterruptRequested)) { - -#ifdef CONFIG_SMP - /* Check if this is the same CPU */ - if (Pcr != KeGetCurrentKPCR()) { - /* Send IPI if High Importance */ - if ((Dpc->Importance == HighImportance) || - (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth)) { - if (Dpc->Number >= MAXIMUM_PROCESSORS) { - KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC); - } else { - KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC); - } + /* Make sure a DPC isn't executing already and respect rules outlined above. */ + if ((!Prcb->DpcRoutineActive) && (!Prcb->DpcInterruptRequested)) { + +#ifdef CONFIG_SMP + /* Check if this is the same CPU */ + if (Prcb != KeGetCurrentPrcb()) { + + /* Send IPI if High Importance */ + if ((Dpc->Importance == HighImportance) || + (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth)) { + + if (Dpc->Number >= MAXIMUM_PROCESSORS) { + + KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC); + } else { + + KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC); + }
- } - } else { - /* Request an Interrupt only if the DPC isn't low priority */ - if ((Dpc->Importance != LowImportance) || - (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) || - (Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) { - - /* Request Interrupt */ - HalRequestSoftwareInterrupt(DISPATCH_LEVEL); - Pcr->PrcbData.DpcInterruptRequested = TRUE; - } - } + } + } else { + + /* Request an Interrupt only if the DPC isn't low priority */ + if ((Dpc->Importance != LowImportance) || + (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) || + (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) { + + /* Request Interrupt */ + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + Prcb->DpcInterruptRequested = TRUE; + } + } #else - DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Pcr->PrcbData.DpcData[0].DpcQueueDepth, Pcr->PrcbData.MaximumDpcQueueDepth, Pcr->PrcbData.DpcRequestRate, Pcr->PrcbData.MinimumDpcRate); - /* Request an Interrupt only if the DPC isn't low priority */ - if ((Dpc->Importance != LowImportance) || - (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) || - (Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) { - - /* Request Interrupt */ - DPRINT("Requesting Interrupt\n"); - HalRequestSoftwareInterrupt(DISPATCH_LEVEL); - Pcr->PrcbData.DpcInterruptRequested = TRUE; - } + DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Prcb->DpcData[0].DpcQueueDepth, Prcb->MaximumDpcQueueDepth, Prcb->DpcRequestRate, Prcb->MinimumDpcRate); + + /* Request an Interrupt only if the DPC isn't low priority */ + if ((Dpc->Importance != LowImportance) || + (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) || + (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) { + + /* Request Interrupt */ + DPRINT("Requesting Interrupt\n"); + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + Prcb->DpcInterruptRequested = TRUE; + } #endif - } + } #ifdef CONFIG_SMP - KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock); #endif - /* Lower IRQL */ - KeLowerIrql(OldIrql); - return(TRUE); + /* Lower IRQL */ + KeLowerIrql(OldIrql); + return(TRUE); }
/* * @implemented - */ -BOOLEAN STDCALL -KeRemoveQueueDpc (PKDPC Dpc) -/* + * * FUNCTION: * Removes DPC object from the system dpc queue * ARGUMENTS: @@ -281,33 +292,36 @@ * TRUE if the DPC was in the queue * FALSE otherwise */ +BOOLEAN +STDCALL +KeRemoveQueueDpc(PKDPC Dpc) { - BOOLEAN WasInQueue; - KIRQL OldIrql; - - /* Raise IRQL */ - DPRINT("Removing DPC: %x\n", Dpc); - KeRaiseIrql(HIGH_LEVEL, &OldIrql); + BOOLEAN WasInQueue; + KIRQL OldIrql; + + /* Raise IRQL */ + DPRINT("Removing DPC: %x\n", Dpc); + KeRaiseIrql(HIGH_LEVEL, &OldIrql); #ifdef CONFIG_SMP - KiAcquireSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock); + KiAcquireSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock); #endif - - /* First make sure the DPC lock isn't being held */ - WasInQueue = Dpc->DpcData ? TRUE : FALSE; - if (Dpc->DpcData) { - - /* Remove the DPC */ - ((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--; - RemoveEntryList(&Dpc->DpcListEntry); + + /* First make sure the DPC lock isn't being held */ + WasInQueue = Dpc->DpcData ? TRUE : FALSE; + if (Dpc->DpcData) { + + /* Remove the DPC */ + ((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--; + RemoveEntryList(&Dpc->DpcListEntry);
- } + } #ifdef CONFIG_SMP KiReleaseSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock); #endif
- /* Return if the DPC was in the queue or not */ - KeLowerIrql(OldIrql); - return WasInQueue; + /* Return if the DPC was in the queue or not */ + KeLowerIrql(OldIrql); + return WasInQueue; }
/* @@ -323,7 +337,8 @@ * Called when deleting a Driver. */ { - if (KeGetCurrentKPCR()->PrcbData.DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + /* Request an interrupt if needed */ + if (KeGetCurrentPrcb()->DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL); }
/* @@ -332,10 +347,11 @@ BOOLEAN STDCALL KeIsExecutingDpc( - VOID + VOID ) { - return KeGetCurrentKPCR()->PrcbData.DpcRoutineActive; + /* Return if the Dpc Routine is active */ + return KeGetCurrentPrcb()->DpcRoutineActive; }
/* @@ -349,39 +365,41 @@ */ VOID STDCALL -KeSetImportanceDpc (IN PKDPC Dpc, - IN KDPC_IMPORTANCE Importance) +KeSetImportanceDpc (IN PKDPC Dpc, + IN KDPC_IMPORTANCE Importance) { - Dpc->Importance = Importance; + /* Set the DPC Importance */ + Dpc->Importance = Importance; }
/* + * @implemented + * * FUNCTION: Specifies on which processor the DPC will run * ARGUMENTS: * Dpc = Initalizes DPC * Number = Processor number * RETURNS: None - * - * @implemented */ -VOID STDCALL -KeSetTargetProcessorDpc (IN PKDPC Dpc, - IN CCHAR Number) +VOID +STDCALL +KeSetTargetProcessorDpc(IN PKDPC Dpc, + IN CCHAR Number) { - if (Number >= MAXIMUM_PROCESSORS) - { - Dpc->Number = 0; - } - else - { - ASSERT(Number < KeNumberProcessors); - Dpc->Number = Number + MAXIMUM_PROCESSORS; - } + /* Check how many CPUs are on the system */ + if (Number >= MAXIMUM_PROCESSORS) { + + /* No CPU Number */ + Dpc->Number = 0; + + } else { + + /* Set the Number Specified */ + ASSERT(Number < KeNumberProcessors); + Dpc->Number = Number + MAXIMUM_PROCESSORS; + } }
-VOID -STDCALL -KiQuantumEnd(VOID) /* * FUNCTION: * Called when a quantum end occurs to check if priority should be changed @@ -389,152 +407,173 @@ * NOTES: * Called when deleting a Driver. */ +VOID +STDCALL +KiQuantumEnd(VOID) { - PKPRCB Prcb; - PKTHREAD CurrentThread; - KIRQL OldIrql; - PKPROCESS Process; - KPRIORITY OldPriority; - KPRIORITY NewPriority; - - /* Lock dispatcher, get current thread */ - Prcb = &KeGetCurrentKPCR()->PrcbData; - CurrentThread = KeGetCurrentThread(); - OldIrql = KeRaiseIrqlToSynchLevel(); - - /* Get the Thread's Process */ - Process = CurrentThread->ApcState.Process; - - /* Set DPC Event if requested */ - if (Prcb->DpcSetEventRequest) { - KeSetEvent(Prcb->DpcEvent, 0, 0); - } - - /* Check if Quantum expired */ - if (CurrentThread->Quantum <= 0) { - /* Set the new Quantum */ - CurrentThread->Quantum = Process->ThreadQuantum; - - /* Calculate new priority */ - OldPriority = CurrentThread->Priority; - if (OldPriority < LOW_REALTIME_PRIORITY) { - NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1; - if (NewPriority < CurrentThread->BasePriority) { - NewPriority = CurrentThread->BasePriority; - } - CurrentThread->PriorityDecrement = 0; - if (OldPriority != NewPriority) { - /* Set new Priority */ - CurrentThread->Priority = NewPriority; - } else { - /* Queue new thread if none is already */ - if (Prcb->NextThread == NULL) { - /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */ - } else { - /* Make the current thread non-premeptive if a new thread is queued */ - CurrentThread->Preempted = FALSE; - } - } - } else { - /* Set the Quantum back to Maximum */ - //if (CurrentThread->DisableQuantum) { - // CurrentThread->Quantum = MAX_QUANTUM; - //} - } - } - /* Dispatch the Thread */ - KeLowerIrql(DISPATCH_LEVEL); - PsDispatchThread(THREAD_STATE_READY); -} + PKPRCB Prcb; + PKTHREAD CurrentThread; + KIRQL OldIrql; + PKPROCESS Process; + KPRIORITY OldPriority; + KPRIORITY NewPriority; + + /* Lock dispatcher, get current thread */ + Prcb = KeGetCurrentPrcb(); + CurrentThread = KeGetCurrentThread(); + OldIrql = KeRaiseIrqlToSynchLevel(); + + /* Get the Thread's Process */ + Process = CurrentThread->ApcState.Process; + + /* Set DPC Event if requested */ + if (Prcb->DpcSetEventRequest) { + KeSetEvent(Prcb->DpcEvent, 0, 0); + } + + /* Check if Quantum expired */ + if (CurrentThread->Quantum <= 0) { + /* Set the new Quantum */ + CurrentThread->Quantum = Process->ThreadQuantum; + + /* Calculate new priority */ + OldPriority = CurrentThread->Priority; + if (OldPriority < LOW_REALTIME_PRIORITY) { + + /* Set the New Priority and add the Priority Decrement */ + NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1; + + /* Don't go out of bounds */ + if (NewPriority < CurrentThread->BasePriority) NewPriority = CurrentThread->BasePriority; + + /* Reset the priority decrement */ + CurrentThread->PriorityDecrement = 0; + + /* Set a new priority if needed */ + if (OldPriority != NewPriority) { + + /* Set new Priority */ + CurrentThread->Priority = NewPriority; + + } else { + + /* Queue new thread if none is already */ + if (Prcb->NextThread == NULL) { + + /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */ + + } else { + + /* Make the current thread non-premeptive if a new thread is queued */ + CurrentThread->Preempted = FALSE; + } + }
+ + } else { + /* Set the Quantum back to Maximum */ + //if (CurrentThread->DisableQuantum) { + // CurrentThread->Quantum = MAX_QUANTUM; + //} + } + } + + /* Dispatch the Thread */ + KeLowerIrql(DISPATCH_LEVEL); + PsDispatchThread(THREAD_STATE_READY); +} + /* * @implemented + * + * FUNCTION: + * Called whenever a system interrupt is generated at DISPATCH_LEVEL. + * It delivers queued DPCs and dispatches a new thread if need be. */ VOID STDCALL KiDispatchInterrupt(VOID) -/* - * FUNCTION: - * Called whenever a system interrupt is generated at DISPATCH_LEVEL. - * It delivers queued DPCs and dispatches a new thread if need be. - */ { - PLIST_ENTRY DpcEntry; - PKDPC Dpc; - KIRQL OldIrql; - PKPCR Pcr; + PLIST_ENTRY DpcEntry; + PKDPC Dpc; + KIRQL OldIrql; + PKPRCB Prcb;
- DPRINT("Dispatching Interrupts\n"); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + DPRINT("Dispatching Interrupts\n"); + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
- /* Set DPC Deliver to Active */ - Pcr = KeGetCurrentKPCR(); + /* Set DPC Deliver to Active */ + Prcb = KeGetCurrentPrcb();
- if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0) { - /* Raise IRQL */ - KeRaiseIrql(HIGH_LEVEL, &OldIrql); -#ifdef CONFIG_SMP - KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + if (Prcb->DpcData[0].DpcQueueDepth > 0) { + /* Raise IRQL */ + KeRaiseIrql(HIGH_LEVEL, &OldIrql); +#ifdef CONFIG_SMP + KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock); #endif - Pcr->PrcbData.DpcRoutineActive = TRUE; + Prcb->DpcRoutineActive = TRUE;
- DPRINT("&Pcr->PrcbData.DpcData[0].DpcListHead: %x\n", &Pcr->PrcbData.DpcData[0].DpcListHead); - /* Loop while we have entries */ - while (!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)) { - ASSERT(Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0); - DPRINT("Queue Depth: %x\n", Pcr->PrcbData.DpcData[0].DpcQueueDepth); - - /* Get the DPC call it */ - DpcEntry = RemoveHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead); - Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry); - DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink); - Dpc->DpcData = NULL; - Pcr->PrcbData.DpcData[0].DpcQueueDepth--; + DPRINT("&Prcb->DpcData[0].DpcListHead: %x\n", &Prcb->DpcData[0].DpcListHead); + /* Loop while we have entries */ + while (!IsListEmpty(&Prcb->DpcData[0].DpcListHead)) { + + ASSERT(Prcb->DpcData[0].DpcQueueDepth > 0); + DPRINT("Queue Depth: %x\n", Prcb->DpcData[0].DpcQueueDepth); + + /* Get the DPC call it */ + DpcEntry = RemoveHeadList(&Prcb->DpcData[0].DpcListHead); + Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry); + DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink); + Dpc->DpcData = NULL; + Prcb->DpcData[0].DpcQueueDepth--; #ifdef CONFIG_SMP - KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock); #endif - /* Disable/Enabled Interrupts and Call the DPC */ - KeLowerIrql(OldIrql); - DPRINT("Calling DPC: %x\n", Dpc); - Dpc->DeferredRoutine(Dpc, - Dpc->DeferredContext, - Dpc->SystemArgument1, - Dpc->SystemArgument2); - KeRaiseIrql(HIGH_LEVEL, &OldIrql); - + /* Disable/Enabled Interrupts and Call the DPC */ + KeLowerIrql(OldIrql); + DPRINT("Calling DPC: %x\n", Dpc); + Dpc->DeferredRoutine(Dpc, + Dpc->DeferredContext, + Dpc->SystemArgument1, + Dpc->SystemArgument2); + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + #ifdef CONFIG_SMP - KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); - /* - * If the dpc routine drops the irql below DISPATCH_LEVEL, - * a thread switch can occur and after the next thread switch - * the execution may start on an other processor. - */ - if (Pcr != KeGetCurrentKPCR()) { - Pcr->PrcbData.DpcRoutineActive = FALSE; - KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); - Pcr = KeGetCurrentKPCR(); - KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); - Pcr->PrcbData.DpcRoutineActive = TRUE; - } + KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock); + /* + * If the dpc routine drops the irql below DISPATCH_LEVEL, + * a thread switch can occur and after the next thread switch + * the execution may start on an other processor. + */ + if (Prcb != KeGetCurrentPrcb()) { + + Prcb->DpcRoutineActive = FALSE; + KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock); + Prcb = KeGetCurrentPrcb(); + KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock); + Prcb->DpcRoutineActive = TRUE; + } #endif - } - /* Clear DPC Flags */ - Pcr->PrcbData.DpcRoutineActive = FALSE; - Pcr->PrcbData.DpcInterruptRequested = FALSE; + } + /* Clear DPC Flags */ + Prcb->DpcRoutineActive = FALSE; + Prcb->DpcInterruptRequested = FALSE; #ifdef CONFIG_SMP - KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock); #endif - - /* DPC Dispatching Ended, re-enable interrupts */ - KeLowerIrql(OldIrql); - } - - DPRINT("Checking for Quantum End\n"); - /* If we have Quantum End, call the function */ - if (Pcr->PrcbData.QuantumEnd) { - Pcr->PrcbData.QuantumEnd = FALSE; - KiQuantumEnd(); - } + + /* DPC Dispatching Ended, re-enable interrupts */ + KeLowerIrql(OldIrql); + } + + DPRINT("Checking for Quantum End\n"); + + /* If we have Quantum End, call the function */ + if (Prcb->QuantumEnd) { + + Prcb->QuantumEnd = FALSE; + KiQuantumEnd(); + } }
/* EOF */ _____
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c --- trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-03-12 19:23:04 UTC (rev 13974) +++ trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-03-12 19:45:37 UTC (rev 13975) @@ -187,7 +187,7 @@
/* Check FPU/MMX/SSE support. */ KiCheckFPU();
- KeInitDpc(Pcr); + KeInitDpc(Pcr->Prcb);
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) { @@ -262,7 +262,7 @@ /* Mark the end of the exception handler list */ KPCR->Tib.ExceptionList = (PVOID)-1;
- KeInitDpc(KPCR); + KeInitDpc(KPCR->Prcb);
KeInitExceptions (); KeInitInterrupts ();