ReactOS 0.4.16-dev-319-g6cf4263
thrdobj.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for thrdobj.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

UCHAR NTAPI KeFindNextRightSetAffinity (IN UCHAR Number, IN KAFFINITY Set)
 
BOOLEAN NTAPI KeReadStateThread (IN PKTHREAD Thread)
 
KPRIORITY NTAPI KeQueryBasePriorityThread (IN PKTHREAD Thread)
 
BOOLEAN NTAPI KeSetDisableBoostThread (IN OUT PKTHREAD Thread, IN BOOLEAN Disable)
 
VOID NTAPI KeReadyThread (IN PKTHREAD Thread)
 
ULONG NTAPI KeAlertResumeThread (IN PKTHREAD Thread)
 
BOOLEAN NTAPI KeAlertThread (IN PKTHREAD Thread, IN KPROCESSOR_MODE AlertMode)
 
VOID NTAPI KeBoostPriorityThread (IN PKTHREAD Thread, IN KPRIORITY Increment)
 
ULONG NTAPI KeForceResumeThread (IN PKTHREAD Thread)
 
VOID NTAPI KeFreezeAllThreads (VOID)
 
ULONG NTAPI KeResumeThread (IN PKTHREAD Thread)
 
VOID NTAPI KeRundownThread (VOID)
 
VOID NTAPI KeStartThread (IN OUT PKTHREAD Thread)
 
VOID NTAPI KiSuspendRundown (IN PKAPC Apc)
 
