ReactOS 0.4.15-dev-6055-g36cdd34
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 ULONG 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
 
ULONG KiMask32Array [MAXIMUM_PRIORITY]
 

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 133 of file thrdobj.c.

134{
135 ULONG PreviousCount;
136 KLOCK_QUEUE_HANDLE ApcLock;
139
140 /* Lock the Dispatcher Database and the APC Queue */
143
144 /* Return if Thread is already alerted. */
145 if (!Thread->Alerted[KernelMode])
146 {
147 /* If it's Blocked, unblock if it we should */
148 if ((Thread->State == Waiting) && (Thread->Alertable))
149 {
150 /* Abort the wait */
152 }
153 else
154 {
155 /* If not, simply Alert it */
156 Thread->Alerted[KernelMode] = TRUE;
157 }
158 }
159
160 /* Save the old Suspend Count */
161 PreviousCount = Thread->SuspendCount;
162
163 /* If the thread is suspended, decrease one of the suspend counts */
164 if (PreviousCount)
165 {
166 /* Decrease count. If we are now zero, unwait it completely */
167 Thread->SuspendCount--;
168 if (!(Thread->SuspendCount) && !(Thread->FreezeCount))
169 {
170 /* Signal and satisfy */
171 Thread->SuspendSemaphore.Header.SignalState++;
172 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
173 }
174 }
175
176 /* Release Locks and return the Old State */
179 KiExitDispatcher(ApcLock.OldIrql);
180 return PreviousCount;
181}
#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:426
#define THREAD_ALERT_INCREMENT
Definition: ketypes.h:126
#define ASSERT_THREAD(object)
Definition: ketypes.h:2016
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 185 of file thrdobj.c.

187{
189 KLOCK_QUEUE_HANDLE ApcLock;
192
193 /* Lock the Dispatcher Database and the APC Queue */
196
197 /* Save the Previous State */
198 PreviousState = Thread->Alerted[AlertMode];
199
200 /* Check if it's already alerted */
201 if (!PreviousState)
202 {
203 /* Check if the thread is alertable, and blocked in the given mode */
204 if ((Thread->State == Waiting) &&
205 (Thread->Alertable) &&
206 (AlertMode <= Thread->WaitMode))
207 {
208 /* Abort the wait to alert the thread */
210 }
211 else
212 {
213 /* Otherwise, merely set the alerted state */
214 Thread->Alerted[AlertMode] = TRUE;
215 }
216 }
217
218 /* Release the Dispatcher Lock */
221 KiExitDispatcher(ApcLock.OldIrql);
222
223 /* Return the old state */
224 return PreviousState;
225}
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 229 of file thrdobj.c.

231{
235
236 /* Lock the Dispatcher Database */
238
239 /* Only threads in the dynamic range get boosts */
240 if (Thread->Priority < LOW_REALTIME_PRIORITY)
241 {
242 /* Lock the thread */
244
245 /* Check again, and make sure there's not already a boost */
246 if ((Thread->Priority < LOW_REALTIME_PRIORITY) &&
247 !(Thread->PriorityDecrement))
248 {
249 /* Compute the new priority and see if it's higher */
250 Priority = Thread->BasePriority + Increment;
251 if (Priority > Thread->Priority)
252 {
254 {
256 }
257
258 /* Reset the quantum */
259 Thread->Quantum = Thread->QuantumReset;
260
261 /* Set the new Priority */
263 }
264 }
265
266 /* Release thread lock */
268 }
269
270 /* Release the dispatcher lokc */
272}
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:792

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 940 of file thrdobj.c.

947{
949}
#define UNIMPLEMENTED
Definition: debug.h:115

◆ KeFindNextRightSetAffinity()

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

Definition at line 32 of file thrdobj.c.

