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.

svn path=/trunk/; revision=13975
This commit is contained in:
Thomas Bluemel 2005-03-12 19:45:37 +00:00
parent b2a42182ef
commit fd962e2f04
3 changed files with 347 additions and 307 deletions

View file

@ -41,6 +41,7 @@ VOID KeSetGdtSelector(ULONG Entry, ULONG Value1, ULONG Value2);
struct _KTHREAD; struct _KTHREAD;
struct _KIRQ_TRAPFRAME; struct _KIRQ_TRAPFRAME;
struct _KPCR; struct _KPCR;
struct _KPRCB;
struct _KEXCEPTION_FRAME; struct _KEXCEPTION_FRAME;
#define IPI_REQUEST_FUNCTIONCALL 0 #define IPI_REQUEST_FUNCTIONCALL 0
@ -192,7 +193,7 @@ extern LARGE_INTEGER SystemBootTime;
VOID KeInitExceptions(VOID); VOID KeInitExceptions(VOID);
VOID KeInitInterrupts(VOID); VOID KeInitInterrupts(VOID);
VOID KeInitTimer(VOID); VOID KeInitTimer(VOID);
VOID KeInitDpc(struct _KPCR* Pcr); VOID KeInitDpc(struct _KPRCB* Prcb);
VOID KeInitDispatcher(VOID); VOID KeInitDispatcher(VOID);
VOID KeInitializeDispatcher(VOID); VOID KeInitializeDispatcher(VOID);
VOID KiInitializeSystemClock(VOID); VOID KiInitializeSystemClock(VOID);

View file