VOID NTAPI KiSuspendNop (IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
 
VOID NTAPI KiSuspendThread (IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
ULONG NTAPI KeSuspendThread (PKTHREAD Thread)
 
VOID NTAPI KeThawAllThreads (VOID)
 
BOOLEAN NTAPI KeTestAlertThread (IN KPROCESSOR_MODE AlertMode)
 
NTSTATUS NTAPI KeInitThread (IN OUT PKTHREAD Thread, IN PVOID KernelStack, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext, IN PCONTEXT Context, IN PVOID Teb, IN PKPROCESS Process)
 
VOID NTAPI KeInitializeThread (IN PKPROCESS Process, IN OUT PKTHREAD Thread, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext, IN PCONTEXT Context, IN PVOID Teb, IN PVOID KernelStack)
 
VOID NTAPI KeUninitThread (IN PKTHREAD Thread)
 
VOID NTAPI KeCapturePersistentThreadState (IN PVOID CurrentThread, IN ULONG Setting1, IN ULONG Setting2, IN ULONG Setting3, IN ULONG Setting4, IN ULONG Setting5, IN PVOID ThreadState)
 
PKTHREAD NTAPI KeGetCurrentThread (VOID)
 
UCHAR NTAPI KeGetPreviousMode (VOID)
 
ULONG NTAPI KeQueryRuntimeThread (IN PKTHREAD Thread, OUT PULONG UserTime)
 
BOOLEAN NTAPI KeSetKernelStackSwapEnable (IN BOOLEAN Enable)
 
KPRIORITY NTAPI KeQueryPriorityThread (IN PKTHREAD Thread)
 
VOID NTAPI KeRevertToUserAffinityThread (VOID)
 
UCHAR NTAPI KeSetIdealProcessorThread (IN PKTHREAD Thread, IN UCHAR Processor)
 
VOID NTAPI KeSetSystemAffinityThread (IN KAFFINITY Affinity)
 
LONG NTAPI KeSetBasePriorityThread (IN PKTHREAD Thread, IN LONG Increment)
 
KAFFINITY NTAPI KeSetAffinityThread (IN PKTHREAD Thread, IN KAFFINITY Affinity)
 
KPRIORITY NTAPI KeSetPriorityThread (IN PKTHREAD Thread, IN KPRIORITY Priority)
 
VOID NTAPI KeTerminateThread (IN KPRIORITY Increment)
 

Variables

EX_WORK_QUEUE ExWorkerQueue [MaximumWorkQueue]
 
LIST_ENTRY PspReaperListHead
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file thrdobj.c.

Function Documentation

◆ KeAlertResumeThread()

ULONG NTAPI KeAlertResumeThread ( IN PKTHREAD  Thread)

Definition at line 124 of file thrdobj.c.

125{
126 ULONG PreviousCount;
127 KLOCK_QUEUE_HANDLE ApcLock;
130
131 /* Lock the Dispatcher Database and the APC Queue */
134
135 /* Return if Thread is already alerted. */
136 if (!Thread->Alerted[KernelMode])
137 {
138 /* If it's Blocked, unblock if it we should */
139 if ((Thread->State == Waiting) && (Thread->Alertable))
140 {
141 /* Abort the wait */
143 }
144 else
145 {
146 /* If not, simply Alert it */
147 Thread->Alerted[KernelMode] = TRUE;
148 }
149 }
150
151 /* Save the old Suspend Count */
152 PreviousCount = Thread->SuspendCount;
153
154 /* If the thread is suspended, decrease one of the suspend counts */
155 if (PreviousCount)
156 {
157 /* Decrease count. If we are now zero, unwait it completely */
158 Thread->SuspendCount--;
159 if (!(Thread->SuspendCount) && !(Thread->FreezeCount))
160 {
161 /* Signal and satisfy */
162 Thread->SuspendSemaphore.Header.SignalState++;
163 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
164 }
165 }
166
167 /* Release Locks and return the Old State */
170 KiExitDispatcher(ApcLock.OldIrql);
171 return PreviousCount;
172}
#define TRUE
Definition: types.h:120
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
FORCEINLINE VOID KiAcquireApcLockRaiseToSynch(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:607
FORCEINLINE VOID KiReleaseDispatcherLockFromSynchLevel(VOID)
Definition: ke_x.h:174
FORCEINLINE VOID KiAcquireDispatcherLockAtSynchLevel(VOID)
Definition: ke_x.h:165
FORCEINLINE VOID KiReleaseApcLockFromSynchLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:643
#define KernelMode
Definition: asm.h:34
@ Waiting
Definition: ketypes.h:393
#define THREAD_ALERT_INCREMENT
Definition: ketypes.h:126
#define ASSERT_THREAD(object)
Definition: ketypes.h:2076
VOID FASTCALL KiUnwaitThread(IN PKTHREAD Thread, IN LONG_PTR WaitStatus, IN KPRIORITY Increment)
Definition: wait.c:89
VOID FASTCALL KiWaitTest(PVOID Object, KPRIORITY Increment)
VOID FASTCALL KiExitDispatcher(KIRQL OldIrql)
#define STATUS_ALERTED
Definition: ntstatus.h:80
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
uint32_t ULONG
Definition: typedefs.h:59
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by NtAlertResumeThread().

◆ KeAlertThread()

BOOLEAN NTAPI KeAlertThread ( IN PKTHREAD  Thread,
IN KPROCESSOR_MODE  AlertMode 
)

Definition at line 176 of file thrdobj.c.

178{
180 KLOCK_QUEUE_HANDLE ApcLock;
183
184 /* Lock the Dispatcher Database and the APC Queue */
187
188 /* Save the Previous State */
189 PreviousState = Thread->Alerted[AlertMode];
190
191 /* Check if it's already alerted */
192 if (!PreviousState)
193 {
194 /* Check if the thread is alertable, and blocked in the given mode */
195 if ((Thread->State == Waiting) &&
196 (Thread->Alertable) &&
197 (AlertMode <= Thread->WaitMode))
198 {
199 /* Abort the wait to alert the thread */
201 }
202 else
203 {
204 /* Otherwise, merely set the alerted state */
205 Thread->Alerted[AlertMode] = TRUE;
206 }
207 }
208
209 /* Release the Dispatcher Lock */
212 KiExitDispatcher(ApcLock.OldIrql);
213
214 /* Return the old state */
215 return PreviousState;
216}
unsigned char BOOLEAN
_In_ WDF_POWER_DEVICE_STATE PreviousState
Definition: wdfdevice.h:829

Referenced by NtAlertThread().

◆ KeBoostPriorityThread()

VOID NTAPI KeBoostPriorityThread ( IN PKTHREAD  Thread,
IN KPRIORITY  Increment 
)

Definition at line 220 of file thrdobj.c.

222{
226
227 /* Lock the Dispatcher Database */
229
230 /* Only threads in the dynamic range get boosts */
231 if (Thread->Priority < LOW_REALTIME_PRIORITY)
232 {
233 /* Lock the thread */
235
236 /* Check again, and make sure there's not already a boost */
237 if ((Thread->Priority < LOW_REALTIME_PRIORITY) &&
238 !(Thread->PriorityDecrement))
239 {
240 /* Compute the new priority and see if it's higher */
241 Priority = Thread->BasePriority + Increment;
242 if (Priority > Thread->Priority)
243 {
245 {
247 }
248
249 /* Reset the quantum */
250 Thread->Quantum = Thread->QuantumReset;
251
252 /* Set the new Priority */
254 }
255 }
256
257 /* Release thread lock */
259 }
260
261 /* Release the dispatcher lokc */
263}
LONG KPRIORITY
Definition: compat.h:803
UCHAR KIRQL
Definition: env_spec_w32.h:591
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:46
#define LOW_REALTIME_PRIORITY
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:157
FORCEINLINE VOID KiAcquireThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:240
FORCEINLINE VOID KiReleaseThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:250
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:149
VOID FASTCALL KiSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdschd.c:511
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by NtSetInformationProcess().

◆ KeCapturePersistentThreadState()

VOID NTAPI KeCapturePersistentThreadState ( IN PVOID  CurrentThread,
IN ULONG  Setting1,
IN ULONG  Setting2,
IN ULONG  Setting3,
IN ULONG  Setting4,
IN ULONG  Setting5,
IN PVOID  ThreadState 
)

Definition at line 931 of file thrdobj.c.

938{
940}
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15

◆ KeFindNextRightSetAffinity()

UCHAR NTAPI KeFindNextRightSetAffinity ( IN UCHAR  Number,
IN KAFFINITY  Set 
)

Definition at line 22 of file thrdobj.c.

24{
25 KAFFINITY Bit;
27 ASSERT(Set != 0);
28
29 /* Calculate the mask */
30 Bit = (AFFINITY_MASK(Number) - 1) & Set;
31
32 /* If it's 0, use the one we got */
33 if (!Bit) Bit = Set;
34
35 /* Now find the right set and return it */
37 return (UCHAR)Result;
38}
ULONG_PTR KAFFINITY
Definition: compat.h:85
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE KAFFINITY AFFINITY_MASK(ULONG Index)
Definition: kefuncs.h:39
FORCEINLINE BOOLEAN BitScanReverseAffinity(PULONG Index, KAFFINITY Mask)
Definition: kefuncs.h:54
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:207
static BOOL Set
Definition: pageheap.c:10
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by KeInitializeProcess(), and KeStartThread().

◆ KeForceResumeThread()

ULONG NTAPI KeForceResumeThread ( IN PKTHREAD  Thread)

Definition at line 267 of file thrdobj.c.

268{
269 KLOCK_QUEUE_HANDLE ApcLock;
270 ULONG PreviousCount;
273
274 /* Lock the APC Queue */
276
277 /* Save the old Suspend Count */
278 PreviousCount = Thread->SuspendCount + Thread->FreezeCount;
279
280 /* If the thread is suspended, wake it up!!! */
281 if (PreviousCount)
282 {
283 /* Unwait it completely */
284 Thread->SuspendCount = 0;
285 Thread->FreezeCount = 0;
286
287 /* Lock the dispatcher */
289
290 /* Signal and satisfy */
291 Thread->SuspendSemaphore.Header.SignalState++;
292 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
293
294 /* Release the dispatcher */
296 }
297
298 /* Release Lock and return the Old State */
300 KiExitDispatcher(ApcLock.OldIrql);
301 return PreviousCount;
302}

Referenced by PspCreateThread(), PspExitThread(), PspTerminateThreadByPointer(), and PsSuspendThread().

◆ KeFreezeAllThreads()

VOID NTAPI KeFreezeAllThreads ( VOID  )

Definition at line 306 of file thrdobj.c.

307{
309 PKTHREAD Current, CurrentThread = KeGetCurrentThread();
310 PKPROCESS Process = CurrentThread->ApcState.Process;
311 PLIST_ENTRY ListHead, NextEntry;
312 LONG OldCount;
314
315 /* Lock the process */
317
318 /* If someone is already trying to free us, try again */
319 while (CurrentThread->FreezeCount)
320 {
321 /* Release and re-acquire the process lock so the APC will go through */
324 }
325
326 /* Enter a critical region */
328
329 /* Loop the Process's Threads */
330 ListHead = &Process->ThreadListHead;
331 NextEntry = ListHead->Flink;
332 do
333 {
334 /* Get the current thread */
335 Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
336
337 /* Lock it */
338 KiAcquireApcLockAtSynchLevel(Current, &ApcLock);
339
340 /* Make sure it's not ours, and check if APCs are enabled */
341 if ((Current != CurrentThread) && (Current->ApcQueueable))
342 {
343 /* Sanity check */
344 OldCount = Current->SuspendCount;
345 ASSERT(OldCount != MAXIMUM_SUSPEND_COUNT);
346
347 /* Increase the freeze count */
348 Current->FreezeCount++;
349
350 /* Make sure it wasn't already suspended */
351 if (!(OldCount) && !(Current->SuspendCount))
352 {
353 /* Did we already insert it? */
354 if (!Current->SuspendApc.Inserted)
355 {
356 /* Insert the APC */
357 Current->SuspendApc.Inserted = TRUE;
358 KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT);
359 }
360 else
361 {
362 /* Lock the dispatcher */
364
365 /* Unsignal the semaphore, the APC was already inserted */
366 Current->SuspendSemaphore.Header.SignalState--;
367
368 /* Release the dispatcher */
370 }
371 }
372 }
373
374 /* Release the APC lock */
376
377 /* Move to the next thread */
378 NextEntry = NextEntry->Flink;
379 } while (NextEntry != ListHead);
380
381 /* Release the process lock and exit the dispatcher */
384}
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define KeGetCurrentThread
Definition: hal.h:55
FORCEINLINE VOID KiReleaseProcessLockFromSynchLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:668
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
FORCEINLINE VOID KiReleaseProcessLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:660
FORCEINLINE VOID KiAcquireApcLockAtSynchLevel(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:616
FORCEINLINE VOID KiAcquireProcessLockRaiseToSynch(IN PKPROCESS Process, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:651
VOID FASTCALL KiInsertQueueApc(IN PKAPC Apc, IN KPRIORITY PriorityBoost)
Definition: apc.c:85
long LONG
Definition: pedump.c:60
ULONG FreezeCount
Definition: ketypes.h:1737
DISPATCHER_HEADER Header
Definition: ketypes.h:1661
CHAR SuspendCount
Definition: ketypes.h:1965
KAPC_STATE ApcState
Definition: ketypes.h:1778
ULONG ApcQueueable
Definition: ketypes.h:1711
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define MAXIMUM_SUSPEND_COUNT
Definition: winbase.h:431
*LockHandle LockHandle _Out_ PKLOCK_QUEUE_HANDLE LockHandle
Definition: kefuncs.h:717

Referenced by DbgkpSuspendProcess().

◆ KeGetCurrentThread()

PKTHREAD NTAPI KeGetCurrentThread ( VOID  )

Definition at line 948 of file thrdobj.c.

949{
950 /* Return the current thread on this PCR */
951 return _KeGetCurrentThread();
952}
#define _KeGetCurrentThread()
Definition: ketypes.h:1111

◆ KeGetPreviousMode()

UCHAR NTAPI KeGetPreviousMode ( VOID  )

Definition at line 960 of file thrdobj.c.

961{
962 /* Return the previous mode of this thread */
963 return _KeGetPreviousMode();
964}
#define _KeGetPreviousMode()
Definition: ketypes.h:1112

◆ KeInitializeThread()

VOID NTAPI KeInitializeThread ( IN PKPROCESS  Process,
IN OUT PKTHREAD  Thread,
IN PKSYSTEM_ROUTINE  SystemRoutine,
IN PKSTART_ROUTINE  StartRoutine,
IN PVOID  StartContext,
IN PCONTEXT  Context,
IN PVOID  Teb,
IN PVOID  KernelStack 
)

Definition at line 891 of file thrdobj.c.

899{
900 /* Initialize and start the thread on success */
902 KernelStack,
903 SystemRoutine,
905 StartContext,
906 Context,
907 Teb,
908 Process)))
909 {
910 /* Start it */
912 }
913}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS NTAPI KeInitThread(IN OUT PKTHREAD Thread, IN PVOID KernelStack, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext, IN PCONTEXT Context, IN PVOID Teb, IN PKPROCESS Process)
Definition: thrdobj.c:756
VOID NTAPI KeStartThread(IN OUT PKTHREAD Thread)
Definition: thrdobj.c:489
_In_ ULONG _In_opt_ POBJECT_ATTRIBUTES _In_opt_ HANDLE _Out_opt_ PCLIENT_ID _In_ PKSTART_ROUTINE StartRoutine
Definition: psfuncs.h:91

Referenced by KiInitializeHandBuiltThread(), and KiInitializeKernel().

◆ KeInitThread()

NTSTATUS NTAPI KeInitThread ( IN OUT PKTHREAD  Thread,
IN PVOID  KernelStack,
IN PKSYSTEM_ROUTINE  SystemRoutine,
IN PKSTART_ROUTINE  StartRoutine,
IN PVOID  StartContext,
IN PCONTEXT  Context,
IN PVOID  Teb,
IN PKPROCESS  Process 
)

Definition at line 756 of file thrdobj.c.

764{
765 BOOLEAN AllocatedStack = FALSE;
766 ULONG i;
767 PKWAIT_BLOCK TimerWaitBlock;
770
771 /* Initialize the Dispatcher Header */
772 Thread->Header.Type = ThreadObject;
773 Thread->Header.ThreadControlFlags = 0;
774 Thread->Header.DebugActive = FALSE;
775 Thread->Header.SignalState = 0;
776 InitializeListHead(&(Thread->Header.WaitListHead));
777
778 /* Initialize the Mutant List */
779 InitializeListHead(&Thread->MutantListHead);
780
781 /* Initialize the wait blocks */
782 for (i = 0; i< (THREAD_WAIT_OBJECTS + 1); i++)
783 {
784 /* Put our pointer */
785 Thread->WaitBlock[i].Thread = Thread;
786 }
787
788 /* Set swap settings */
789 Thread->EnableStackSwap = TRUE;
790 Thread->IdealProcessor = 1;
791 Thread->SwapBusy = FALSE;
792 Thread->KernelStackResident = TRUE;
793 Thread->AdjustReason = AdjustNone;
794
795 /* Initialize the lock */
797
798 /* Setup the Service Descriptor Table for Native Calls */
799 Thread->ServiceTable = KeServiceDescriptorTable;
800
801 /* Setup APC Fields */
802 InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
803 InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
804 Thread->ApcState.Process = Process;
805 Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
806 Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
807 Thread->ApcStateIndex = OriginalApcEnvironment;
808 Thread->ApcQueueable = TRUE;
809 KeInitializeSpinLock(&Thread->ApcQueueLock);
810
811 /* Initialize the Suspend APC */
812 KeInitializeApc(&Thread->SuspendApc,
813 Thread,
819 NULL);
820
821 /* Initialize the Suspend Semaphore */
822 KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
823
824 /* Setup the timer */
825 Timer = &Thread->Timer;
827 TimerWaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK];
828 TimerWaitBlock->Object = Timer;
829 TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
830 TimerWaitBlock->WaitType = WaitAny;
831 TimerWaitBlock->NextWaitBlock = NULL;
832
833 /* Link the two wait lists together */
834 TimerWaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead;
835 TimerWaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead;
836
837 /* Set the TEB and process */
838 Thread->Teb = Teb;
839 Thread->Process = Process;
840
841 /* Check if we have a kernel stack */
842 if (!KernelStack)
843 {
844 /* We don't, allocate one */
845 KernelStack = MmCreateKernelStack(FALSE, 0);
846 if (!KernelStack) return STATUS_INSUFFICIENT_RESOURCES;
847
848 /* Remember for later */
849 AllocatedStack = TRUE;
850 }
851
852 /* Set the Thread Stacks */
853 Thread->InitialStack = KernelStack;
854 Thread->StackBase = KernelStack;
855 Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE;
856 Thread->KernelStackResident = TRUE;
857
858 /* Enter SEH to avoid crashes due to user mode */
861 {
862 /* Initialize the Thread Context */
864 SystemRoutine,
866 StartContext,
867 Context);
868 }
870 {
871 /* Set failure status */
873
874 /* Check if a stack was allocated */
875 if (AllocatedStack)
876 {
877 /* Delete the stack */
879 Thread->InitialStack = NULL;
880 }
881 }
882 _SEH2_END;
883
884 /* Set the Thread to initialized */
885 Thread->State = Initialized;
886 return Status;
887}
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define ULONG_PTR
Definition: config.h:101
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
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
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define UserMode
Definition: asm.h:35
@ ThreadObject
Definition: ketypes.h:412
@ Initialized
Definition: ketypes.h:388
@ AttachedApcEnvironment
Definition: ketypes.h:768
@ OriginalApcEnvironment
Definition: ketypes.h:767
@ AdjustNone
Definition: ketypes.h:439
@ WaitAny
VOID NTAPI KiInitializeContextThread(PKTHREAD Thread, PKSYSTEM_ROUTINE SystemRoutine, PKSTART_ROUTINE StartRoutine, PVOID StartContext, PCONTEXT Context)
#define TIMER_WAIT_BLOCK
Definition: ke.h:164
VOID NTAPI MmDeleteKernelStack(PVOID Stack, BOOLEAN GuiStack)
PVOID NTAPI MmCreateKernelStack(BOOLEAN GuiStack, UCHAR Node)
VOID NTAPI KeInitializeApc(IN PKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT TargetEnvironment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine, IN KPROCESSOR_MODE Mode, IN PVOID Context)
Definition: apc.c:651
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[SSDT_MAX_ENTRIES]
Definition: procobj.c:23
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define KERNEL_STACK_SIZE
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
#define STATUS_SUCCESS
Definition: shellext.h:65
EX_PUSH_LOCK ThreadLock
Definition: pstypes.h:1161
PVOID Object
Definition: ketypes.h:468
LIST_ENTRY WaitListEntry
Definition: ketypes.h:456
UCHAR WaitType
Definition: ketypes.h:458
USHORT WaitKey
Definition: ketypes.h:460
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
VOID NTAPI KiSuspendNop(IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
Definition: thrdobj.c:571
VOID NTAPI KiSuspendRundown(IN PKAPC Apc)
Definition: thrdobj.c:563
VOID NTAPI KiSuspendThread(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: thrdobj.c:587
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define THREAD_WAIT_OBJECTS
Definition: ketypes.h:492

Referenced by KeInitializeThread(), and PspCreateThread().

◆ KeQueryBasePriorityThread()

KPRIORITY NTAPI KeQueryBasePriorityThread ( IN PKTHREAD  Thread)

Definition at line 52 of file thrdobj.c.

53{
54 LONG BaseIncrement;
59
60 /* Raise IRQL to synch level */
62
63 /* Lock the thread */
65
66 /* Get the Process */
67 Process = Thread->ApcStatePointer[0]->Process;
68
69 /* Calculate the base increment */
70 BaseIncrement = Thread->BasePriority - Process->BasePriority;
71
72 /* If saturation occured, return the saturation increment instead */
73 if (Thread->Saturation) BaseIncrement = (HIGH_PRIORITY + 1) / 2 *
74 Thread->Saturation;
75
76 /* Release thread lock */
78
79 /* Lower IRQl and return Increment */
81 return BaseIncrement;
82}
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: pic.c:156
#define HIGH_PRIORITY

Referenced by NtQueryInformationThread().

◆ KeQueryPriorityThread()

KPRIORITY NTAPI KeQueryPriorityThread ( IN PKTHREAD  Thread)

Definition at line 1008 of file thrdobj.c.

1009{
1011
1012 /* Return the current priority */
1013 return Thread->Priority;
1014}

Referenced by CountThread(), TestEventConcurrent(), and TestEventScheduling().

◆ KeQueryRuntimeThread()

ULONG NTAPI KeQueryRuntimeThread ( IN PKTHREAD  Thread,
OUT PULONG  UserTime 
)

Definition at line 971 of file thrdobj.c.

973{
975
976 /* Return the User Time */
977 *UserTime = Thread->UserTime;
978
979 /* Return the Kernel Time */
980 return Thread->KernelTime;
981}
_Out_ PULONG UserTime
Definition: kefuncs.h:759

◆ KeReadStateThread()

BOOLEAN NTAPI KeReadStateThread ( IN PKTHREAD  Thread)

Definition at line 42 of file thrdobj.c.

43{
45
46 /* Return signal state */
47 return (BOOLEAN)Thread->Header.SignalState;
48}

Referenced by NtQueryInformationThread(), and PspExitThread().

◆ KeReadyThread()

VOID NTAPI KeReadyThread ( IN PKTHREAD  Thread)

Definition at line 106 of file thrdobj.c.

107{
111
112 /* Lock the Dispatcher Database */
114
115 /* Make the thread ready */
117
118 /* Unlock dispatcher database */
120}
VOID NTAPI KiReadyThread(IN PKTHREAD Thread)
Definition: thrdschd.c:429

Referenced by PspCreateThread().

◆ KeResumeThread()

ULONG NTAPI KeResumeThread ( IN PKTHREAD  Thread)

Definition at line 388 of file thrdobj.c.

389{
390 KLOCK_QUEUE_HANDLE ApcLock;
391 ULONG PreviousCount;
394
395 /* Lock the APC Queue */
397
398 /* Save the Old Count */
399 PreviousCount = Thread->SuspendCount;
400
401 /* Check if it existed */
402 if (PreviousCount)
403 {
404 /* Decrease the suspend count */
405 Thread->SuspendCount--;
406
407 /* Check if the thrad is still suspended or not */
408 if ((!Thread->SuspendCount) && (!Thread->FreezeCount))
409 {
410 /* Acquire the dispatcher lock */
412
413 /* Signal the Suspend Semaphore */
414 Thread->SuspendSemaphore.Header.SignalState++;
415 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
416
417 /* Release the dispatcher lock */
419 }
420 }
421
422 /* Release APC Queue lock and return the Old State */
424 KiExitDispatcher(ApcLock.OldIrql);
425 return PreviousCount;
426}

Referenced by PspCreateThread(), PsResumeProcess(), and PsResumeThread().

◆ KeRevertToUserAffinityThread()

VOID NTAPI KeRevertToUserAffinityThread ( VOID  )

Definition at line 1021 of file thrdobj.c.

1022{
1023 KIRQL OldIrql;
1024 PKPRCB Prcb;
1025 PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1027 ASSERT(CurrentThread->SystemAffinityActive != FALSE);
1028
1029 /* Lock the Dispatcher Database */
1031
1032 /* Set the user affinity and processor and disable system affinity */
1033 CurrentThread->Affinity = CurrentThread->UserAffinity;
1034 CurrentThread->IdealProcessor = CurrentThread->UserIdealProcessor;
1035 CurrentThread->SystemAffinityActive = FALSE;
1036
1037 /* Get the current PRCB and check if it doesn't match this affinity */
1038 Prcb = KeGetCurrentPrcb();
1039 if (!(Prcb->SetMember & CurrentThread->Affinity))
1040 {
1041 /* Lock the PRCB */
1042 KiAcquirePrcbLock(Prcb);
1043
1044 /* Check if there's no next thread scheduled */
1045 if (!Prcb->NextThread)
1046 {
1047 /* Select a new thread and set it on standby */
1048 NextThread = KiSelectNextThread(Prcb);
1049 NextThread->State = Standby;
1050 Prcb->NextThread = NextThread;
1051 }
1052
1053 /* Release the PRCB lock */
1054 KiReleasePrcbLock(Prcb);
1055 }
1056
1057 /* Unlock dispatcher database */
1059}
FORCEINLINE VOID KiReleasePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:230
FORCEINLINE VOID KiAcquirePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:220
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1150
@ Standby
Definition: ketypes.h:391
PKTHREAD FASTCALL KiSelectNextThread(IN PKPRCB Prcb)
Definition: thrdschd.c:328
struct _KTHREAD * NextThread
Definition: ketypes.h:640
UINT64 SetMember
Definition: ketypes.h:651
ULONG UserIdealProcessor
Definition: ketypes.h:1783
GROUP_AFFINITY Affinity
Definition: ketypes.h:1938
ULONG IdealProcessor
Definition: ketypes.h:1944
ULONG SystemAffinityActive
Definition: ketypes.h:1697
GROUP_AFFINITY UserAffinity
Definition: ketypes.h:1912
volatile UCHAR State
Definition: ketypes.h:1789

Referenced by _IRQL_requires_max_(), CmpInitializeMachineDependentConfiguration(), ExSetTimerResolution(), Ke386CallBios(), KeConnectInterrupt(), KeDisconnectInterrupt(), KeSetSystemTime(), and KiInitMachineDependent().

◆ KeRundownThread()

VOID NTAPI KeRundownThread ( VOID  )

Definition at line 430 of file thrdobj.c.

431{
434 PLIST_ENTRY NextEntry, ListHead;
435 PKMUTANT Mutant;
437
438 /* Optimized path if nothing is on the list at the moment */
439 if (IsListEmpty(&Thread->MutantListHead)) return;
440
441 /* Lock the Dispatcher Database */
443
444 /* Get the List Pointers */
445 ListHead = &Thread->MutantListHead;
446 NextEntry = ListHead->Flink;
447 while (NextEntry != ListHead)
448 {
449 /* Get the Mutant */
450 Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry);
451 ASSERT_MUTANT(Mutant);
452
453 /* Make sure it's not terminating with APCs off */
454 if (Mutant->ApcDisable)
455 {
456 /* Bugcheck the system */
457 KeBugCheckEx(THREAD_TERMINATE_HELD_MUTEX,
459 (ULONG_PTR)Mutant,
460 0,
461 0);
462 }
463
464 /* Now we can remove it */
466
467 /* Unconditionally abandon it */
468 Mutant->Header.SignalState = 1;
469 Mutant->Abandoned = TRUE;
470 Mutant->OwnerThread = NULL;
471
472 /* Check if the Wait List isn't empty */
473 if (!IsListEmpty(&Mutant->Header.WaitListHead))
474 {
475 /* Wake the Mutant */
477 }
478
479 /* Move on */
480 NextEntry = Thread->MutantListHead.Flink;
481 }
482
483 /* Release the Lock */
485}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define MUTANT_INCREMENT
Definition: extypes.h:84
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
LIST_ENTRY WaitListHead
Definition: ketypes.h:808
DISPATCHER_HEADER Header
Definition: ketypes.h:841
LIST_ENTRY MutantListEntry
Definition: ketypes.h:842
BOOLEAN Abandoned
Definition: ketypes.h:844
struct _KTHREAD *RESTRICTED_POINTER OwnerThread
Definition: ketypes.h:843
UCHAR ApcDisable
Definition: ketypes.h:845
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ASSERT_MUTANT(Object)

Referenced by PspExitThread().

◆ KeSetAffinityThread()

KAFFINITY NTAPI KeSetAffinityThread ( IN PKTHREAD  Thread,
IN KAFFINITY  Affinity 
)

Definition at line 1295 of file thrdobj.c.

1297{
1298 KIRQL OldIrql;
1299 KAFFINITY OldAffinity;
1302
1303 /* Lock the dispatcher database */
1305
1306 /* Call the internal function */
1307 OldAffinity = KiSetAffinityThread(Thread, Affinity);
1308
1309 /* Release the dispatcher database and return old affinity */
1311 return OldAffinity;
1312}
KAFFINITY FASTCALL KiSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdschd.c:685
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174

Referenced by NtSetInformationThread().

◆ KeSetBasePriorityThread()

LONG NTAPI KeSetBasePriorityThread ( IN PKTHREAD  Thread,
IN LONG  Increment 
)

Definition at line 1176 of file thrdobj.c.

1178{
1179 KIRQL OldIrql;
1180 KPRIORITY OldBasePriority, Priority, BasePriority;
1181 LONG OldIncrement;
1185
1186 /* Get the process */
1187 Process = Thread->ApcState.Process;
1188
1189 /* Lock the Dispatcher Database */
1191
1192 /* Lock the thread */
1194
1195 /* Save the old base priority and increment */
1196 OldBasePriority = Thread->BasePriority;
1197 OldIncrement = OldBasePriority - Process->BasePriority;
1198
1199 /* If priority saturation happened, use the saturated increment */
1200 if (Thread->Saturation) OldIncrement = (HIGH_PRIORITY + 1) / 2 *
1201 Thread->Saturation;
1202
1203 /* Reset the saturation value */
1204 Thread->Saturation = 0;
1205
1206 /* Now check if saturation is being used for the new value */
1207 if (abs(Increment) >= ((HIGH_PRIORITY + 1) / 2))
1208 {
1209 /* Check if we need positive or negative saturation */
1210 Thread->Saturation = (Increment > 0) ? 1 : -1;
1211 }
1212
1213 /* Normalize the Base Priority */
1214 BasePriority = Process->BasePriority + Increment;
1215 if (Process->BasePriority >= LOW_REALTIME_PRIORITY)
1216 {
1217 /* Check if it's too low */
1218 if (BasePriority < LOW_REALTIME_PRIORITY)
1219 {
1220 /* Set it to the lowest real time level */
1221 BasePriority = LOW_REALTIME_PRIORITY;
1222 }
1223
1224 /* Check if it's too high */
1225 if (BasePriority > HIGH_PRIORITY) BasePriority = HIGH_PRIORITY;
1226
1227 /* We are at real time, so use the raw base priority */
1228 Priority = BasePriority;
1229 }
1230 else
1231 {
1232 /* Check if it's entering the real time range */
1233 if (BasePriority >= LOW_REALTIME_PRIORITY)
1234 {
1235 /* Set it to the highest dynamic level */
1236 BasePriority = LOW_REALTIME_PRIORITY - 1;
1237 }
1238
1239 /* Check if it's too low and normalize it */
1240 if (BasePriority <= LOW_PRIORITY) BasePriority = 1;
1241
1242 /* Check if Saturation is used */
1243 if (Thread->Saturation)
1244 {
1245 /* Use the raw base priority */
1246 Priority = BasePriority;
1247 }
1248 else
1249 {
1250 /* Otherwise, calculate the new priority */
1252 Priority += (BasePriority - OldBasePriority);
1253
1254 /* Check if it entered the real-time range */
1256 {
1257 /* Normalize it down to the highest dynamic priority */
1259 }
1260 else if (Priority <= LOW_PRIORITY)
1261 {
1262 /* It went too low, normalize it */
1263 Priority = 1;
1264 }
1265 }
1266 }
1267
1268 /* Finally set the new base priority */
1269 Thread->BasePriority = (SCHAR)BasePriority;
1270
1271 /* Reset the decrements */
1272 Thread->PriorityDecrement = 0;
1273
1274 /* Check if we're changing priority after all */
1275 if (Priority != Thread->Priority)
1276 {
1277 /* Reset the quantum and do the actual priority modification */
1278 Thread->Quantum = Thread->QuantumReset;
1280 }
1281
1282 /* Release thread lock */
1284
1285 /* Release the dispatcher database and return old increment */
1287 return OldIncrement;
1288}
#define abs(i)
Definition: fconv.c:206
#define LOW_PRIORITY
FORCEINLINE SCHAR KiComputeNewPriority(IN PKTHREAD Thread, IN SCHAR Adjustment)
Definition: ke_x.h:1472
if(dx< 0)
Definition: linetemp.h:194
signed char SCHAR
Definition: sqltypes.h:14

Referenced by ExpCreateWorkerThread(), ExpWorkerThreadBalanceManager(), and NtSetInformationThread().

◆ KeSetDisableBoostThread()

BOOLEAN NTAPI KeSetDisableBoostThread ( IN OUT PKTHREAD  Thread,
IN BOOLEAN  Disable 
)

Definition at line 86 of file thrdobj.c.

88{
90
91 /* Check if we're enabling or disabling */
92 if (Disable)
93 {
94 /* Set the bit */
95 return InterlockedBitTestAndSet(&Thread->ThreadFlags, 1);
96 }
97 else
98 {
99 /* Remove the bit */
100 return InterlockedBitTestAndReset(&Thread->ThreadFlags, 1);
101 }
102}
#define InterlockedBitTestAndSet
Definition: interlocked.h:30
#define InterlockedBitTestAndReset
Definition: interlocked.h:35

Referenced by NtSetInformationProcess(), and NtSetInformationThread().

◆ KeSetIdealProcessorThread()

UCHAR NTAPI KeSetIdealProcessorThread ( IN PKTHREAD  Thread,
IN UCHAR  Processor 
)

Definition at line 1066 of file thrdobj.c.

1068{
1069 CCHAR OldIdealProcessor;
1070 KIRQL OldIrql;
1072
1073 /* Lock the Dispatcher Database */
1075
1076 /* Save Old Ideal Processor */
1077 OldIdealProcessor = Thread->UserIdealProcessor;
1078
1079 /* Make sure a valid CPU was given */
1081 {
1082 /* Check if the user ideal CPU is in the affinity */
1083 if (Thread->Affinity & AFFINITY_MASK(Processor))
1084 {
1085 /* Set the ideal processor */
1086 Thread->IdealProcessor = Processor;
1087
1088 /* Check if system affinity is used */
1089 if (!Thread->SystemAffinityActive)
1090 {
1091 /* It's not, so update the user CPU too */
1092 Thread->UserIdealProcessor = Processor;
1093 }
1094 }
1095 }
1096
1097 /* Release dispatcher lock and return the old ideal CPU */
1099 return OldIdealProcessor;
1100}
#define MAXIMUM_PROCESSORS
Definition: rwlock.h:5
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
char CCHAR
Definition: typedefs.h:51
_In_ UCHAR Processor
Definition: kefuncs.h:670

Referenced by NtSetInformationThread().

◆ KeSetKernelStackSwapEnable()

BOOLEAN NTAPI KeSetKernelStackSwapEnable ( IN BOOLEAN  Enable)

Definition at line 988 of file thrdobj.c.

989{
992
993 /* Save Old State */
994 PreviousState = Thread->EnableStackSwap;
995
996 /* Set New State */
997 Thread->EnableStackSwap = Enable;
998
999 /* Return Old State */
1000 return PreviousState;
1001}
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142

Referenced by co_MsqSendMessage(), ExitThreadCallback(), ExpSetSwappingKernelApc(), ExpWorkerThreadEntryPoint(), and ExSwapinWorkerThreads().

◆ KeSetPriorityThread()

KPRIORITY NTAPI KeSetPriorityThread ( IN PKTHREAD  Thread,
IN KPRIORITY  Priority 
)

Definition at line 1319 of file thrdobj.c.

1321{
1322 KIRQL OldIrql;
1323 KPRIORITY OldPriority;
1328
1329 /* Lock the Dispatcher Database */
1331
1332 /* Lock the thread */
1334
1335 /* Save the old Priority and reset decrement */
1336 OldPriority = Thread->Priority;
1337 Thread->PriorityDecrement = 0;
1338
1339 /* Make sure that an actual change is being done */
1340 if (Priority != Thread->Priority)
1341 {
1342 /* Reset the quantum */
1343 Thread->Quantum = Thread->QuantumReset;
1344
1345 /* Check if priority is being set too low and normalize if so */
1346 if ((Thread->BasePriority != 0) && !(Priority)) Priority = 1;
1347
1348 /* Set the new Priority */
1350 }
1351
1352 /* Release thread lock */
1354
1355 /* Release the dispatcher database */
1357
1358 /* Return Old Priority */
1359 return OldPriority;
1360}
BOOLEAN NTAPI KeIsExecutingDpc(VOID)
Definition: dpc.c:965

Referenced by FsRtlWorkerThread(), InbvMonitorThread(), KeBalanceSetManager(), KiInitializeKernel(), KiSystemStartupBootStack(), MmZeroPageThread(), NtSetInformationThread(), Phase1InitializationDiscard(), RawInputThreadMain(), and VfdDeviceThread().

◆ KeSetSystemAffinityThread()

VOID NTAPI KeSetSystemAffinityThread ( IN KAFFINITY  Affinity)

Definition at line 1107 of file thrdobj.c.

1108{
1109 KIRQL OldIrql;
1110 PKPRCB Prcb;
1111 PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1114
1115 /* Lock the Dispatcher Database */
1117
1118 /* Restore the affinity and enable system affinity */
1119 CurrentThread->Affinity = Affinity;
1120 CurrentThread->SystemAffinityActive = TRUE;
1121
1122 /* Check if the ideal processor is part of the affinity */
1123#ifdef CONFIG_SMP
1124 if (!(Affinity & AFFINITY_MASK(CurrentThread->IdealProcessor)))
1125 {
1126 KAFFINITY AffinitySet, NodeMask;
1127 ULONG IdealProcessor;
1128
1129 /* It's not! Get the PRCB */
1130 Prcb = KiProcessorBlock[CurrentThread->IdealProcessor];
1131
1132 /* Calculate the affinity set */
1133 AffinitySet = KeActiveProcessors & Affinity;
1134 NodeMask = Prcb->ParentNode->ProcessorMask & AffinitySet;
1135 if (NodeMask)
1136 {
1137 /* Use the Node set instead */
1138 AffinitySet = NodeMask;
1139 }
1140
1141 /* Calculate the ideal CPU from the affinity set */
1142 BitScanReverseAffinity(&IdealProcessor, AffinitySet);
1143 CurrentThread->IdealProcessor = (UCHAR)IdealProcessor;
1144 }
1145#endif
1146
1147 /* Get the current PRCB and check if it doesn't match this affinity */
1148 Prcb = KeGetCurrentPrcb();
1149 if (!(Prcb->SetMember & CurrentThread->Affinity))
1150 {
1151 /* Lock the PRCB */
1152 KiAcquirePrcbLock(Prcb);
1153
1154 /* Check if there's no next thread scheduled */
1155 if (!Prcb->NextThread)
1156 {
1157 /* Select a new thread and set it on standby */
1158 NextThread = KiSelectNextThread(Prcb);
1159 NextThread->State = Standby;
1160 Prcb->NextThread = NextThread;
1161 }
1162
1163 /* Release the PRCB lock */
1164 KiReleasePrcbLock(Prcb);
1165 }
1166
1167 /* Unlock dispatcher database */
1169}
PKPRCB KiProcessorBlock[]
Definition: krnlinit.c:32
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
struct _KNODE * ParentNode
Definition: ketypes.h:824

Referenced by _Function_class_(), _IRQL_requires_max_(), CmpInitializeMachineDependentConfiguration(), ExSetTimerResolution(), Ke386CallBios(), KeConnectInterrupt(), KeDisconnectInterrupt(), KeSetSystemTime(), KiInitMachineDependent(), and PopShutdownSystem().

◆ KeStartThread()

VOID NTAPI KeStartThread ( IN OUT PKTHREAD  Thread)

Definition at line 489 of file thrdobj.c.

490{
492#ifdef CONFIG_SMP
493 PKNODE Node;
494 PKPRCB NodePrcb;
496#endif
497 UCHAR IdealProcessor = 0;
498 PKPROCESS Process = Thread->ApcState.Process;
499
500 /* Setup static fields from parent */
501 Thread->DisableBoost = Process->DisableBoost;
502#if defined(_M_IX86)
503 Thread->Iopl = Process->Iopl;
504#endif
505 Thread->Quantum = Process->QuantumReset;
506 Thread->QuantumReset = Process->QuantumReset;
507 Thread->SystemAffinityActive = FALSE;
508
509 /* Lock the process */
511
512 /* Setup volatile data */
513 Thread->Priority = Process->BasePriority;
514 Thread->BasePriority = Process->BasePriority;
515 Thread->Affinity = Process->Affinity;
516 Thread->UserAffinity = Process->Affinity;
517
518#ifdef CONFIG_SMP
519 /* Get the KNODE and its PRCB */
520 Node = KeNodeBlock[Process->IdealNode];
521 NodePrcb = KiProcessorBlock[Process->ThreadSeed];
522
523 /* Calculate affinity mask */
524#ifdef _M_ARM
526 Set = 0;
527#else
528 Set = ~NodePrcb->MultiThreadProcessorSet;
529#endif
530 Mask = Node->ProcessorMask & Process->Affinity;
531 Set &= Mask;
532 if (Set) Mask = Set;
533
534 /* Get the new thread seed */
535 IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask);
536 Process->ThreadSeed = IdealProcessor;
537
538 /* Sanity check */
539 ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor)));
540#endif
541
542 /* Set the Ideal Processor */
543 Thread->IdealProcessor = IdealProcessor;
544 Thread->UserIdealProcessor = IdealProcessor;
545
546 /* Lock the Dispatcher Database */
548
549 /* Insert the thread into the process list */
550 InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
551
552 /* Increase the stack count */
553 ASSERT(Process->StackCount != MAXULONG_PTR);
554 Process->StackCount++;
555
556 /* Release locks and return */
559}
#define MAXULONG_PTR
Definition: basetsd.h:103
union node Node
Definition: types.h:1255
#define InsertTailList(ListHead, Entry)
unsigned int Mask
Definition: fpcontrol.c:82
NTSYSAPI void WINAPI DbgBreakPoint(void)
PKNODE KeNodeBlock[1]
Definition: krnlinit.c:39
LIST_ENTRY ThreadListEntry
Definition: pstypes.h:1159
UCHAR NTAPI KeFindNextRightSetAffinity(IN UCHAR Number, IN KAFFINITY Set)
Definition: thrdobj.c:22
Definition: dlist.c:348

