mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:35:43 +00:00
- Used interlocked functions to modify the values for the ipi functions on smp machines.
svn path=/trunk/; revision=12689
This commit is contained in:
parent
2d760db23f
commit
7060a9893e
2 changed files with 19 additions and 28 deletions
|
@ -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 ********************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue