ReactOS 0.4.15-dev-7711-g5627da4
ipi.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ke/ipi.c
5 * PURPOSE: Inter-Processor Packet Interface
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
15/* GLOBALS *******************************************************************/
16
18
19/* PRIVATE FUNCTIONS *********************************************************/
20
21#ifndef _M_AMD64
22
23VOID
26 IN PVOID BroadcastFunction,
27 IN PVOID Argument,
29{
30 /* FIXME: TODO */
31 ASSERTMSG("Not yet implemented\n", FALSE);
32}
33
34VOID
36KiIpiSend(IN KAFFINITY TargetProcessors,
37 IN ULONG IpiRequest)
38{
39 /* FIXME: TODO */
40 ASSERTMSG("Not yet implemented\n", FALSE);
41}
42
43VOID
45KiIpiSendPacket(IN KAFFINITY TargetProcessors,
46 IN PKIPI_WORKER WorkerFunction,
47 IN PKIPI_BROADCAST_WORKER BroadcastFunction,
50{
51 /* FIXME: TODO */
52 ASSERTMSG("Not yet implemented\n", FALSE);
53}
54
55VOID
58{
59 /* FIXME: TODO */
60 ASSERTMSG("Not yet implemented\n", FALSE);
61}
62
63VOID
66 IN volatile PULONG ReverseStall)
67{
68 /* FIXME: TODO */
69 ASSERTMSG("Not yet implemented\n", FALSE);
70}
71
72#if 0
73VOID
75KiIpiSendRequest(IN KAFFINITY TargetSet,
76 IN ULONG IpiRequest)
77{
78#ifdef CONFIG_SMP
79 LONG i;
80 PKPRCB Prcb;
81 KAFFINITY Current;
82
83 for (i = 0, Current = 1; i < KeNumberProcessors; i++, Current <<= 1)
84 {
85 if (TargetSet & Current)
86 {
87 /* Get the PRCB for this CPU */
88 Prcb = KiProcessorBlock[i];
89
90 InterlockedBitTestAndSet((PLONG)&Prcb->IpiFrozen, IpiRequest);
92 }
93 }
94#endif
95}
96
97VOID
101 IN ULONG_PTR Argument,
102 IN ULONG Count,
104{
105#ifdef CONFIG_SMP
107 LONG i;
108 PKPRCB Prcb, CurrentPrcb;
109 KIRQL oldIrql;
110
112
113 CurrentPrcb = KeGetCurrentPrcb();
114 (void)InterlockedExchangeUL(&CurrentPrcb->TargetSet, TargetSet);
116 (void)InterlockedExchangePointer(&CurrentPrcb->CurrentPacket[0], Argument);
117 (void)InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[1], Count);
118 (void)InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[2], Synchronize ? 1 : 0);
119
120 for (i = 0, Processor = 1; i < KeNumberProcessors; i++, Processor <<= 1)
121 {
122 if (TargetSet & Processor)
123 {
124 Prcb = KiProcessorBlock[i];
125 while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0));
127 if (Processor != CurrentPrcb->SetMember)
128 {
130 }
131 }
132 }
133 if (TargetSet & CurrentPrcb->SetMember)
134 {
135 KeRaiseIrql(IPI_LEVEL, &oldIrql);
137 KeLowerIrql(oldIrql);
138 }
139#endif
140}
141#endif
142
143/* PUBLIC FUNCTIONS **********************************************************/
144
145/*
146 * @implemented
147 */
149NTAPI
151 IN PKEXCEPTION_FRAME ExceptionFrame)
152{
153#ifdef CONFIG_SMP
154 PKPRCB Prcb;
156
157 Prcb = KeGetCurrentPrcb();
158
160 {
162 }
163
165 {
168 }
169
171 {
172#if defined(_M_ARM) || defined(_M_AMD64)
174#else
175 (void)InterlockedDecrementUL(&Prcb->SignalDone->CurrentPacket[1]);
176 if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
177 {
178 while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[1], 0, 0));
179 }
180 ((VOID (NTAPI*)(PVOID))(Prcb->SignalDone->WorkerRoutine))(Prcb->SignalDone->CurrentPacket[0]);
182 if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
183 {
184 while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->TargetSet, 0, 0));
185 }
187#endif // _M_ARM
188 }
189#endif
190 return TRUE;
191}
192
193/*
194 * @implemented
195 */
197NTAPI
199 IN ULONG_PTR Argument)
200{
202 KIRQL OldIrql, OldIrql2;
203#ifdef CONFIG_SMP
205 ULONG Count;
206 PKPRCB Prcb = KeGetCurrentPrcb();
207#endif
208
209 /* Raise to DPC level if required */
212
213#ifdef CONFIG_SMP
214 /* Get current processor count and affinity */
217
218 /* Exclude ourselves */
219 Affinity &= ~Prcb->SetMember;
220#endif
221
222 /* Acquire the IPI lock */
224
225#ifdef CONFIG_SMP
226 /* Make sure this is MP */
227 if (Affinity)
228 {
229 /* Send an IPI */
232 Function,
233 Argument,
234 &Count);
235
236 /* Spin until the other processors are ready */
237 while (Count != 1)
238 {
241 }
242 }
243#endif
244
245 /* Raise to IPI level */
246 KeRaiseIrql(IPI_LEVEL, &OldIrql2);
247
248#ifdef CONFIG_SMP
249 /* Let the other processors know it is time */
250 Count = 0;
251#endif
252
253 /* Call the function */
254 Status = Function(Argument);
255
256#ifdef CONFIG_SMP
257 /* If this is MP, wait for the other processors to finish */
258 if (Affinity)
259 {
260 /* Sanity check */
261 ASSERT(Prcb == KeGetCurrentPrcb());
262
263 /* FIXME: TODO */
264 ASSERTMSG("Not yet implemented\n", FALSE);
265 }
266#endif
267
268 /* Release the lock */
270
271 /* Lower IRQL back */
273 return Status;
274}
275
276#endif // !_M_AMD64
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG_PTR KAFFINITY
Definition: compat.h:85
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define SYNCH_LEVEL
Definition: env_spec_w32.h:704
#define IPI_LEVEL
Definition: env_spec_w32.h:701
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define InterlockedDecrementUL(Addend)
Definition: ex.h:1524
#define InterlockedCompareExchangeUL(Destination, Exchange, Comperand)
Definition: ex.h:1536
#define InterlockedExchangeUL(Target, Value)
Definition: ex.h:1530
_Must_inspect_result_ _In_ PFLT_CALLBACK_DATA _In_ PFLT_DEFERRED_IO_WORKITEM_ROUTINE WorkerRoutine
Definition: fltkernel.h:1977
return pFxInterrupt Synchronize(Callback, Context)
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Irql)
Definition: pic.c:271
VOID NTAPI HalRequestIpi(_In_ KAFFINITY TargetProcessors)
Definition: ipi.c:20
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define InterlockedBitTestAndSet
Definition: interlocked.h:30
#define InterlockedBitTestAndReset
Definition: interlocked.h:35
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1148
#define IPI_SYNCH_REQUEST
Definition: ketypes.h:301
#define IPI_DPC
Definition: ketypes.h:298
#define IPI_APC
Definition: ketypes.h:297
int Count
Definition: noreturn.cpp:7
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define FASTCALL
Definition: nt_native.h:50
PKPRCB KiProcessorBlock[]
Definition: krnlinit.c:32
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
ULONG_PTR NTAPI KeIpiGenericCall(_In_ PKIPI_BROADCAST_WORKER Function, _In_ ULONG_PTR Argument)
Definition: ipi.c:44
VOID FASTCALL KiIpiSend(_In_ KAFFINITY TargetSet, _In_ ULONG IpiRequest)
Definition: ipi.c:18
VOID NTAPI KiIpiGenericCallTarget(IN PKIPI_CONTEXT PacketContext, IN PVOID BroadcastFunction, IN PVOID Argument, IN PVOID Count)
Definition: ipi.c:25
KSPIN_LOCK KiReverseStallIpiLock
Definition: krnlinit.c:64
VOID FASTCALL KiIpiSignalPacketDoneAndStall(IN PKIPI_CONTEXT PacketContext, IN volatile PULONG ReverseStall)
Definition: ipi.c:65
VOID FASTCALL KiIpiSignalPacketDone(IN PKIPI_CONTEXT PacketContext)
Definition: ipi.c:57
BOOLEAN NTAPI KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
Definition: ipi.c:150
VOID NTAPI KiIpiSendPacket(IN KAFFINITY TargetProcessors, IN PKIPI_WORKER WorkerFunction, IN PKIPI_BROADCAST_WORKER BroadcastFunction, IN ULONG_PTR Context, IN PULONG Count)
Definition: ipi.c:45
long LONG
Definition: pedump.c:60
#define KeMemoryBarrierWithoutFence()
Definition: ke.h:66
#define YieldProcessor
Definition: ke.h:48
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:341
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
UCHAR DpcInterruptRequested
Definition: ketypes.h:756
UINT64 SetMember
Definition: ketypes.h:648
volatile PKIPI_WORKER WorkerRoutine
Definition: ketypes.h:668
UINT64 TargetSet
Definition: ketypes.h:740
volatile struct _KPRCB * SignalDone
Definition: ketypes.h:672
ULONG IpiFrozen
Definition: ketypes.h:741
volatile PVOID CurrentPacket[3]
Definition: ketypes.h:666
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
_In_ UCHAR Processor
Definition: kefuncs.h:670
VOID(NTAPI * PKIPI_WORKER)(IN OUT PKIPI_CONTEXT PacketContext, IN PVOID Parameter1 OPTIONAL, IN PVOID Parameter2 OPTIONAL, IN PVOID Parameter3 OPTIONAL)
Definition: ketypes.h:588
KIPI_BROADCAST_WORKER * PKIPI_BROADCAST_WORKER
Definition: ketypes.h:617