34{
35 ULONG Bit, Result;
36 ASSERT(Set != 0);
37
38 /* Calculate the mask */
39 Bit = (AFFINITY_MASK(Number) - 1) & Set;
40
41 /* If it's 0, use the one we got */
42 if (!Bit) Bit = Set;
43
44 /* Now find the right set and return it */
46 return (UCHAR)Result;
47}
#define BitScanReverse
Definition: interlocked.h:6
#define ASSERT(a)
Definition: mode.c:44
#define AFFINITY_MASK(Id)
Definition: ke.h:159
_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:426
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by KeInitializeProcess(), and KeStartThread().

◆ KeForceResumeThread()

ULONG NTAPI KeForceResumeThread ( IN PKTHREAD  Thread)

Definition at line 276 of file thrdobj.c.

277{
278 KLOCK_QUEUE_HANDLE ApcLock;
279 ULONG PreviousCount;
282
283 /* Lock the APC Queue */
285
286 /* Save the old Suspend Count */
287 PreviousCount = Thread->SuspendCount + Thread->FreezeCount;
288
289 /* If the thread is suspended, wake it up!!! */
290 if (PreviousCount)
291 {
292 /* Unwait it completely */
293 Thread->SuspendCount = 0;
294 Thread->FreezeCount = 0;
295
296 /* Lock the dispatcher */
298
299 /* Signal and satisfy */
300 Thread->SuspendSemaphore.Header.SignalState++;
301 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
302
303 /* Release the dispatcher */
305 }
306
307 /* Release Lock and return the Old State */
309 KiExitDispatcher(ApcLock.OldIrql);
310 return PreviousCount;
311}

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

◆ KeFreezeAllThreads()

VOID NTAPI KeFreezeAllThreads ( VOID  )

Definition at line 315 of file thrdobj.c.

316{
318 PKTHREAD Current, CurrentThread = KeGetCurrentThread();
319 PKPROCESS Process = CurrentThread->ApcState.Process;
320 PLIST_ENTRY ListHead, NextEntry;
321 LONG OldCount;
323
324 /* Lock the process */
326
327 /* If someone is already trying to free us, try again */
328 while (CurrentThread->FreezeCount)
329 {
330 /* Release and re-acquire the process lock so the APC will go through */
333 }
334
335 /* Enter a critical region */
337
338 /* Loop the Process's Threads */
339 ListHead = &Process->ThreadListHead;
340 NextEntry = ListHead->Flink;
341 do
342 {
343 /* Get the current thread */
344 Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
345
346 /* Lock it */
347 KiAcquireApcLockAtSynchLevel(Current, &ApcLock);
348
349 /* Make sure it's not ours, and check if APCs are enabled */
350 if ((Current != CurrentThread) && (Current->ApcQueueable))
351 {
352 /* Sanity check */
353 OldCount = Current->SuspendCount;
354 ASSERT(OldCount != MAXIMUM_SUSPEND_COUNT);
355
356 /* Increase the freeze count */
357 Current->FreezeCount++;
358
359 /* Make sure it wasn't already suspended */
360 if (!(OldCount) && !(Current->SuspendCount))
361 {
362 /* Did we already insert it? */
363 if (!Current->SuspendApc.Inserted)
364 {
365 /* Insert the APC */
366 Current->SuspendApc.Inserted = TRUE;
367 KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT);
368 }
369 else
370 {
371 /* Lock the dispatcher */
373
374 /* Unsignal the semaphore, the APC was already inserted */
375 Current->SuspendSemaphore.Header.SignalState--;
376
377 /* Release the dispatcher */
379 }
380 }
381 }
382
383 /* Release the APC lock */
385
386 /* Move to the next thread */
387 NextEntry = NextEntry->Flink;
388 } while (NextEntry != ListHead);
389
390 /* Release the process lock and exit the dispatcher */
393}
_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:1677
DISPATCHER_HEADER Header
Definition: ketypes.h:1601
CHAR SuspendCount
Definition: ketypes.h:1905
KAPC_STATE ApcState
Definition: ketypes.h:1718
ULONG ApcQueueable
Definition: ketypes.h:1651
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:405
*LockHandle LockHandle _Out_ PKLOCK_QUEUE_HANDLE LockHandle
Definition: kefuncs.h:731

