- Used interlocked functions to modify the values for the ipi functions on smp machines.

svn path=/trunk/; revision=12689
This commit is contained in:
Hartmut Birr 2005-01-01 11:22:12 +00:00
parent 2d760db23f
commit 7060a9893e
2 changed files with 19 additions and 28 deletions

View file

@ -43,9 +43,9 @@ struct _KIRQ_TRAPFRAME;
struct _KPCR; struct _KPCR;
struct _KEXCEPTION_FRAME; struct _KEXCEPTION_FRAME;
#define IPI_REQUEST_FUNCTIONCALL 1 #define IPI_REQUEST_FUNCTIONCALL 0
#define IPI_REQUEST_APC 2 #define IPI_REQUEST_APC 1
#define IPI_REQUEST_DPC 4 #define IPI_REQUEST_DPC 2
/* ipi.c ********************************************************************/ /* ipi.c ********************************************************************/

View file

@ -1,4 +1,4 @@
/* $Id: ipi.c,v 1.5 2004/12/24 17:06:58 navaraf Exp $ /* $Id$
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -33,7 +33,7 @@ KiIpiSendRequest(ULONG TargetSet, ULONG IpiRequest)
if (TargetSet & (1 << i)) if (TargetSet & (1 << i))
{ {
Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
Pcr->PrcbData.IpiFrozen |= IpiRequest; Ke386TestAndSetBit(IpiRequest, &Pcr->PrcbData.IpiFrozen);
HalRequestIpi(i); HalRequestIpi(i);
} }
} }
@ -51,8 +51,6 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
LARGE_INTEGER StartTime, CurrentTime, Frequency; LARGE_INTEGER StartTime, CurrentTime, Frequency;
ULONG Count = 5; ULONG Count = 5;
#endif #endif
ULONG TargetSet, Processor;
PKPCR Pcr; PKPCR Pcr;
ASSERT(KeGetCurrentIrql() == IPI_LEVEL); ASSERT(KeGetCurrentIrql() == IPI_LEVEL);
@ -61,23 +59,21 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
Pcr = KeGetCurrentKPCR(); Pcr = KeGetCurrentKPCR();
if (Pcr->PrcbData.IpiFrozen & IPI_REQUEST_APC) if (Ke386TestAndClearBit(IPI_REQUEST_APC, &Pcr->PrcbData.IpiFrozen))
{ {
Pcr->PrcbData.IpiFrozen &= ~IPI_REQUEST_APC;
HalRequestSoftwareInterrupt(APC_LEVEL); HalRequestSoftwareInterrupt(APC_LEVEL);
} }
if (Pcr->PrcbData.IpiFrozen & IPI_REQUEST_DPC) if (Ke386TestAndClearBit(IPI_REQUEST_DPC, &Pcr->PrcbData.IpiFrozen))
{ {
Pcr->PrcbData.IpiFrozen &= ~IPI_REQUEST_DPC;
Pcr->PrcbData.DpcInterruptRequested = TRUE; Pcr->PrcbData.DpcInterruptRequested = TRUE;
HalRequestSoftwareInterrupt(DISPATCH_LEVEL); HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
} }
if (Pcr->PrcbData.IpiFrozen & IPI_REQUEST_FUNCTIONCALL) if (Ke386TestAndClearBit(IPI_REQUEST_FUNCTIONCALL, &Pcr->PrcbData.IpiFrozen))
{ {
InterlockedDecrementUL(&Pcr->PrcbData.SignalDone->CurrentPacket[1]); InterlockedDecrementUL(&Pcr->PrcbData.SignalDone->CurrentPacket[1]);
if (Pcr->PrcbData.SignalDone->CurrentPacket[2]) if (InterlockedCompareExchangeUL(&Pcr->PrcbData.SignalDone->CurrentPacket[2], 0, 0))
{ {
#ifdef DBG #ifdef DBG
StartTime = KeQueryPerformanceCounter(&Frequency); StartTime = KeQueryPerformanceCounter(&Frequency);
@ -88,19 +84,15 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
CurrentTime = KeQueryPerformanceCounter(NULL); CurrentTime = KeQueryPerformanceCounter(NULL);
if (CurrentTime.QuadPart > StartTime.QuadPart + Count * Frequency.QuadPart) if (CurrentTime.QuadPart > StartTime.QuadPart + Count * Frequency.QuadPart)
{ {
DPRINT1("Waiting longer than %d seconds to start the ipi routine\n", Count); DbgPrint("(%s:%d) CPU%d, waiting longer than %d seconds to start the ipi routine\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber(), Count);
KEBUGCHECK(0); KEBUGCHECK(0);
} }
#endif #endif
} }
} }
((VOID STDCALL(*)(PVOID))(Pcr->PrcbData.SignalDone->WorkerRoutine))(Pcr->PrcbData.SignalDone->CurrentPacket[0]); ((VOID STDCALL(*)(PVOID))(Pcr->PrcbData.SignalDone->WorkerRoutine))(Pcr->PrcbData.SignalDone->CurrentPacket[0]);
do Ke386TestAndClearBit(KeGetCurrentProcessorNumber(), &Pcr->PrcbData.SignalDone->TargetSet);
{ if (InterlockedCompareExchangeUL(&Pcr->PrcbData.SignalDone->CurrentPacket[2], 0, 0))
Processor = 1 << KeGetCurrentProcessorNumber();
TargetSet = Pcr->PrcbData.SignalDone->TargetSet;
} while (Processor & InterlockedCompareExchangeUL(&Pcr->PrcbData.SignalDone->TargetSet, TargetSet & ~Processor, TargetSet));
if (Pcr->PrcbData.SignalDone->CurrentPacket[2])
{ {
#ifdef DBG #ifdef DBG
StartTime = KeQueryPerformanceCounter(&Frequency); StartTime = KeQueryPerformanceCounter(&Frequency);
@ -111,14 +103,13 @@ KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
CurrentTime = KeQueryPerformanceCounter(NULL); CurrentTime = KeQueryPerformanceCounter(NULL);
if (CurrentTime.QuadPart > StartTime.QuadPart + Count * Frequency.QuadPart) if (CurrentTime.QuadPart > StartTime.QuadPart + Count * Frequency.QuadPart)
{ {
DPRINT1("Waiting longer than %d seconds after executing the ipi routine\n", Count); DbgPrint("(%s:%d) CPU%d, waiting longer than %d seconds after executing the ipi routine\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber(), Count);
KEBUGCHECK(0); KEBUGCHECK(0);
} }
#endif #endif
} }
} }
InterlockedExchangePointer(&Pcr->PrcbData.SignalDone, NULL); InterlockedExchangePointer(&Pcr->PrcbData.SignalDone, NULL);
Pcr->PrcbData.IpiFrozen &= ~IPI_REQUEST_FUNCTIONCALL;
} }
DPRINT("KiIpiServiceRoutine done\n"); DPRINT("KiIpiServiceRoutine done\n");
return TRUE; return TRUE;
@ -136,11 +127,11 @@ KiIpiSendPacket(ULONG TargetSet, VOID STDCALL (*WorkerRoutine)(PVOID), PVOID Arg
ASSERT(KeGetCurrentIrql() == SYNCH_LEVEL); ASSERT(KeGetCurrentIrql() == SYNCH_LEVEL);
CurrentPcr = KeGetCurrentKPCR(); CurrentPcr = KeGetCurrentKPCR();
CurrentPcr->PrcbData.TargetSet = TargetSet; InterlockedExchangeUL(&CurrentPcr->PrcbData.TargetSet, TargetSet);
CurrentPcr->PrcbData.WorkerRoutine = (ULONG_PTR)WorkerRoutine; InterlockedExchangeUL(&CurrentPcr->PrcbData.WorkerRoutine, (ULONG_PTR)WorkerRoutine);
CurrentPcr->PrcbData.CurrentPacket[0] = Argument; InterlockedExchangePointer(&CurrentPcr->PrcbData.CurrentPacket[0], Argument);
CurrentPcr->PrcbData.CurrentPacket[1] = (PVOID)Count; InterlockedExchangeUL(&CurrentPcr->PrcbData.CurrentPacket[1], Count);
CurrentPcr->PrcbData.CurrentPacket[2] = (PVOID)(ULONG)Synchronize; InterlockedExchangeUL(&CurrentPcr->PrcbData.CurrentPacket[2], Synchronize ? 1 : 0);
CurrentProcessor = 1 << KeGetCurrentProcessorNumber(); CurrentProcessor = 1 << KeGetCurrentProcessorNumber();
@ -150,7 +141,7 @@ KiIpiSendPacket(ULONG TargetSet, VOID STDCALL (*WorkerRoutine)(PVOID), PVOID Arg
{ {
Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE); Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
while(0 != InterlockedCompareExchangeUL(&Pcr->PrcbData.SignalDone, (LONG)&CurrentPcr->PrcbData, 0)); while(0 != InterlockedCompareExchangeUL(&Pcr->PrcbData.SignalDone, (LONG)&CurrentPcr->PrcbData, 0));
Pcr->PrcbData.IpiFrozen |= IPI_REQUEST_FUNCTIONCALL; Ke386TestAndSetBit(IPI_REQUEST_FUNCTIONCALL, &Pcr->PrcbData.IpiFrozen);
if (Processor != CurrentProcessor) if (Processor != CurrentProcessor)
{ {
HalRequestIpi(i); HalRequestIpi(i);