Referenced by KeInitializeThread(), and PspCreateThread().

◆ KeSuspendThread()

ULONG NTAPI KeSuspendThread ( PKTHREAD  Thread)

Definition at line 601 of file thrdobj.c.

602{
603 KLOCK_QUEUE_HANDLE ApcLock;
604 ULONG PreviousCount;
607
608 /* Lock the APC Queue */
610
611 /* Save the Old Count */
612 PreviousCount = Thread->SuspendCount;
613
614 /* Handle the maximum */
615 if (PreviousCount == MAXIMUM_SUSPEND_COUNT)
616 {
617 /* Raise an exception */
618 KiReleaseApcLock(&ApcLock);
620 }
621
622 /* Should we bother to queue at all? */
623 if (Thread->ApcQueueable)
624 {
625 /* Increment the suspend count */
626 Thread->SuspendCount++;
627
628 /* Check if we should suspend it */
629 if (!(PreviousCount) && !(Thread->FreezeCount))
630 {
631 /* Is the APC already inserted? */
632 if (!Thread->SuspendApc.Inserted)
633 {
634 /* Not inserted, insert it */
635 Thread->SuspendApc.Inserted = TRUE;
637 }
638 else
639 {
640 /* Lock the dispatcher */
642
643 /* Unsignal the semaphore, the APC was already inserted */
644 Thread->SuspendSemaphore.Header.SignalState--;
645
646 /* Release the dispatcher */
648 }
649 }
650 }
651
652 /* Release Lock and return the Old State */
654 KiExitDispatcher(ApcLock.OldIrql);
655 return PreviousCount;
656}
FORCEINLINE VOID KiReleaseApcLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:635
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
#define STATUS_SUSPEND_COUNT_EXCEEDED
Definition: ntstatus.h:310