Referenced by DbgkpSuspendProcess().

◆ KeGetCurrentThread()

PKTHREAD NTAPI KeGetCurrentThread ( VOID  )

Definition at line 957 of file thrdobj.c.

958{
959 /* Return the current thread on this PCR */
960 return _KeGetCurrentThread();
961}
#define _KeGetCurrentThread()
Definition: ketypes.h:1104

◆ KeGetPreviousMode()

UCHAR NTAPI KeGetPreviousMode ( VOID  )

Definition at line 969 of file thrdobj.c.

970{
971 /* Return the previous mode of this thread */
972 return _KeGetPreviousMode();
973}
#define _KeGetPreviousMode()
Definition: ketypes.h:1105

◆ 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 900 of file thrdobj.c.

908{
909 /* Initialize and start the thread on success */
911 KernelStack,
912 SystemRoutine,
914 StartContext,
915 Context,
916 Teb,
917 Process)))
918 {
919 /* Start it */
921 }
922}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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:765
VOID NTAPI KeStartThread(IN OUT PKTHREAD Thread)
Definition: thrdobj.c:498
_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 765 of file thrdobj.c.

773{
774 BOOLEAN AllocatedStack = FALSE;
775 ULONG i;
776 PKWAIT_BLOCK TimerWaitBlock;
779
780 /* Initialize the Dispatcher Header */
781 Thread->Header.Type = ThreadObject;
782 Thread->Header.ThreadControlFlags = 0;
783 Thread->Header.DebugActive = FALSE;
784 Thread->Header.SignalState = 0;
785 InitializeListHead(&(Thread->Header.WaitListHead));
786
787 /* Initialize the Mutant List */
788 InitializeListHead(&Thread->MutantListHead);
789
790 /* Initialize the wait blocks */
791 for (i = 0; i< (THREAD_WAIT_OBJECTS + 1); i++)
792 {
793 /* Put our pointer */
794 Thread->WaitBlock[i].Thread = Thread;
795 }
796
797 /* Set swap settings */
798 Thread->EnableStackSwap = TRUE;
799 Thread->IdealProcessor = 1;
800 Thread->SwapBusy = FALSE;
801 Thread->KernelStackResident = TRUE;
802 Thread->AdjustReason = AdjustNone;
803
804 /* Initialize the lock */
806
807 /* Setup the Service Descriptor Table for Native Calls */
808 Thread->ServiceTable = KeServiceDescriptorTable;
809
810 /* Setup APC Fields */
811 InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
812 InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
813 Thread->ApcState.Process = Process;
814 Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
815 Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
816 Thread->ApcStateIndex = OriginalApcEnvironment;
817 Thread->ApcQueueable = TRUE;
818 KeInitializeSpinLock(&Thread->ApcQueueLock);
819
820 /* Initialize the Suspend APC */
821 KeInitializeApc(&Thread->SuspendApc,
822 Thread,
828 NULL);
829
830 /* Initialize the Suspend Semaphore */
831 KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
832
833 /* Setup the timer */
834 Timer = &Thread->Timer;
836 TimerWaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK];
837 TimerWaitBlock->Object = Timer;
838 TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
839 TimerWaitBlock->WaitType = WaitAny;
840 TimerWaitBlock->NextWaitBlock = NULL;
841
842 /* Link the two wait lists together */
843 TimerWaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead;
844 TimerWaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead;
845
846 /* Set the TEB and process */
847 Thread->Teb = Teb;
848 Thread->Process = Process;
849
850 /* Check if we have a kernel stack */
851 if (!KernelStack)
852 {
853 /* We don't, allocate one */
854 KernelStack = MmCreateKernelStack(FALSE, 0);
855 if (!KernelStack) return STATUS_INSUFFICIENT_RESOURCES;
856
857 /* Remember for later */
858 AllocatedStack = TRUE;
859 }
860
861 /* Set the Thread Stacks */
862 Thread->InitialStack = KernelStack;
863 Thread->StackBase = KernelStack;
864 Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE;
865 Thread->KernelStackResident = TRUE;
866
867 /* Enter SEH to avoid crashes due to user mode */
870 {
871 /* Initialize the Thread Context */
873 SystemRoutine,
875 StartContext,
876 Context);
877 }
879 {
880 /* Set failure status */
882
883 /* Check if a stack was allocated */
884 if (AllocatedStack)
885 {
886 /* Delete the stack */
888 Thread->InitialStack = NULL;
889 }
890 }
891 _SEH2_END;
892
893 /* Set the Thread to initialized */
894 Thread->State = Initialized;
895 return Status;
896}
LONG NTSTATUS
Definition: precomp.h:26
#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
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
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:85
#define UserMode
Definition: asm.h:35
@ ThreadObject
Definition: ketypes.h:445
@ Initialized
Definition: ketypes.h:421
@ AttachedApcEnvironment
Definition: ketypes.h:708
@ OriginalApcEnvironment
Definition: ketypes.h:707
@ AdjustNone
Definition: ketypes.h:472
@ WaitAny
VOID NTAPI KiInitializeContextThread(PKTHREAD Thread, PKSYSTEM_ROUTINE SystemRoutine, PKSTART_ROUTINE StartRoutine, PVOID StartContext, PCONTEXT Context)
#define TIMER_WAIT_BLOCK
Definition: ke.h:166
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
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[SSDT_MAX_ENTRIES]
Definition: procobj.c:23
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#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:1160
PVOID Object
Definition: ketypes.h:456
LIST_ENTRY WaitListEntry
Definition: ketypes.h:444
UCHAR WaitType
Definition: ketypes.h:446
USHORT WaitKey
Definition: ketypes.h:448
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:580
VOID NTAPI KiSuspendRundown(IN PKAPC Apc)
Definition: thrdobj.c:572
VOID NTAPI KiSuspendThread(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: thrdobj.c:596
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:480

Referenced by KeInitializeThread(), and PspCreateThread().

◆ KeQueryBasePriorityThread()

KPRIORITY NTAPI KeQueryBasePriorityThread ( IN PKTHREAD  Thread)

Definition at line 61 of file thrdobj.c.

62{
63 LONG BaseIncrement;
68
69 /* Raise IRQL to synch level */
71
72 /* Lock the thread */
74
75 /* Get the Process */
76 Process = Thread->ApcStatePointer[0]->Process;
77
78 /* Calculate the base increment */
79 BaseIncrement = Thread->BasePriority - Process->BasePriority;
80
81 /* If saturation occured, return the saturation increment instead */
82 if (Thread->Saturation) BaseIncrement = (HIGH_PRIORITY + 1) / 2 *
83 Thread->Saturation;
84
85 /* Release thread lock */
87
88 /* Lower IRQl and return Increment */
90 return BaseIncrement;
91}
#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 1017 of file thrdobj.c.

1018{
1020
1021 /* Return the current priority */
1022 return Thread->Priority;
1023}

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

◆ KeQueryRuntimeThread()

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

Definition at line 980 of file thrdobj.c.

982{
984
985 /* Return the User Time */
986 *UserTime = Thread->UserTime;
987
988 /* Return the Kernel Time */
989 return Thread->KernelTime;
990}
_Out_ PULONG UserTime
Definition: kefuncs.h:773

◆ KeReadStateThread()

BOOLEAN NTAPI KeReadStateThread ( IN PKTHREAD  Thread)

Definition at line 51 of file thrdobj.c.

52{
54
55 /* Return signal state */
56 return (BOOLEAN)Thread->Header.SignalState;
57}

Referenced by NtQueryInformationThread(), and PspExitThread().

◆ KeReadyThread()

VOID NTAPI KeReadyThread ( IN PKTHREAD  Thread)

Definition at line 115 of file thrdobj.c.

116{
120
121 /* Lock the Dispatcher Database */
123
124 /* Make the thread ready */
126
127 /* Unlock dispatcher database */
129}
VOID NTAPI KiReadyThread(IN PKTHREAD Thread)
Definition: thrdschd.c:429

Referenced by PspCreateThread().

◆ KeResumeThread()

ULONG NTAPI KeResumeThread ( IN PKTHREAD  Thread)

Definition at line 397 of file thrdobj.c.

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

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

◆ KeRevertToUserAffinityThread()

VOID NTAPI KeRevertToUserAffinityThread ( VOID  )

Definition at line 1030 of file thrdobj.c.

1031{
1032 KIRQL OldIrql;
1033 PKPRCB Prcb;
1034 PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1036 ASSERT(CurrentThread->SystemAffinityActive != FALSE);
1037
1038 /* Lock the Dispatcher Database */
1040
1041 /* Set the user affinity and processor and disable system affinity */
1042 CurrentThread->Affinity = CurrentThread->UserAffinity;
1043 CurrentThread->IdealProcessor = CurrentThread->UserIdealProcessor;
1044 CurrentThread->SystemAffinityActive = FALSE;
1045
1046 /* Get the current PRCB and check if it doesn't match this affinity */
1047 Prcb = KeGetCurrentPrcb();
1048 if (!(Prcb->SetMember & CurrentThread->Affinity))
1049 {
1050 /* Lock the PRCB */
1051 KiAcquirePrcbLock(Prcb);
1052
1053 /* Check if there's no next thread scheduled */
1054 if (!Prcb->NextThread)
1055 {
1056 /* Select a new thread and set it on standby */
1057 NextThread = KiSelectNextThread(Prcb);
1058 NextThread->State = Standby;
1059 Prcb->NextThread = NextThread;
1060 }
1061
1062 /* Release the PRCB lock */
1063 KiReleasePrcbLock(Prcb);
1064 }
1065
1066 /* Unlock dispatcher database */
1068}
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:1080
@ Standby
Definition: ketypes.h:424
PKTHREAD FASTCALL KiSelectNextThread(IN PKPRCB Prcb)
Definition: thrdschd.c:328
UINT64 SetMember
Definition: ketypes.h:583
struct _KTHREAD * NextThread
Definition: ketypes.h:572
ULONG UserIdealProcessor
Definition: ketypes.h:1723
GROUP_AFFINITY Affinity
Definition: ketypes.h:1878
ULONG IdealProcessor
Definition: ketypes.h:1884
ULONG SystemAffinityActive
Definition: ketypes.h:1637
GROUP_AFFINITY UserAffinity
Definition: ketypes.h:1852
volatile UCHAR State
Definition: ketypes.h:1729

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

◆ KeRundownThread()

VOID NTAPI KeRundownThread ( VOID  )

Definition at line 439 of file thrdobj.c.

440{
443 PLIST_ENTRY NextEntry, ListHead;
444 PKMUTANT Mutant;
446
447 /* Optimized path if nothing is on the list at the moment */
448 if (IsListEmpty(&Thread->MutantListHead)) return;
449
450 /* Lock the Dispatcher Database */
452
453 /* Get the List Pointers */
454 ListHead = &Thread->MutantListHead;
455 NextEntry = ListHead->Flink;
456 while (NextEntry != ListHead)
457 {
458 /* Get the Mutant */
459 Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry);
460 ASSERT_MUTANT(Mutant);
461
462 /* Make sure it's not terminating with APCs off */
463 if (Mutant->ApcDisable)
464 {
465 /* Bugcheck the system */
466 KeBugCheckEx(THREAD_TERMINATE_HELD_MUTEX,
468 (ULONG_PTR)Mutant,
469 0,
470 0);
471 }
472
473 /* Now we can remove it */
475
476 /* Unconditionally abandon it */
477 Mutant->Header.SignalState = 1;
478 Mutant->Abandoned = TRUE;
479 Mutant->OwnerThread = NULL;
480
481 /* Check if the Wait List isn't empty */
482 if (!IsListEmpty(&Mutant->Header.WaitListHead))
483 {
484 /* Wake the Mutant */
486 }
487
488 /* Move on */
489 NextEntry = Thread->MutantListHead.Flink;
490 }
491
492 /* Release the Lock */
494}
#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:796
DISPATCHER_HEADER Header
Definition: ketypes.h:829
LIST_ENTRY MutantListEntry
Definition: ketypes.h:830
BOOLEAN Abandoned
Definition: ketypes.h:832
struct _KTHREAD *RESTRICTED_POINTER OwnerThread
Definition: ketypes.h:831
UCHAR ApcDisable
Definition: ketypes.h:833
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 1303 of file thrdobj.c.

