ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ipi.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/ke/ipi.c
00005  * PURPOSE:         Inter-Processor Packet Interface
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include <ntoskrnl.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* GLOBALS *******************************************************************/
00016 
00017 extern KSPIN_LOCK KiReverseStallIpiLock;
00018 
00019 /* PRIVATE FUNCTIONS *********************************************************/
00020 
00021 VOID
00022 NTAPI
00023 KiIpiGenericCallTarget(IN PKIPI_CONTEXT PacketContext,
00024                        IN PVOID BroadcastFunction,
00025                        IN PVOID Argument,
00026                        IN PVOID Count)
00027 {
00028     /* FIXME: TODO */
00029     ASSERTMSG("Not yet implemented\n", FALSE);
00030 }
00031 
00032 VOID
00033 FASTCALL
00034 KiIpiSend(IN KAFFINITY TargetProcessors,
00035           IN ULONG IpiRequest)
00036 {
00037     /* FIXME: TODO */
00038     ASSERTMSG("Not yet implemented\n", FALSE);
00039 }
00040 
00041 VOID
00042 NTAPI
00043 KiIpiSendPacket(IN KAFFINITY TargetProcessors,
00044                 IN PKIPI_WORKER WorkerFunction,
00045                 IN PKIPI_BROADCAST_WORKER BroadcastFunction,
00046                 IN ULONG_PTR Context,
00047                 IN PULONG Count)
00048 {
00049     /* FIXME: TODO */
00050     ASSERTMSG("Not yet implemented\n", FALSE);
00051 }
00052 
00053 VOID
00054 FASTCALL
00055 KiIpiSignalPacketDone(IN PKIPI_CONTEXT PacketContext)
00056 {
00057     /* FIXME: TODO */
00058     ASSERTMSG("Not yet implemented\n", FALSE);
00059 }
00060 
00061 VOID
00062 FASTCALL
00063 KiIpiSignalPacketDoneAndStall(IN PKIPI_CONTEXT PacketContext,
00064                               IN volatile PULONG ReverseStall)
00065 {
00066     /* FIXME: TODO */
00067     ASSERTMSG("Not yet implemented\n", FALSE);
00068 }
00069 
00070 #if 0
00071 VOID
00072 NTAPI
00073 KiIpiSendRequest(IN KAFFINITY TargetSet,
00074                  IN ULONG IpiRequest)
00075 {
00076 #ifdef CONFIG_SMP
00077     LONG i;
00078     PKPRCB Prcb;
00079     KAFFINITY Current;
00080 
00081     for (i = 0, Current = 1; i < KeNumberProcessors; i++, Current <<= 1)
00082     {
00083         if (TargetSet & Current)
00084         {
00085             /* Get the PRCB for this CPU */
00086             Prcb = KiProcessorBlock[i];
00087 
00088             InterlockedBitTestAndSet((PLONG)&Prcb->IpiFrozen, IpiRequest);
00089             HalRequestIpi(i);
00090         }
00091     }
00092 #endif
00093 }
00094 
00095 VOID
00096 NTAPI
00097 KiIpiSendPacket(IN KAFFINITY TargetSet,
00098                 IN PKIPI_BROADCAST_WORKER WorkerRoutine,
00099                 IN ULONG_PTR Argument,
00100                 IN ULONG Count,
00101                 IN BOOLEAN Synchronize)
00102 {
00103 #ifdef CONFIG_SMP
00104     KAFFINITY Processor;
00105     LONG i;
00106     PKPRCB Prcb, CurrentPrcb;
00107     KIRQL oldIrql;
00108 
00109     ASSERT(KeGetCurrentIrql() == SYNCH_LEVEL);
00110 
00111     CurrentPrcb = KeGetCurrentPrcb();
00112     (void)InterlockedExchangeUL(&CurrentPrcb->TargetSet, TargetSet);
00113     (void)InterlockedExchangeUL(&CurrentPrcb->WorkerRoutine, (ULONG_PTR)WorkerRoutine);
00114     (void)InterlockedExchangePointer(&CurrentPrcb->CurrentPacket[0], Argument);
00115     (void)InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[1], Count);
00116     (void)InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[2], Synchronize ? 1 : 0);
00117 
00118     for (i = 0, Processor = 1; i < KeNumberProcessors; i++, Processor <<= 1)
00119     {
00120         if (TargetSet & Processor)
00121         {
00122             Prcb = KiProcessorBlock[i];
00123             while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0));
00124             InterlockedBitTestAndSet((PLONG)&Prcb->IpiFrozen, IPI_SYNCH_REQUEST);
00125             if (Processor != CurrentPrcb->SetMember)
00126             {
00127                 HalRequestIpi(i);
00128             }
00129         }
00130     }
00131     if (TargetSet & CurrentPrcb->SetMember)
00132     {
00133         KeRaiseIrql(IPI_LEVEL, &oldIrql);
00134         KiIpiServiceRoutine(NULL, NULL);
00135         KeLowerIrql(oldIrql);
00136     }
00137 #endif
00138 }
00139 #endif
00140 
00141 /* PUBLIC FUNCTIONS **********************************************************/
00142 
00143 /*
00144  * @implemented
00145  */
00146 BOOLEAN
00147 NTAPI
00148 KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
00149                     IN PKEXCEPTION_FRAME ExceptionFrame)
00150 {
00151 #ifdef CONFIG_SMP
00152     PKPRCB Prcb;
00153     ASSERT(KeGetCurrentIrql() == IPI_LEVEL);
00154 
00155     Prcb = KeGetCurrentPrcb();
00156 
00157     if (InterlockedBitTestAndReset((PLONG)&Prcb->IpiFrozen, IPI_APC))
00158     {
00159         HalRequestSoftwareInterrupt(APC_LEVEL);
00160     }
00161 
00162     if (InterlockedBitTestAndReset((PLONG)&Prcb->IpiFrozen, IPI_DPC))
00163     {
00164         Prcb->DpcInterruptRequested = TRUE;
00165         HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
00166     }
00167 
00168     if (InterlockedBitTestAndReset((PLONG)&Prcb->IpiFrozen, IPI_SYNCH_REQUEST))
00169     {
00170         (void)InterlockedDecrementUL(&Prcb->SignalDone->CurrentPacket[1]);
00171         if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
00172         {
00173             while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[1], 0, 0));
00174         }
00175         ((VOID (NTAPI*)(PVOID))(Prcb->SignalDone->WorkerRoutine))(Prcb->SignalDone->CurrentPacket[0]);
00176         InterlockedBitTestAndReset((PLONG)&Prcb->SignalDone->TargetSet, KeGetCurrentProcessorNumber());
00177         if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
00178         {
00179             while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->TargetSet, 0, 0));
00180         }
00181         (void)InterlockedExchangePointer(&Prcb->SignalDone, NULL);
00182     }
00183 #endif
00184    return TRUE;
00185 }
00186 
00187 /*
00188  * @implemented
00189  */
00190 ULONG_PTR
00191 NTAPI
00192 KeIpiGenericCall(IN PKIPI_BROADCAST_WORKER Function,
00193                  IN ULONG_PTR Argument)
00194 {
00195     ULONG_PTR Status;
00196     KIRQL OldIrql, OldIrql2;
00197 #ifdef CONFIG_SMP
00198     KAFFINITY Affinity;
00199     ULONG Count;
00200     PKPRCB Prcb = KeGetCurrentPrcb();
00201 #endif
00202 
00203     /* Raise to DPC level if required */
00204     OldIrql = KeGetCurrentIrql();
00205     if (OldIrql < DISPATCH_LEVEL) KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
00206 
00207 #ifdef CONFIG_SMP
00208     /* Get current processor count and affinity */
00209     Count = KeNumberProcessors;
00210     Affinity = KeActiveProcessors;
00211 
00212     /* Exclude ourselves */
00213     Affinity &= ~Prcb->SetMember;
00214 #endif
00215 
00216     /* Acquire the IPI lock */
00217     KeAcquireSpinLockAtDpcLevel(&KiReverseStallIpiLock);
00218 
00219 #ifdef CONFIG_SMP
00220     /* Make sure this is MP */
00221     if (Affinity)
00222     {
00223         /* Send an IPI */
00224         KiIpiSendPacket(Affinity,
00225                         KiIpiGenericCallTarget,
00226                         Function,
00227                         Argument,
00228                         &Count);
00229 
00230         /* Spin until the other processors are ready */
00231         while ((volatile ULONG)Count != 1) YieldProcessor();
00232     }
00233 #endif
00234 
00235     /* Raise to IPI level */
00236     KeRaiseIrql(IPI_LEVEL, &OldIrql2);
00237 
00238 #ifdef CONFIG_SMP
00239     /* Let the other processors know it is time */
00240     Count = 0;
00241 #endif
00242 
00243     /* Call the function */
00244     Status = Function(Argument);
00245 
00246 #ifdef CONFIG_SMP
00247     /* If this is MP, wait for the other processors to finish */
00248     if (Affinity)
00249     {
00250         /* Sanity check */
00251         ASSERT(Prcb == (volatile PKPRCB)KeGetCurrentPrcb());
00252 
00253         /* FIXME: TODO */
00254         ASSERTMSG("Not yet implemented\n", FALSE);
00255     }
00256 #endif
00257 
00258     /* Release the lock */
00259     KeReleaseSpinLockFromDpcLevel(&KiReverseStallIpiLock);
00260 
00261     /* Lower IRQL back */
00262     KeLowerIrql(OldIrql);
00263     return Status;
00264 }

Generated on Mon May 28 2012 04:37:26 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.