Referenced by NtSetSystemPowerState(), PspCreateThread(), and PsSuspendThread().

◆ KeTerminateThread()

VOID NTAPI KeTerminateThread ( IN KPRIORITY  Increment)

Definition at line 1367 of file thrdobj.c.

1368{
1369 PLIST_ENTRY *ListHead;
1370 PETHREAD Entry, SavedEntry;
1371 PETHREAD *ThreadAddr;
1374 PKPROCESS Process = Thread->ApcState.Process;
1376
1377 /* Lock the process */
1379
1380 /* Make sure we won't get Swapped */
1382
1383 /* Save the Kernel and User Times */
1384 Process->KernelTime += Thread->KernelTime;
1385 Process->UserTime += Thread->UserTime;
1386
1387 /* Get the current entry and our Port */
1389 ThreadAddr = &((PETHREAD)Thread)->ReaperLink;
1390
1391 /* Add it to the reaper's list */
1392 do
1393 {
1394 /* Get the list head */
1395 ListHead = &PspReaperListHead.Flink;
1396
1397 /* Link ourselves */
1398 *ThreadAddr = Entry;
1399 SavedEntry = Entry;
1400
1401 /* Now try to do the exchange */
1403 ThreadAddr,
1404 Entry);
1405
1406 /* Break out if the change was succesful */
1407 } while (Entry != SavedEntry);
1408
1409 /* Acquire the dispatcher lock */
1411
1412 /* Check if the reaper wasn't active */
1413 if (!Entry)
1414 {
1415 /* Activate it as a work item, directly through its Queue */
1418 FALSE);
1419 }
1420
1421 /* Check the thread has an associated queue */
1422 if (Thread->Queue)
1423 {
1424 /* Remove it from the list, and handle the queue */
1425 RemoveEntryList(&Thread->QueueListEntry);
1427 }
1428
1429 /* Signal the thread */
1430 Thread->Header.SignalState = TRUE;
1431 if (!IsListEmpty(&Thread->Header.WaitListHead))
1432 {
1433 /* Unwait the threads */
1434 KxUnwaitThread(&Thread->Header, Increment);
1435 }
1436
1437 /* Remove the thread from the list */
1439
1440 /* Release the process lock */
1442
1443 /* Set us as terminated, decrease the Process's stack count */
1444 Thread->State = Terminated;
1445
1446 /* Decrease stack count */
1447 ASSERT(Process->StackCount != 0);
1448 ASSERT(Process->State == ProcessInMemory);
1449 Process->StackCount--;
1450 if (!(Process->StackCount) && !(IsListEmpty(&Process->ThreadListHead)))
1451 {
1452 /* FIXME: Swap stacks */
1453 }
1454
1455 /* Rundown arch-specific parts */
1457
1458 /* Swap to a new thread */
1461}
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
FORCEINLINE VOID KiSetThreadSwapBusy(IN PKTHREAD Thread)
Definition: ke_x.h:210
FORCEINLINE VOID KxUnwaitThread(IN DISPATCHER_HEADER *Object, IN KPRIORITY Increment)
Definition: ke_x.h:1259
@ ProcessInMemory
Definition: ketypes.h:460
@ Terminated
Definition: ketypes.h:392
struct _ETHREAD * PETHREAD
Definition: nt_native.h:29
FORCEINLINE VOID KiRundownThread(IN PKTHREAD Thread)
Definition: ke.h:293
LONG_PTR FASTCALL KiSwapThread(IN PKTHREAD Thread, IN PKPRCB Prcb)
Definition: thrdschd.c:355
VOID FASTCALL KiActivateWaiterQueue(IN PKQUEUE Queue)
Definition: queue.c:24
LONG NTAPI KiInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry, BOOLEAN Head)
WORK_QUEUE_ITEM PspReaperWorkItem
Definition: kill.c:20
base of all file and directory entries
Definition: entries.h:83
LIST_ENTRY List
Definition: extypes.h:203
LIST_ENTRY PspReaperListHead
Definition: kill.c:19
EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue]
Definition: work.c:31
@ HyperCriticalWorkQueue
Definition: extypes.h:191