1305{
1306 KIRQL OldIrql;
1307 KAFFINITY OldAffinity;
1310
1311 /* Lock the dispatcher database */
1313
1314 /* Call the internal function */
1315 OldAffinity = KiSetAffinityThread(Thread, Affinity);
1316
1317 /* Release the dispatcher database and return old affinity */
1319 return OldAffinity;
1320}
ULONG_PTR KAFFINITY
Definition: compat.h:85
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 1184 of file thrdobj.c.

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

97{
99
100 /* Check if we're enabling or disabling */
101 if (Disable)
102 {
103 /* Set the bit */
104 return InterlockedBitTestAndSet(&Thread->ThreadFlags, 1);
105 }
106 else
107 {
108 /* Remove the bit */
109 return InterlockedBitTestAndReset(&Thread->ThreadFlags, 1);
110 }
111}
#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 1075 of file thrdobj.c.

1077{
1078 CCHAR OldIdealProcessor;
1079 KIRQL OldIrql;
1081
1082 /* Lock the Dispatcher Database */
1084
1085 /* Save Old Ideal Processor */
1086 OldIdealProcessor = Thread->UserIdealProcessor;
1087
1088 /* Make sure a valid CPU was given */
1090 {
1091 /* Check if the user ideal CPU is in the affinity */
1092 if (Thread->Affinity & AFFINITY_MASK(Processor))
1093 {
1094 /* Set the ideal processor */
1095 Thread->IdealProcessor = Processor;
1096
1097 /* Check if system affinity is used */
1098 if (!Thread->SystemAffinityActive)
1099 {
1100 /* It's not, so update the user CPU too */
1101 Thread->UserIdealProcessor = Processor;
1102 }
1103 }
1104 }
1105
1106 /* Release dispatcher lock and return the old ideal CPU */
1108 return OldIdealProcessor;
1109}
#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:684

