ReactOS  0.4.15-dev-1152-g6c94e4f
gate.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for gate.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID FASTCALL KeInitializeGate (IN PKGATE Gate)
 
VOID FASTCALL KeWaitForGate (IN PKGATE Gate, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode)
 
VOID FASTCALL KeSignalGateBoostPriority (IN PKGATE Gate)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file gate.c.

Function Documentation

◆ KeInitializeGate()

VOID FASTCALL KeInitializeGate ( IN PKGATE  Gate)

Definition at line 19 of file gate.c.

20 {
21  /* Initialize the Dispatcher Header */
22  Gate->Header.Type = GateObject;
23  Gate->Header.Signalling = FALSE;
24  Gate->Header.Size = sizeof(KGATE) / sizeof(ULONG);
25  Gate->Header.SignalState = 0;
26  InitializeListHead(&(Gate->Header.WaitListHead));
27 }
#define FALSE
Definition: types.h:117
struct _KGATE KGATE
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int ULONG
Definition: retypes.h:1

◆ KeSignalGateBoostPriority()

VOID FASTCALL KeSignalGateBoostPriority ( IN PKGATE  Gate)

Definition at line 136 of file gate.c.

137 {
138  PKTHREAD WaitThread;
139  PKWAIT_BLOCK WaitBlock;
140  KIRQL OldIrql;
141  ASSERT_GATE(Gate);
143 
144  /* Start entry loop */
145  for (;;)
146  {
147  /* Raise to synch level */
149 
150  /* Lock the gate */
151  KiAcquireDispatcherObject(&Gate->Header);
152 
153  /* Make sure we're not already signaled or that the list is empty */
154  if (Gate->Header.SignalState) break;
155 
156  /* Check if our wait list is empty */
157  if (IsListEmpty(&Gate->Header.WaitListHead))
158  {
159  /* It is, so signal the event */
160  Gate->Header.SignalState = 1;
161  break;
162  }
163  else
164  {
165  /* Get WaitBlock */
166  WaitBlock = CONTAINING_RECORD(Gate->Header.WaitListHead.Flink,
167  KWAIT_BLOCK,
168  WaitListEntry);
169 
170  /* Get the Associated thread */
171  WaitThread = WaitBlock->Thread;
172 
173  /* Check to see if the waiting thread is locked */
174  if (KiTryThreadLock(WaitThread))
175  {
176  /* Unlock the gate */
177  KiReleaseDispatcherObject(&Gate->Header);
178 
179  /* Lower IRQL and loop again */
181  continue;
182  }
183 
184  /* Remove it */
185  RemoveEntryList(&WaitBlock->WaitListEntry);
186 
187  /* Clear wait status */
188  WaitThread->WaitStatus = STATUS_SUCCESS;
189 
190  /* Set state and CPU */
191  WaitThread->State = DeferredReady;
192  WaitThread->DeferredProcessor = KeGetCurrentPrcb()->Number;
193 
194  /* Release the gate lock */
195  KiReleaseDispatcherObject(&Gate->Header);
196 
197  /* Release the thread lock */
198  KiReleaseThreadLock(WaitThread);
199 
200  /* FIXME: Boosting */
201 
202  /* Check if we have a queue */
203  if (WaitThread->Queue)
204  {
205  /* Acquire the dispatcher lock */
207 
208  /* Check if we still have one */
209  if (WaitThread->Queue)
210  {
211  /* Increment active threads */
212  WaitThread->Queue->CurrentCount++;
213  }
214 
215  /* Release lock */
217  }
218 
219  /* Make the thread ready */
220  KiReadyThread(WaitThread);
221 
222  /* Exit the dispatcher */
224  return;
225  }
226  }
227 
228  /* If we got here, then there's no rescheduling. */
229  KiReleaseDispatcherObject(&Gate->Header);
231 }
FORCEINLINE VOID KiReleaseThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:245
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
LIST_ENTRY WaitListEntry
Definition: ketypes.h:444
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1063
struct _KTHREAD * Thread
Definition: ketypes.h:453
FORCEINLINE BOOLEAN KiTryThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:255
#define ASSERT_GATE(Object)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
VOID FASTCALL KiExitDispatcher(KIRQL OldIrql)
VOID NTAPI KiReadyThread(IN PKTHREAD Thread)
Definition: thrdschd.c:429
volatile INT_PTR WaitStatus
Definition: ketypes.h:1689
FORCEINLINE VOID KiAcquireDispatcherObject(IN DISPATCHER_HEADER *Object)
Definition: ke_x.h:127
FORCEINLINE VOID KiReleaseDispatcherObject(IN DISPATCHER_HEADER *Object)
Definition: ke_x.h:137
PKQUEUE Queue
Definition: ketypes.h:1696
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
FORCEINLINE VOID KiReleaseDispatcherLockFromSynchLevel(VOID)
Definition: ke_x.h:169
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
volatile ULONG CurrentCount
Definition: ketypes.h:1288
volatile UCHAR State
Definition: ketypes.h:1679
ULONG DeferredProcessor
Definition: ketypes.h:1796
return STATUS_SUCCESS
Definition: btrfs.c:3014
FORCEINLINE VOID KiAcquireDispatcherLockAtSynchLevel(VOID)
Definition: ke_x.h:160
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: pic.c:156

