reactos/ntoskrnl/ke
diff -u -r1.43 -r1.44
--- dpc.c 31 Oct 2004 15:31:40 -0000 1.43
+++ dpc.c 31 Oct 2004 17:02:31 -0000 1.44
@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: dpc.c,v 1.43 2004/10/31 15:31:40 hbirr Exp $
+/* $Id: dpc.c,v 1.44 2004/10/31 17:02:31 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -63,6 +63,8 @@
*/
{
Dpc->Type = 0;
+ Dpc->Number=0;
+ Dpc->Importance=MediumImportance;
Dpc->DeferredRoutine = DeferredRoutine;
Dpc->DeferredContext = DeferredContext;
Dpc->Lock = 0;
@@ -102,12 +104,18 @@
Pcr->PrcbData.DpcData[0].DpcQueueDepth--;
Pcr->PrcbData.DpcData[0].DpcCount++;
- ASSERT((Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0 && IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)) ||
- (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0 && !IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)));
+ if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0)
+ {
+ ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
+ }
+ else
+ {
+ ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
+ }
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
current->Lock=FALSE;
- Pcr->PrcbData.DpcRoutineActive=1;
+ Pcr->PrcbData.DpcRoutineActive++;
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
KeLowerIrql(oldlvl);
current->DeferredRoutine(current,current->DeferredContext,
@@ -116,7 +124,20 @@
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
- Pcr->PrcbData.DpcRoutineActive=0;
+ Pcr->PrcbData.DpcRoutineActive--;
+#ifdef MP
+ /*
+ * 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())
+ {
+ KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+ Pcr = KeGetCurrentKPCR();
+ KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+ }
+#endif
}
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
@@ -179,7 +200,20 @@
PKPCR Pcr;
KeRaiseIrql(HIGH_LEVEL, &oldIrql);
+#ifdef MP
+ 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 = (PKPCR)(KPCR_BASE + Dpc->Number * PAGE_SIZE);
+ }
+#else
Pcr = KeGetCurrentKPCR();
+#endif
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
WasInQueue = Dpc->Lock ? TRUE : FALSE;
if (WasInQueue)
@@ -189,8 +223,14 @@
Dpc->Lock=0;
}
- ASSERT((Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0 && IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)) ||
- (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0 && !IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)));
+ if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0)
+ {
+ ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
+ }
+ else
+ {
+ ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
+ }
KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
KeLowerIrql(oldIrql);
@@ -223,8 +263,6 @@
ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL);
- Dpc->Number=0;
- Dpc->Importance=MediumImportance;
Dpc->SystemArgument1=SystemArgument1;
Dpc->SystemArgument2=SystemArgument2;
if (Dpc->Lock)
@@ -233,10 +271,31 @@
}
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
+#ifdef MP
+ 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();
+ }
+#else
Pcr = KeGetCurrentKPCR();
+#endif
+
KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
- ASSERT((Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0 && IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)) ||
- (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0 && !IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)));
+ if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0)
+ {
+ ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
+ }
+ else
+ {
+ ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
+ }
InsertHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead,&Dpc->DpcListEntry);
DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
Pcr->PrcbData.DpcData[0].DpcQueueDepth++;
@@ -281,7 +340,15 @@
KeSetTargetProcessorDpc (IN PKDPC Dpc,
IN CCHAR Number)
{
- UNIMPLEMENTED;
+ if (Number >= MAXIMUM_PROCESSORS)
+ {
+ Dpc->Number = 0;
+ }
+ else
+ {
+ ASSERT(Number < KeNumberProcessors);
+ Dpc->Number = Number + MAXIMUM_PROCESSORS;
+ }
}
VOID INIT_FUNCTION