ReactOS 0.4.15-dev-5875-g7c755d9
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
21VOID
24 IN PVOID BroadcastFunction,
25 IN PVOID Argument,
27{
28 /* FIXME: TODO */
29 ASSERTMSG("Not yet implemented\n", FALSE);
30}
31
32VOID
34KiIpiSend(IN KAFFINITY TargetProcessors,
35 IN ULONG IpiRequest)
36{
37 /* FIXME: TODO */
38 ASSERTMSG("Not yet implemented\n", FALSE);
39}
40
41VOID
43KiIpiSendPacket(IN KAFFINITY TargetProcessors,
44 IN PKIPI_WORKER WorkerFunction,
45 IN PKIPI_BROADCAST_WORKER BroadcastFunction,
48{
49 /* FIXME: TODO */
50 ASSERTMSG("Not yet implemented\n", FALSE);
51}
52
53VOID
56{
57 /* FIXME: TODO */
58 ASSERTMSG("Not yet implemented\n", FALSE);
59}
60
61VOID
64 IN volatile PULONG ReverseStall)
65{
66 /* FIXME: TODO */
67 ASSERTMSG("Not yet implemented\n", FALSE);
68}
69
70#if 0
71VOID
73KiIpiSendRequest(IN KAFFINITY TargetSet,
74 IN ULONG IpiRequest)
75{
76#ifdef CONFIG_SMP
77 LONG i;
78 PKPRCB Prcb;
79 KAFFINITY Current;
80
81 for (i = 0, Current = 1; i < KeNumberProcessors; i++, Current <<= 1)
82 {
83 if (TargetSet & Current)
84 {
85 /* Get the PRCB for this CPU */
86 Prcb = KiProcessorBlock[i];
87
88 InterlockedBitTestAndSet((PLONG)&Prcb->IpiFrozen, IpiRequest);
90 }
91 }
92#endif
93}
94
95VOID
99 IN ULONG_PTR Argument,
100 IN ULONG Count,
102{
103#ifdef CONFIG_SMP
105 LONG i;
106 PKPRCB Prcb, CurrentPrcb;
107 KIRQL oldIrql;
108
110
111 CurrentPrcb = KeGetCurrentPrcb();
112 (void)InterlockedExchangeUL(&CurrentPrcb->TargetSet, TargetSet);
114 (void)InterlockedExchangePointer(&CurrentPrcb->CurrentPacket[0], Argument);
115 (void)InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[1], Count);
116 (void)InterlockedExchangeUL(&CurrentPrcb->CurrentPacket[2], Synchronize ? 1 : 0);
117
118 for (i = 0, Processor = 1; i < KeNumberProcessors; i++, Processor <<= 1)
119 {
120 if (TargetSet & Processor)
121 {
122 Prcb = KiProcessorBlock[i];
123 while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0));
125 if (Processor != CurrentPrcb->SetMember)
126 {
128 }
129 }
130 }
131 if (TargetSet & CurrentPrcb->SetMember)
132 {
133 KeRaiseIrql(IPI_LEVEL, &oldIrql);
135 KeLowerIrql(oldIrql);
136 }
137#endif
138}
139#endif
140
141/* PUBLIC FUNCTIONS **********************************************************/
142
143/*
144 * @implemented
145 */
147NTAPI
149 IN PKEXCEPTION_FRAME ExceptionFrame)
150{
151#ifdef CONFIG_SMP
152 PKPRCB Prcb;
154
155 Prcb = KeGetCurrentPrcb();
156
158 {
160 }
161
163 {
166 }
167
169 {
170#if defined(_M_ARM) || defined(_M_AMD64)
172#else
173 (void)InterlockedDecrementUL(&Prcb->SignalDone->CurrentPacket[1]);
174 if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
175 {
176 while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[1], 0, 0));
177 }
178 ((VOID (NTAPI*)(PVOID))(Prcb->SignalDone->WorkerRoutine))(Prcb->SignalDone->CurrentPacket[0]);
180 if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
181 {
182 while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->TargetSet, 0, 0));
183 }
185#endif // _M_ARM
186 }
187#endif
188 return TRUE;
189}
190
191/*
192 * @implemented
193 */
195NTAPI
197 IN ULONG_PTR Argument)
198{
200 KIRQL OldIrql, OldIrql2;
201#ifdef CONFIG_SMP
203 ULONG Count;
204 PKPRCB Prcb = KeGetCurrentPrcb();
205#endif
206
207 /* Raise to DPC level if required */
210
211#ifdef CONFIG_SMP
212 /* Get current processor count and affinity */
215
216 /* Exclude ourselves */
217 Affinity &= ~Prcb->SetMember;
218#endif
219
220 /* Acquire the IPI lock */
222
223#ifdef CONFIG_SMP
224 /* Make sure this is MP */
225 if (Affinity)
226 {
227 /* Send an IPI */
230 Function,
231 Argument,
232 &Count);
233
234 /* Spin until the other processors are ready */
235 while (Count != 1)
236 {
239 }
240 }
241#endif
242
243 /* Raise to IPI level */
244 KeRaiseIrql(IPI_LEVEL, &OldIrql2);
245
246#ifdef CONFIG_SMP
247 /* Let the other processors know it is time */
248 Count = 0;
249#endif
250
251 /* Call the function */
252 Status = Function(Argument);
253
254#ifdef CONFIG_SMP
255 /* If this is MP, wait for the other processors to finish */
256 if (Affinity)
257 {
258 /* Sanity check */
259 ASSERT(Prcb == KeGetCurrentPrcb());
260
261 /* FIXME: TODO */
262 ASSERTMSG("Not yet implemented\n", FALSE);
263 }
264#endif
265
266 /* Release the lock */
268
269 /* Lower IRQL back */
271 return Status;
272}
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:1523
#define InterlockedCompareExchangeUL(Destination, Exchange, Comperand)
Definition: ex.h:1535
#define InterlockedExchangeUL(Target, Value)
Definition: ex.h:1529
_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(KAFFINITY TargetProcessors)
Definition: processor.c:96
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define InterlockedBitTestAndSet
Definition: interlocked.h:30
#define InterlockedBitTestAndReset
Definition: interlocked.h:35
VOID NTAPI KiIpiGenericCallTarget(IN PKIPI_CONTEXT PacketContext, IN PVOID BroadcastFunction, IN PVOID Argument, IN PVOID Count)
Definition: ipi.c:23
KSPIN_LOCK KiReverseStallIpiLock
Definition: krnlinit.c:64
ULONG_PTR NTAPI KeIpiGenericCall(IN PKIPI_BROADCAST_WORKER Function, IN ULONG_PTR Argument)
Definition: ipi.c:196
VOID FASTCALL KiIpiSignalPacketDoneAndStall(IN PKIPI_CONTEXT PacketContext, IN volatile PULONG ReverseStall)
Definition: ipi.c:63
VOID FASTCALL KiIpiSignalPacketDone(IN PKIPI_CONTEXT PacketContext)
Definition: ipi.c:55
BOOLEAN NTAPI KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
Definition: ipi.c:148
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:43
VOID FASTCALL KiIpiSend(IN KAFFINITY TargetProcessors, IN ULONG IpiRequest)
Definition: ipi.c:34
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1080
#define IPI_SYNCH_REQUEST
Definition: ketypes.h:240
#define IPI_DPC
Definition: ketypes.h:237
#define IPI_APC
Definition: ketypes.h:236
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
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:337
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
UCHAR DpcInterruptRequested
Definition: ketypes.h:691
UINT64 SetMember
Definition: ketypes.h:583
volatile PKIPI_WORKER WorkerRoutine
Definition: ketypes.h:617
UINT64 TargetSet
Definition: ketypes.h:675
volatile struct _KPRCB * SignalDone
Definition: ketypes.h:621
ULONG IpiFrozen
Definition: ketypes.h:676
volatile PVOID CurrentPacket[3]
Definition: ketypes.h:615
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:792
_In_ UCHAR Processor
Definition: kefuncs.h:684
VOID(NTAPI * PKIPI_WORKER)(IN OUT PKIPI_CONTEXT PacketContext, IN PVOID Parameter1 OPTIONAL, IN PVOID Parameter2 OPTIONAL, IN PVOID Parameter3 OPTIONAL)
Definition: ketypes.h:576
KIPI_BROADCAST_WORKER * PKIPI_BROADCAST_WORKER
Definition: ketypes.h:605