Author: sginsberg
Date: Sat Nov 1 07:01:58 2008
New Revision: 37127
URL:
http://svn.reactos.org/svn/reactos?rev=37127&view=rev
Log:
- Implement most of SMP KeFlushEntireTb (currently unused though)
- Update KiTbFlushTimeStamp on both UP and MP after flushing
Modified:
trunk/reactos/ntoskrnl/ke/i386/cpu.c
Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/cpu.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/cpu.c [iso-8859-1] Sat Nov 1 07:01:58 2008
@@ -994,6 +994,20 @@
return KeLargestCacheLine;
}
+VOID
+NTAPI
+KiFlushTargetEntireTb(IN PKIPI_CONTEXT PacketContext,
+ IN PVOID Ignored1,
+ IN PVOID Ignored2,
+ IN PVOID Ignored3)
+{
+ /* Signal this packet as done */
+ KiIpiSignalPacketDone(PacketContext);
+
+ /* Flush the TB for the Current CPU */
+ KeFlushCurrentTb();
+}
+
/*
* @implemented
*/
@@ -1003,19 +1017,50 @@
IN BOOLEAN AllProcessors)
{
KIRQL OldIrql;
+#ifdef CONFIG_SMP
+ KAFFINITY TargetAffinity;
+ PKPRCB Prcb = KeGetCurrentPrcb();
+#endif
/* Raise the IRQL for the TB Flush */
OldIrql = KeRaiseIrqlToSynchLevel();
#ifdef CONFIG_SMP
- /* FIXME: Support IPI Flush */
-#error Not yet implemented!
+ /* FIXME: Use KiTbFlushTimeStamp to synchronize TB flush */
+
+ /* Get the current processor affinity, and exclude ourselves */
+ TargetAffinity = KeActiveProcessors;
+ TargetAffinity &= ~KeGetCurrentPrcb()->SetMember;
+
+ /* Make sure this is MP */
+ if (TargetAffinity)
+ {
+ /* Send an IPI TB flush to the other processors */
+ KiIpiSendPacket(TargetAffinity,
+ KiFlushTargetEntireTb,
+ NULL,
+ 0,
+ NULL);
+ }
#endif
- /* Flush the TB for the Current CPU */
+ /* Flush the TB for the Current CPU, and update the flush stamp */
KeFlushCurrentTb();
- /* Return to Original IRQL */
+#ifdef CONFIG_SMP
+ /* If this is MP, wait for the other processors to finish */
+ if (TargetAffinity)
+ {
+ /* Sanity check */
+ ASSERT(Prcb == (volatile PKPRCB)KeGetCurrentPrcb());
+
+ /* FIXME: TODO */
+ ASSERTMSG("Not yet implemented\n", FALSE);
+ }
+#endif
+
+ /* Update the flush stamp and return to original IRQL */
+ InterlockedExchangeAdd(&KiTbFlushTimeStamp, 1);
KeLowerIrql(OldIrql);
}