Referenced by NtSetInformationThread().

◆ KeSetKernelStackSwapEnable()

BOOLEAN NTAPI KeSetKernelStackSwapEnable ( IN BOOLEAN  Enable)

Definition at line 997 of file thrdobj.c.

998{
1001
1002 /* Save Old State */
1003 PreviousState = Thread->EnableStackSwap;
1004
1005 /* Set New State */
1006 Thread->EnableStackSwap = Enable;
1007
1008 /* Return Old State */
1009 return PreviousState;
1010}
_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 1327 of file thrdobj.c.

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

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

◆ KeSetSystemAffinityThread()

VOID NTAPI KeSetSystemAffinityThread ( IN KAFFINITY  Affinity)

Definition at line 1116 of file thrdobj.c.

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

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

◆ KeStartThread()

VOID NTAPI KeStartThread ( IN OUT PKTHREAD  Thread)

Definition at line 498 of file thrdobj.c.

499{
501#ifdef CONFIG_SMP
502 PKNODE Node;
503 PKPRCB NodePrcb;
504 ULONG Set, Mask;
505#endif
506 UCHAR IdealProcessor = 0;
507 PKPROCESS Process = Thread->ApcState.Process;
508
509 /* Setup static fields from parent */
510 Thread->DisableBoost = Process->DisableBoost;
511#if defined(_M_IX86)
512 Thread->Iopl = Process->Iopl;
513#endif
514 Thread->Quantum = Process->QuantumReset;
515 Thread->QuantumReset = Process->QuantumReset;
516 Thread->SystemAffinityActive = FALSE;
517
518 /* Lock the process */
520
521 /* Setup volatile data */
522 Thread->Priority = Process->BasePriority;
523 Thread->BasePriority = Process->BasePriority;
524 Thread->Affinity = Process->Affinity;
525 Thread->UserAffinity = Process->Affinity;
526
527#ifdef CONFIG_SMP
528 /* Get the KNODE and its PRCB */
529 Node = KeNodeBlock[Process->IdealNode];
530 NodePrcb = KiProcessorBlock[Process->ThreadSeed];
531
532 /* Calculate affinity mask */
533#ifdef _M_ARM
535 Set = 0;
536#else
537 Set = ~NodePrcb->MultiThreadProcessorSet;
538#endif
539 Mask = (ULONG)(Node->ProcessorMask & Process->Affinity);
540 Set &= Mask;
541 if (Set) Mask = Set;
542
543 /* Get the new thread seed */
544 IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask);
545 Process->ThreadSeed = IdealProcessor;
546
547 /* Sanity check */
548 ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor)));
549#endif
550
551 /* Set the Ideal Processor */
552 Thread->IdealProcessor = IdealProcessor;
553 Thread->UserIdealProcessor = IdealProcessor;
554
555 /* Lock the Dispatcher Database */
557
558 /* Insert the thread into the process list */
559 InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
560
561 /* Increase the stack count */
562 ASSERT(Process->StackCount != MAXULONG_PTR);
563 Process->StackCount++;
564
565 /* Release locks and return */
568}
#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:1158
UCHAR NTAPI KeFindNextRightSetAffinity(IN UCHAR Number, IN ULONG Set)
Definition: thrdobj.c:32
Definition: dlist.c:348

