Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenipi.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
1.7.6.1
|