Referenced by PspExitThread().

◆ KeTestAlertThread()

BOOLEAN NTAPI KeTestAlertThread ( IN KPROCESSOR_MODE  AlertMode)

Definition at line 722 of file thrdobj.c.

723{
725 BOOLEAN OldState;
726 KLOCK_QUEUE_HANDLE ApcLock;
729
730 /* Lock the Dispatcher Database and the APC Queue */
732
733 /* Save the old State */
734 OldState = Thread->Alerted[AlertMode];
735
736 /* Check the Thread is alerted */
737 if (OldState)
738 {
739 /* Disable alert for this mode */
740 Thread->Alerted[AlertMode] = FALSE;
741 }
742 else if ((AlertMode != KernelMode) &&
743 (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
744 {
745 /* If the mode is User and the Queue isn't empty, set Pending */
746 Thread->ApcState.UserApcPending = TRUE;
747 }
748
749 /* Release Locks and return the Old State */
750 KiReleaseApcLock(&ApcLock);
751 return OldState;
752}

Referenced by KiDeliverApc(), NtContinue(), and NtTestAlert().

◆ KeThawAllThreads()

VOID NTAPI KeThawAllThreads ( VOID  )

Definition at line 660 of file thrdobj.c.

661{
663 PKTHREAD Current, CurrentThread = KeGetCurrentThread();
664 PKPROCESS Process = CurrentThread->ApcState.Process;
665 PLIST_ENTRY ListHead, NextEntry;
666 LONG OldCount;
668
669 /* Lock the process */
671
672 /* Loop the Process's Threads */
673 ListHead = &Process->ThreadListHead;
674 NextEntry = ListHead->Flink;
675 do
676 {
677 /* Get the current thread */
678 Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
679
680 /* Lock it */
681 KiAcquireApcLockAtSynchLevel(Current, &ApcLock);
682
683 /* Make sure we are frozen */
684 OldCount = Current->FreezeCount;
685 if (OldCount)
686 {
687 /* Decrease the freeze count */
688 Current->FreezeCount--;
689
690 /* Check if both counts are zero now */
691 if (!(Current->SuspendCount) && (!Current->FreezeCount))
692 {
693 /* Lock the dispatcher */
695
696 /* Signal the suspend semaphore and wake it */
697 Current->SuspendSemaphore.Header.SignalState++;
698 KiWaitTest(&Current->SuspendSemaphore, 0);
699
700 /* Unlock the dispatcher */
702 }
703 }
704
705 /* Release the APC lock */
707
708 /* Go to the next one */
709 NextEntry = NextEntry->Flink;
710 } while (NextEntry != ListHead);
711
712 /* Release the process lock and exit the dispatcher */
715
716 /* Leave the critical region */
718}
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119

Referenced by DbgkpResumeProcess().

◆ KeUninitThread()

VOID NTAPI KeUninitThread ( IN PKTHREAD  Thread)

Definition at line 917 of file thrdobj.c.

918{
919 /* Delete the stack */
921 Thread->InitialStack = NULL;
922}

Referenced by PspCreateThread().

◆ KiSuspendNop()

VOID NTAPI KiSuspendNop ( IN PKAPC  Apc,
IN PKNORMAL_ROUTINE NormalRoutine,
IN PVOID NormalContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2 
)

Definition at line 571 of file thrdobj.c.

576{
577 /* Does nothing */
579 UNREFERENCED_PARAMETER(NormalRoutine);
580 UNREFERENCED_PARAMETER(NormalContext);
583}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689

Referenced by KeInitThread().

◆ KiSuspendRundown()

VOID NTAPI KiSuspendRundown ( IN PKAPC  Apc)

Definition at line 563 of file thrdobj.c.

564{
565 /* Does nothing */
567}

Referenced by KeInitThread().

◆ KiSuspendThread()

VOID NTAPI KiSuspendThread ( IN PVOID  NormalContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2 
)

Definition at line 587 of file thrdobj.c.

590{
591 /* Non-alertable kernel-mode suspended wait */
592 KeWaitForSingleObject(&KeGetCurrentThread()->SuspendSemaphore,
593 Suspended,
595 FALSE,
596 NULL);
597}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
@ Suspended
Definition: ketypes.h:420

Referenced by KeInitThread().

Variable Documentation

◆ ExWorkerQueue

◆ PspReaperListHead

LIST_ENTRY PspReaperListHead
extern

Definition at line 19 of file kill.c.

Referenced by KeTerminateThread(), and PspReapRoutine().