◆ KeWaitForGate()

VOID FASTCALL KeWaitForGate ( IN PKGATE  Gate,
IN KWAIT_REASON  WaitReason,
IN KPROCESSOR_MODE  WaitMode 
)

Definition at line 31 of file gate.c.

34 {
35  KLOCK_QUEUE_HANDLE ApcLock;
37  PKWAIT_BLOCK GateWaitBlock;
39  PKQUEUE Queue;
40  ASSERT_GATE(Gate);
42 
43  /* Start wait loop */
44  do
45  {
46  /* Acquire the APC lock */
48 
49  /* Check if a kernel APC is pending and we're below APC_LEVEL */
50  if ((Thread->ApcState.KernelApcPending) &&
51  !(Thread->SpecialApcDisable) &&
52  (ApcLock.OldIrql < APC_LEVEL))
53  {
54  /* Release the lock, this will fire the APC */
55  KiReleaseApcLock(&ApcLock);
56  }
57  else
58  {
59  /* Check if we have a queue and lock the dispatcher if so */
60  Queue = Thread->Queue;
62 
63  /* Lock the thread */
65 
66  /* Lock the gate */
67  KiAcquireDispatcherObject(&Gate->Header);
68 
69  /* Check if it's already signaled */
70  if (Gate->Header.SignalState)
71  {
72  /* Unsignal it */
73  Gate->Header.SignalState = 0;
74 
75  /* Release the gate and thread locks */
76  KiReleaseDispatcherObject(&Gate->Header);
78 
79  /* Release the gate lock */
81 
82  /* Release the APC lock and return */
83  KiReleaseApcLock(&ApcLock);
84  break;
85  }
86 
87  /* Setup a Wait Block */
88  GateWaitBlock = &Thread->WaitBlock[0];
89  GateWaitBlock->Object = (PVOID)Gate;
90  GateWaitBlock->Thread = Thread;
91 
92  /* Set the Thread Wait Data */
93  Thread->WaitMode = WaitMode;
94  Thread->WaitReason = WaitReason;
95  Thread->WaitIrql = ApcLock.OldIrql;
96  Thread->State = GateWait;
97  Thread->GateObject = Gate;
98 
99  /* Insert into the Wait List */
100  InsertTailList(&Gate->Header.WaitListHead,
101  &GateWaitBlock->WaitListEntry);
102 
103  /* Release the gate lock */
104  KiReleaseDispatcherObject(&Gate->Header);
105 
106  /* Set swap busy */
108 
109  /* Release the thread lock */
111 
112  /* Check if we had a queue */
113  if (Queue)
114  {
115  /* Wake it up */
116  KiActivateWaiterQueue(Queue);
117 
118  /* Release the dispatcher lock */
120  }
121 
122  /* Release the APC lock but stay at DPC level */
124 
125  /* Find a new thread to run */
127 
128  /* Make sure we weren't executing an APC */
129  if (Status == STATUS_SUCCESS) return;
130  }
131  } while (TRUE);
132 }
FORCEINLINE VOID KiReleaseThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:245
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
LIST_ENTRY WaitListEntry
Definition: ketypes.h:444
#define TRUE
Definition: types.h:120
FORCEINLINE VOID KiSetThreadSwapBusy(IN PKTHREAD Thread)
Definition: ke_x.h:205
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1063
struct _KTHREAD * Thread
Definition: ketypes.h:453
#define InsertTailList(ListHead, Entry)
FORCEINLINE VOID KiReleaseApcLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:630
#define ASSERT_GATE(Object)
void * PVOID
Definition: retypes.h:9
FORCEINLINE VOID KiAcquireThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:235
FORCEINLINE VOID KiAcquireDispatcherObject(IN DISPATCHER_HEADER *Object)
Definition: ke_x.h:127
PVOID Object
Definition: ketypes.h:456
FORCEINLINE VOID KiReleaseDispatcherObject(IN DISPATCHER_HEADER *Object)
Definition: ke_x.h:137
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
Status
Definition: gdiplustypes.h:24
FORCEINLINE VOID KiReleaseDispatcherLockFromSynchLevel(VOID)
Definition: ke_x.h:169
FORCEINLINE VOID KiAcquireApcLockRaiseToSynch(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:602
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FORCEINLINE VOID KiReleaseApcLockFromSynchLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:638
LONG_PTR FASTCALL KiSwapThread(IN PKTHREAD Thread, IN PKPRCB Prcb)
Definition: thrdschd.c:355
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
VOID FASTCALL KiActivateWaiterQueue(IN PKQUEUE Queue)
Definition: queue.c:24
#define KeGetCurrentThread
Definition: hal.h:44
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define APC_LEVEL
Definition: env_spec_w32.h:695
FORCEINLINE VOID KiAcquireDispatcherLockAtSynchLevel(VOID)
Definition: ke_x.h:160