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 ();