Referenced by KeInitializeThread(), and PspCreateThread().

◆ KeSuspendThread()

ULONG NTAPI KeSuspendThread ( PKTHREAD  Thread)

Definition at line 610 of file thrdobj.c.

611{
612 KLOCK_QUEUE_HANDLE ApcLock;
613 ULONG PreviousCount;
616
617 /* Lock the APC Queue */
619
620 /* Save the Old Count */
621 PreviousCount = Thread->SuspendCount;
622
623 /* Handle the maximum */
624 if (PreviousCount == MAXIMUM_SUSPEND_COUNT)
625 {
626 /* Raise an exception */
627 KiReleaseApcLock(&ApcLock);
629 }
630
631 /* Should we bother to queue at all? */
632 if (Thread->ApcQueueable)
633 {
634 /* Increment the suspend count */
635 Thread->SuspendCount++;
636
637 /* Check if we should suspend it */
638 if (!(PreviousCount) && !(Thread->FreezeCount))
639 {
640 /* Is the APC already inserted? */
641 if (!Thread->SuspendApc.Inserted)
642 {
643 /* Not inserted, insert it */
644 Thread->SuspendApc.Inserted = TRUE;
646 }
647 else
648 {
649 /* Lock the dispatcher */
651
652 /* Unsignal the semaphore, the APC was already inserted */
653 Thread->SuspendSemaphore.Header.SignalState--;
654
655 /* Release the dispatcher */
657 }
658 }
659 }
660
661 /* Release Lock and return the Old State */
663 KiExitDispatcher(ApcLock.OldIrql);
664 return PreviousCount;
665}
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 1375 of file thrdobj.c.

