Alex Ionescu <ionucu(a)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(a)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 ();