@ -24,22 +24,22 @@
/* TYPES *******************************************************************/ /* TYPES *******************************************************************/
#define MAX_QUANTUM 0x7F #define MAX_QUANTUM 0x7F
/* GLOBALS ******************************************************************/
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
VOID INIT_FUNCTION
KeInitDpc(PKPCR Pcr)
/* /*
* FUNCTION: Initialize DPC handling * FUNCTION: Initialize DPC handling
*/ */
VOID
INIT_FUNCTION
KeInitDpc(PKPRCB Prcb)
{ {
InitializeListHead(&Pcr->PrcbData.DpcData[0].DpcListHead); InitializeListHead(&Prcb->DpcData[0].DpcListHead);
KeInitializeEvent(Pcr->PrcbData.DpcEvent, 0, 0); KeInitializeEvent(Prcb->DpcEvent, 0, 0);
KeInitializeSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); KeInitializeSpinLock(&Prcb->DpcData[0].DpcLock);
Pcr->PrcbData.MaximumDpcQueueDepth = 4; Prcb->MaximumDpcQueueDepth = 4;
Pcr->PrcbData.MinimumDpcRate = 3; Prcb->MinimumDpcRate = 3;
Pcr->PrcbData.DpcData[0].DpcQueueDepth = 0; Prcb->DpcData[0].DpcQueueDepth = 0;
} }
/* /*
@ -61,7 +61,7 @@ KeInitializeThreadedDpc(PKDPC Dpc,
*/ */
{ {
DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine); DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
//Dpc->Type = KThreadedDpc; Dpc->Type = ThreadedDpcObject;
Dpc->Number= 0; Dpc->Number= 0;
Dpc->Importance= MediumImportance; Dpc->Importance= MediumImportance;
Dpc->DeferredRoutine = DeferredRoutine; Dpc->DeferredRoutine = DeferredRoutine;
@ -71,13 +71,7 @@ KeInitializeThreadedDpc(PKDPC Dpc,
/* /*
* @implemented * @implemented
*/ *
VOID
STDCALL
KeInitializeDpc (PKDPC Dpc,
PKDEFERRED_ROUTINE DeferredRoutine,
PVOID DeferredContext)
/*
* FUNCTION: * FUNCTION:
* Initalizes a DPC and registers the DeferredRoutine for it. * Initalizes a DPC and registers the DeferredRoutine for it.
* ARGUMENTS: * ARGUMENTS:
@ -86,6 +80,11 @@ KeInitializeDpc (PKDPC Dpc,
* DeferredContext = Parameter to be passed to the callback routine. * DeferredContext = Parameter to be passed to the callback routine.
* NOTE: Callers can be running at any IRQL. * 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); DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
Dpc->Type = DpcObject; Dpc->Type = DpcObject;
@ -98,12 +97,7 @@ KeInitializeDpc (PKDPC Dpc,
/* /*
* @implemented * @implemented
*/ *
BOOLEAN STDCALL
KeInsertQueueDpc (PKDPC Dpc,
PVOID SystemArgument1,
PVOID SystemArgument2)
/*
* FUNCTION: * FUNCTION:
* Queues a DPC for execution when the IRQL of a processor * Queues a DPC for execution when the IRQL of a processor
* drops below DISPATCH_LEVEL * drops below DISPATCH_LEVEL
@ -155,9 +149,14 @@ KeInsertQueueDpc (PKDPC Dpc,
* is greater that the target depth or the minimum DPC rate is less than the * is greater that the target depth or the minimum DPC rate is less than the
* target rate. * target rate.
*/ */
BOOLEAN
STDCALL
KeInsertQueueDpc(PKDPC Dpc,
PVOID SystemArgument1,
PVOID SystemArgument2)
{ {
KIRQL OldIrql; KIRQL OldIrql;
PKPCR Pcr; PKPRCB Prcb;
DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n", DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n",
Dpc, SystemArgument1, SystemArgument2); Dpc, SystemArgument1, SystemArgument2);
@ -167,100 +166,115 @@ KeInsertQueueDpc (PKDPC Dpc,
KeRaiseIrql(HIGH_LEVEL, &OldIrql); KeRaiseIrql(HIGH_LEVEL, &OldIrql);
/* Check if this is a Thread DPC, which we don't support (yet) */ /* Check if this is a Thread DPC, which we don't support (yet) */
//if (Dpc->Type == KThreadedDpc) { if (Dpc->Type == ThreadedDpcObject) {
// return FALSE; return FALSE;
// KeLowerIrql(OldIrql); KeLowerIrql(OldIrql);
//} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Get the right PCR for this CPU */ /* Get the right PCR for this CPU */
if (Dpc->Number >= MAXIMUM_PROCESSORS) { if (Dpc->Number >= MAXIMUM_PROCESSORS) {
ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors); ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors);
Pcr = (PKPCR)(KPCR_BASE + (Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE); Prcb = ((PKPCR)((ULONG_PTR)KPCR_BASE + ((Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE)))->Prcb;
} else { } else {
ASSERT (Dpc->Number < KeNumberProcessors); ASSERT (Dpc->Number < KeNumberProcessors);
Pcr = KeGetCurrentKPCR(); Prcb = KeGetCurrentPrcb();
Dpc->Number = KeGetCurrentProcessorNumber(); Dpc->Number = KeGetCurrentProcessorNumber();
} }
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
#else #else
Pcr = (PKPCR)KPCR_BASE; Prcb = ((PKPCR)KPCR_BASE)->Prcb;
#endif #endif
/* Get the DPC Data */ /* Get the DPC Data */
if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Pcr->PrcbData.DpcData[0].DpcLock, 0)) { if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Prcb->DpcData[0].DpcLock, 0)) {
DPRINT("DPC Already Inserted"); DPRINT("DPC Already Inserted");
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
#endif #endif
KeLowerIrql(OldIrql); KeLowerIrql(OldIrql);
return(FALSE); return(FALSE);
} }
/* Make sure the lists are free if the Queue is 0 */ /* Make sure the lists are free if the Queue is 0 */
if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0) { if (Prcb->DpcData[0].DpcQueueDepth == 0) {
ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
ASSERT(IsListEmpty(&Prcb->DpcData[0].DpcListHead));
} else { } else {
ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
ASSERT(!IsListEmpty(&Prcb->DpcData[0].DpcListHead));
} }
/* Now we can play with the DPC safely */ /* Now we can play with the DPC safely */
Dpc->SystemArgument1=SystemArgument1; Dpc->SystemArgument1=SystemArgument1;
Dpc->SystemArgument2=SystemArgument2; Dpc->SystemArgument2=SystemArgument2;
Pcr->PrcbData.DpcData[0].DpcQueueDepth++; Prcb->DpcData[0].DpcQueueDepth++;
Pcr->PrcbData.DpcData[0].DpcCount++; Prcb->DpcData[0].DpcCount++;
/* Insert the DPC into the list. HighImportance DPCs go at the beginning */ /* Insert the DPC into the list. HighImportance DPCs go at the beginning */
if (Dpc->Importance == HighImportance) { if (Dpc->Importance == HighImportance) {
InsertHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry);
InsertHeadList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry);
} else { } else {
InsertTailList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry);
InsertTailList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry);
} }
DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink); 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. */ /* Make sure a DPC isn't executing already and respect rules outlined above. */
if ((!Pcr->PrcbData.DpcRoutineActive) && (!Pcr->PrcbData.DpcInterruptRequested)) { if ((!Prcb->DpcRoutineActive) && (!Prcb->DpcInterruptRequested)) {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Check if this is the same CPU */ /* Check if this is the same CPU */
if (Pcr != KeGetCurrentKPCR()) { if (Prcb != KeGetCurrentPrcb()) {
/* Send IPI if High Importance */ /* Send IPI if High Importance */
if ((Dpc->Importance == HighImportance) || if ((Dpc->Importance == HighImportance) ||
(Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth)) { (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth)) {
if (Dpc->Number >= MAXIMUM_PROCESSORS) { if (Dpc->Number >= MAXIMUM_PROCESSORS) {
KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC); KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC);
} else { } else {
KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC); KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC);
} }
} }
} else { } else {
/* Request an Interrupt only if the DPC isn't low priority */ /* Request an Interrupt only if the DPC isn't low priority */
if ((Dpc->Importance != LowImportance) || if ((Dpc->Importance != LowImportance) ||
(Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) || (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) ||
(Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) { (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) {
/* Request Interrupt */ /* Request Interrupt */
HalRequestSoftwareInterrupt(DISPATCH_LEVEL); HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
Pcr->PrcbData.DpcInterruptRequested = TRUE; Prcb->DpcInterruptRequested = TRUE;
} }
} }
#else #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); 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 */ /* Request an Interrupt only if the DPC isn't low priority */
if ((Dpc->Importance != LowImportance) || if ((Dpc->Importance != LowImportance) ||
(Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) || (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) ||
(Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) { (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) {
/* Request Interrupt */ /* Request Interrupt */
DPRINT("Requesting Interrupt\n"); DPRINT("Requesting Interrupt\n");
HalRequestSoftwareInterrupt(DISPATCH_LEVEL); HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
Pcr->PrcbData.DpcInterruptRequested = TRUE; Prcb->DpcInterruptRequested = TRUE;
} }
#endif #endif
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
#endif #endif
/* Lower IRQL */ /* Lower IRQL */
KeLowerIrql(OldIrql); KeLowerIrql(OldIrql);
@ -269,10 +283,7 @@ KeInsertQueueDpc (PKDPC Dpc,
/* /*
* @implemented * @implemented
*/ *
BOOLEAN STDCALL
KeRemoveQueueDpc (PKDPC Dpc)
/*
* FUNCTION: * FUNCTION:
* Removes DPC object from the system dpc queue * Removes DPC object from the system dpc queue
* ARGUMENTS: * ARGUMENTS:
@ -281,6 +292,9 @@ KeRemoveQueueDpc (PKDPC Dpc)
* TRUE if the DPC was in the queue * TRUE if the DPC was in the queue
* FALSE otherwise * FALSE otherwise
*/ */
BOOLEAN
STDCALL
KeRemoveQueueDpc(PKDPC Dpc)
{ {
BOOLEAN WasInQueue; BOOLEAN WasInQueue;
KIRQL OldIrql; KIRQL OldIrql;
@ -323,7 +337,8 @@ KeFlushQueuedDpcs(VOID)
* Called when deleting a Driver. * 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);
} }
/* /*
@ -335,7 +350,8 @@ KeIsExecutingDpc(
VOID VOID
) )
{ {
return KeGetCurrentKPCR()->PrcbData.DpcRoutineActive; /* Return if the Dpc Routine is active */
return KeGetCurrentPrcb()->DpcRoutineActive;
} }
/* /*
@ -352,36 +368,38 @@ STDCALL
KeSetImportanceDpc (IN PKDPC Dpc, KeSetImportanceDpc (IN PKDPC Dpc,
IN KDPC_IMPORTANCE Importance) IN KDPC_IMPORTANCE Importance)
{ {
/* Set the DPC Importance */
Dpc->Importance = Importance; Dpc->Importance = Importance;
} }
/* /*
* @implemented
*
* FUNCTION: Specifies on which processor the DPC will run * FUNCTION: Specifies on which processor the DPC will run
* ARGUMENTS: * ARGUMENTS:
* Dpc = Initalizes DPC * Dpc = Initalizes DPC
* Number = Processor number * Number = Processor number
* RETURNS: None * RETURNS: None
*
* @implemented
*/ */
VOID STDCALL VOID
STDCALL
KeSetTargetProcessorDpc(IN PKDPC Dpc, KeSetTargetProcessorDpc(IN PKDPC Dpc,
IN CCHAR Number) IN CCHAR Number)
{ {
if (Number >= MAXIMUM_PROCESSORS) /* Check how many CPUs are on the system */
{ if (Number >= MAXIMUM_PROCESSORS) {
/* No CPU Number */
Dpc->Number = 0; Dpc->Number = 0;
}
else } else {
{
/* Set the Number Specified */
ASSERT(Number < KeNumberProcessors); ASSERT(Number < KeNumberProcessors);
Dpc->Number = Number + MAXIMUM_PROCESSORS; Dpc->Number = Number + MAXIMUM_PROCESSORS;
} }
} }
VOID
STDCALL
KiQuantumEnd(VOID)
/* /*
* FUNCTION: * FUNCTION:
* Called when a quantum end occurs to check if priority should be changed * Called when a quantum end occurs to check if priority should be changed
@ -389,6 +407,9 @@ KiQuantumEnd(VOID)
* NOTES: * NOTES:
* Called when deleting a Driver. * Called when deleting a Driver.
*/ */
VOID
STDCALL
KiQuantumEnd(VOID)
{ {
PKPRCB Prcb; PKPRCB Prcb;
PKTHREAD CurrentThread; PKTHREAD CurrentThread;
@ -398,7 +419,7 @@ KiQuantumEnd(VOID)
KPRIORITY NewPriority; KPRIORITY NewPriority;
/* Lock dispatcher, get current thread */ /* Lock dispatcher, get current thread */
Prcb = &KeGetCurrentKPCR()->PrcbData; Prcb = KeGetCurrentPrcb();
CurrentThread = KeGetCurrentThread(); CurrentThread = KeGetCurrentThread();
OldIrql = KeRaiseIrqlToSynchLevel(); OldIrql = KeRaiseIrqlToSynchLevel();
@ -418,23 +439,37 @@ KiQuantumEnd(VOID)
/* Calculate new priority */ /* Calculate new priority */
OldPriority = CurrentThread->Priority; OldPriority = CurrentThread->Priority;
if (OldPriority < LOW_REALTIME_PRIORITY) { if (OldPriority < LOW_REALTIME_PRIORITY) {
/* Set the New Priority and add the Priority Decrement */
NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1; NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1;
if (NewPriority < CurrentThread->BasePriority) {
NewPriority = CurrentThread->BasePriority; /* Don't go out of bounds */
} if (NewPriority < CurrentThread->BasePriority) NewPriority = CurrentThread->BasePriority;
/* Reset the priority decrement */
CurrentThread->PriorityDecrement = 0; CurrentThread->PriorityDecrement = 0;
/* Set a new priority if needed */
if (OldPriority != NewPriority) { if (OldPriority != NewPriority) {
/* Set new Priority */ /* Set new Priority */
CurrentThread->Priority = NewPriority; CurrentThread->Priority = NewPriority;
} else { } else {
/* Queue new thread if none is already */ /* Queue new thread if none is already */
if (Prcb->NextThread == NULL) { if (Prcb->NextThread == NULL) {
/* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */ /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */
} else { } else {
/* Make the current thread non-premeptive if a new thread is queued */ /* Make the current thread non-premeptive if a new thread is queued */
CurrentThread->Preempted = FALSE; CurrentThread->Preempted = FALSE;
} }
} }
} else { } else {
/* Set the Quantum back to Maximum */ /* Set the Quantum back to Maximum */
//if (CurrentThread->DisableQuantum) { //if (CurrentThread->DisableQuantum) {
@ -442,6 +477,7 @@ KiQuantumEnd(VOID)
//} //}
} }
} }
/* Dispatch the Thread */ /* Dispatch the Thread */
KeLowerIrql(DISPATCH_LEVEL); KeLowerIrql(DISPATCH_LEVEL);
PsDispatchThread(THREAD_STATE_READY); PsDispatchThread(THREAD_STATE_READY);
@ -449,49 +485,49 @@ KiQuantumEnd(VOID)
/* /*
* @implemented * @implemented
*/ *
VOID
STDCALL
KiDispatchInterrupt(VOID)
/*
* FUNCTION: * FUNCTION:
* Called whenever a system interrupt is generated at DISPATCH_LEVEL. * Called whenever a system interrupt is generated at DISPATCH_LEVEL.
* It delivers queued DPCs and dispatches a new thread if need be. * It delivers queued DPCs and dispatches a new thread if need be.
*/ */
VOID
STDCALL
KiDispatchInterrupt(VOID)
{ {
PLIST_ENTRY DpcEntry; PLIST_ENTRY DpcEntry;
PKDPC Dpc; PKDPC Dpc;
KIRQL OldIrql; KIRQL OldIrql;
PKPCR Pcr; PKPRCB Prcb;
DPRINT("Dispatching Interrupts\n"); DPRINT("Dispatching Interrupts\n");
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
/* Set DPC Deliver to Active */ /* Set DPC Deliver to Active */
Pcr = KeGetCurrentKPCR(); Prcb = KeGetCurrentPrcb();
if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0) { if (Prcb->DpcData[0].DpcQueueDepth > 0) {
/* Raise IRQL */ /* Raise IRQL */
KeRaiseIrql(HIGH_LEVEL, &OldIrql); KeRaiseIrql(HIGH_LEVEL, &OldIrql);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
#endif #endif
Pcr->PrcbData.DpcRoutineActive = TRUE; Prcb->DpcRoutineActive = TRUE;
DPRINT("&Pcr->PrcbData.DpcData[0].DpcListHead: %x\n", &Pcr->PrcbData.DpcData[0].DpcListHead); DPRINT("&Prcb->DpcData[0].DpcListHead: %x\n", &Prcb->DpcData[0].DpcListHead);
/* Loop while we have entries */ /* Loop while we have entries */
while (!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)) { while (!IsListEmpty(&Prcb->DpcData[0].DpcListHead)) {
ASSERT(Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0);
DPRINT("Queue Depth: %x\n", Pcr->PrcbData.DpcData[0].DpcQueueDepth); ASSERT(Prcb->DpcData[0].DpcQueueDepth > 0);
DPRINT("Queue Depth: %x\n", Prcb->DpcData[0].DpcQueueDepth);
/* Get the DPC call it */ /* Get the DPC call it */
DpcEntry = RemoveHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead); DpcEntry = RemoveHeadList(&Prcb->DpcData[0].DpcListHead);
Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry); Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry);
DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink); DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
Dpc->DpcData = NULL; Dpc->DpcData = NULL;
Pcr->PrcbData.DpcData[0].DpcQueueDepth--; Prcb->DpcData[0].DpcQueueDepth--;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
#endif #endif
/* Disable/Enabled Interrupts and Call the DPC */ /* Disable/Enabled Interrupts and Call the DPC */
KeLowerIrql(OldIrql); KeLowerIrql(OldIrql);
@ -503,26 +539,27 @@ KiDispatchInterrupt(VOID)
KeRaiseIrql(HIGH_LEVEL, &OldIrql); KeRaiseIrql(HIGH_LEVEL, &OldIrql);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
/* /*
* If the dpc routine drops the irql below DISPATCH_LEVEL, * If the dpc routine drops the irql below DISPATCH_LEVEL,
* a thread switch can occur and after the next thread switch * a thread switch can occur and after the next thread switch
* the execution may start on an other processor. * the execution may start on an other processor.
*/ */
if (Pcr != KeGetCurrentKPCR()) { if (Prcb != KeGetCurrentPrcb()) {
Pcr->PrcbData.DpcRoutineActive = FALSE;
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); Prcb->DpcRoutineActive = FALSE;
Pcr = KeGetCurrentKPCR(); KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); Prcb = KeGetCurrentPrcb();
Pcr->PrcbData.DpcRoutineActive = TRUE; KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
Prcb->DpcRoutineActive = TRUE;
} }
#endif #endif
} }
/* Clear DPC Flags */ /* Clear DPC Flags */
Pcr->PrcbData.DpcRoutineActive = FALSE; Prcb->DpcRoutineActive = FALSE;
Pcr->PrcbData.DpcInterruptRequested = FALSE; Prcb->DpcInterruptRequested = FALSE;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
#endif #endif
/* DPC Dispatching Ended, re-enable interrupts */ /* DPC Dispatching Ended, re-enable interrupts */
@ -530,9 +567,11 @@ KiDispatchInterrupt(VOID)
} }
DPRINT("Checking for Quantum End\n"); DPRINT("Checking for Quantum End\n");
/* If we have Quantum End, call the function */ /* If we have Quantum End, call the function */
if (Pcr->PrcbData.QuantumEnd) { if (Prcb->QuantumEnd) {
Pcr->PrcbData.QuantumEnd = FALSE;
Prcb->QuantumEnd = FALSE;
KiQuantumEnd(); KiQuantumEnd();
} }
} }

View file

@ -187,7 +187,7 @@ KeApplicationProcessorInit(VOID)
/* Check FPU/MMX/SSE support. */ /* Check FPU/MMX/SSE support. */
KiCheckFPU(); KiCheckFPU();
KeInitDpc(Pcr); KeInitDpc(Pcr->Prcb);
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL)
{ {
@ -262,7 +262,7 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
/* Mark the end of the exception handler list */ /* Mark the end of the exception handler list */
KPCR->Tib.ExceptionList = (PVOID)-1; KPCR->Tib.ExceptionList = (PVOID)-1;
KeInitDpc(KPCR); KeInitDpc(KPCR->Prcb);
KeInitExceptions (); KeInitExceptions ();
KeInitInterrupts (); KeInitInterrupts ();