1376{
1377 PLIST_ENTRY *ListHead;
1378 PETHREAD Entry, SavedEntry;
1379 PETHREAD *ThreadAddr;
1382 PKPROCESS Process = Thread->ApcState.Process;
1384
1385 /* Lock the process */
1387
1388 /* Make sure we won't get Swapped */
1390
1391 /* Save the Kernel and User Times */
1392 Process->KernelTime += Thread->KernelTime;
1393 Process->UserTime += Thread->UserTime;
1394
1395 /* Get the current entry and our Port */
1397 ThreadAddr = &((PETHREAD)Thread)->ReaperLink;
1398
1399 /* Add it to the reaper's list */
1400 do
1401 {
1402 /* Get the list head */
1403 ListHead = &PspReaperListHead.Flink;
1404
1405 /* Link ourselves */
1406 *ThreadAddr = Entry;
1407 SavedEntry = Entry;
1408
1409 /* Now try to do the exchange */
1411 ThreadAddr,
1412 Entry);
1413
1414 /* Break out if the change was succesful */
1415 } while (Entry != SavedEntry);
1416
1417 /* Acquire the dispatcher lock */
1419
1420 /* Check if the reaper wasn't active */
1421 if (!Entry)
1422 {
1423 /* Activate it as a work item, directly through its Queue */
1426 FALSE);
1427 }
1428
1429 /* Check the thread has an associated queue */
1430 if (Thread->Queue)
1431 {
1432 /* Remove it from the list, and handle the queue */
1433 RemoveEntryList(&Thread->QueueListEntry);
1435 }
1436
1437 /* Signal the thread */
1438 Thread->Header.SignalState = TRUE;
1439 if (!IsListEmpty(&Thread->Header.WaitListHead))
1440 {
1441 /* Unwait the threads */
1442 KxUnwaitThread(&Thread->Header, Increment);
1443 }
1444
1445 /* Remove the thread from the list */
1447
1448 /* Release the process lock */
1450
1451 /* Set us as terminated, decrease the Process's stack count */
1452 Thread->State = Terminated;
1453
1454 /* Decrease stack count */
1455 ASSERT(Process->StackCount != 0);
1456 ASSERT(Process->State == ProcessInMemory);
1457 Process->StackCount--;
1458 if (!(Process->StackCount) && !(IsListEmpty(&Process->ThreadListHead)))
1459 {
1460 /* FIXME: Swap stacks */
1461 }
1462
1463 /* Rundown arch-specific parts */
1465
1466 /* Swap to a new thread */
1469}
#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:493
@ Terminated
Definition: ketypes.h:425
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 731 of file thrdobj.c.

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

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

◆ KeThawAllThreads()

VOID NTAPI KeThawAllThreads ( VOID  )

Definition at line 669 of file thrdobj.c.

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

Referenced by DbgkpResumeProcess().

◆ KeUninitThread()

VOID NTAPI KeUninitThread ( IN PKTHREAD  Thread)

Definition at line 926 of file thrdobj.c.

927{
928 /* Delete the stack */
930 Thread->InitialStack = NULL;
931}

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 580 of file thrdobj.c.

585{
586 /* Does nothing */
588 UNREFERENCED_PARAMETER(NormalRoutine);
589 UNREFERENCED_PARAMETER(NormalContext);
592}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:676
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:677

Referenced by KeInitThread().

◆ KiSuspendRundown()

VOID NTAPI KiSuspendRundown ( IN PKAPC  Apc)

Definition at line 572 of file thrdobj.c.

573{
574 /* Does nothing */
576}

Referenced by KeInitThread().

◆ KiSuspendThread()

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

Definition at line 596 of file thrdobj.c.

599{
600 /* Non-alertable kernel-mode suspended wait */
601 KeWaitForSingleObject(&KeGetCurrentThread()->SuspendSemaphore,
602 Suspended,
604 FALSE,
605 NULL);
606}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
@ Suspended
Definition: ketypes.h:408

Referenced by KeInitThread().

Variable Documentation

◆ ExWorkerQueue

◆ KiMask32Array

ULONG KiMask32Array[MAXIMUM_PRIORITY]
Initial value:
=
{
0x1, 0x2, 0x4, 0x8, 0x10, 0x20,
0x40, 0x80, 0x100, 0x200, 0x400, 0x800,
0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000,
0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000,
0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000,
0x40000000, 0x80000000
}

Definition at line 18 of file thrdobj.c.

◆ PspReaperListHead

LIST_ENTRY PspReaperListHead
extern

Definition at line 19 of file kill.c.

Referenced by KeTerminateThread(), and PspReapRoutine().