ReactOS  r76032
thrdobj.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ke/thrdobj.c
5  * PURPOSE: Implements routines to manage the Kernel Thread Object
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
17 
19 {
20  0x1, 0x2, 0x4, 0x8, 0x10, 0x20,
21  0x40, 0x80, 0x100, 0x200, 0x400, 0x800,
22  0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000,
23  0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000,
24  0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000,
25  0x40000000, 0x80000000
26 };
27 
28 /* FUNCTIONS *****************************************************************/
29 
30 UCHAR
31 NTAPI
33  IN ULONG Set)
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 */
45  BitScanReverse(&Result, Bit);
46  return (UCHAR)Result;
47 }
48 
49 BOOLEAN
50 NTAPI
52 {
53  ASSERT_THREAD(Thread);
54 
55  /* Return signal state */
56  return (BOOLEAN)Thread->Header.SignalState;
57 }
58 
60 NTAPI
62 {
63  LONG BaseIncrement;
64  KIRQL OldIrql;
66  ASSERT_THREAD(Thread);
68 
69  /* Raise IRQL to synch level */
70  OldIrql = KeRaiseIrqlToSynchLevel();
71 
72  /* Lock the thread */
73  KiAcquireThreadLock(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 */
86  KiReleaseThreadLock(Thread);
87 
88  /* Lower IRQl and return Increment */
89  KeLowerIrql(OldIrql);
90  return BaseIncrement;
91 }
92 
93 BOOLEAN
94 NTAPI
96  IN BOOLEAN Disable)
97 {
98  ASSERT_THREAD(Thread);
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 }
112 
113 VOID
114 NTAPI
116 {
117  KIRQL OldIrql;
118  ASSERT_THREAD(Thread);
120 
121  /* Lock the Dispatcher Database */
122  OldIrql = KiAcquireDispatcherLock();
123 
124  /* Make the thread ready */
125  KiReadyThread(Thread);
126 
127  /* Unlock dispatcher database */
128  KiReleaseDispatcherLock(OldIrql);
129 }
130 
131 ULONG
132 NTAPI
134 {
135  ULONG PreviousCount;
136  KLOCK_QUEUE_HANDLE ApcLock;
137  ASSERT_THREAD(Thread);
139 
140  /* Lock the Dispatcher Database and the APC Queue */
141  KiAcquireApcLock(Thread, &ApcLock);
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 }
182 
183 BOOLEAN
184 NTAPI
186  IN KPROCESSOR_MODE AlertMode)
187 {
189  KLOCK_QUEUE_HANDLE ApcLock;
190  ASSERT_THREAD(Thread);
192 
193  /* Lock the Dispatcher Database and the APC Queue */
194  KiAcquireApcLock(Thread, &ApcLock);
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 }
226 
227 VOID
228 NTAPI
231 {
232  KIRQL OldIrql;
235 
236  /* Lock the Dispatcher Database */
237  OldIrql = KiAcquireDispatcherLock();
238 
239  /* Only threads in the dynamic range get boosts */
240  if (Thread->Priority < LOW_REALTIME_PRIORITY)
241  {
242  /* Lock the thread */
243  KiAcquireThreadLock(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  {
253  if (Priority >= LOW_REALTIME_PRIORITY)
254  {
255  Priority = LOW_REALTIME_PRIORITY - 1;
256  }
257 
258  /* Reset the quantum */
259  Thread->Quantum = Thread->QuantumReset;
260 
261  /* Set the new Priority */
262  KiSetPriorityThread(Thread, Priority);
263  }
264  }
265 
266  /* Release thread lock */
267  KiReleaseThreadLock(Thread);
268  }
269 
270  /* Release the dispatcher lokc */
271  KiReleaseDispatcherLock(OldIrql);
272 }
273 
274 ULONG
275 NTAPI
277 {
278  KLOCK_QUEUE_HANDLE ApcLock;
279  ULONG PreviousCount;
280  ASSERT_THREAD(Thread);
282 
283  /* Lock the APC Queue */
284  KiAcquireApcLock(Thread, &ApcLock);
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 }
312 
313 VOID
314 NTAPI
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 */
325  KiAcquireProcessLock(Process, &LockHandle);
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 */
331  KiReleaseProcessLock(&LockHandle);
332  KiAcquireProcessLock(Process, &LockHandle);
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  KiAcquireApcLockAtDpcLevel(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;
368  }
369  else
370  {
371  /* Lock the dispatcher */
373 
374  /* Unsignal the semaphore, the APC was already inserted */
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 */
392  KiExitDispatcher(LockHandle.OldIrql);
393 }
394 
395 ULONG
396 NTAPI
398 {
399  KLOCK_QUEUE_HANDLE ApcLock;
400  ULONG PreviousCount;
401  ASSERT_THREAD(Thread);
403 
404  /* Lock the APC Queue */
405  KiAcquireApcLock(Thread, &ApcLock);
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 }
436 
437 VOID
438 NTAPI
440 {
441  KIRQL OldIrql;
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 */
451  OldIrql = KiAcquireDispatcherLock();
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,
467  (ULONG_PTR)Thread,
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 */
493  KiReleaseDispatcherLock(OldIrql);
494 }
495 
496 VOID
497 NTAPI
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 */
519  KiAcquireProcessLock(Process, &LockHandle);
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
534  DbgBreakPoint();
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 */
567  KiReleaseProcessLock(&LockHandle);
568 }
569 
570 VOID
571 NTAPI
573 {
574  /* Does nothing */
576 }
577 
578 VOID
579 NTAPI
581  IN PKNORMAL_ROUTINE *NormalRoutine,
582  IN PVOID *NormalContext,
585 {
586  /* Does nothing */
588  UNREFERENCED_PARAMETER(NormalRoutine);
589  UNREFERENCED_PARAMETER(NormalContext);
590  UNREFERENCED_PARAMETER(SystemArgument1);
591  UNREFERENCED_PARAMETER(SystemArgument2);
592 }
593 
594 VOID
595 NTAPI
596 KiSuspendThread(IN PVOID NormalContext,
599 {
600  /* Non-alertable kernel-mode suspended wait */
601  KeWaitForSingleObject(&KeGetCurrentThread()->SuspendSemaphore,
602  Suspended,
603  KernelMode,
604  FALSE,
605  NULL);
606 }
607 
608 ULONG
609 NTAPI
611 {
612  KLOCK_QUEUE_HANDLE ApcLock;
613  ULONG PreviousCount;
614  ASSERT_THREAD(Thread);
616 
617  /* Lock the APC Queue */
618  KiAcquireApcLock(Thread, &ApcLock);
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 */
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 }
666 
667 VOID
668 NTAPI
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 */
679  KiAcquireProcessLock(Process, &LockHandle);
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  KiAcquireApcLockAtDpcLevel(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 */
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 */
723  KiExitDispatcher(LockHandle.OldIrql);
724 
725  /* Leave the critical region */
727 }
728 
729 BOOLEAN
730 NTAPI
732 {
734  BOOLEAN OldState;
735  KLOCK_QUEUE_HANDLE ApcLock;
736  ASSERT_THREAD(Thread);
738 
739  /* Lock the Dispatcher Database and the APC Queue */
740  KiAcquireApcLock(Thread, &ApcLock);
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 }
762 
763 NTSTATUS
764 NTAPI
766  IN PVOID KernelStack,
767  IN PKSYSTEM_ROUTINE SystemRoutine,
769  IN PVOID StartContext,
771  IN PVOID Teb,
773 {
774  BOOLEAN AllocatedStack = FALSE;
775  ULONG i;
776  PKWAIT_BLOCK TimerWaitBlock;
777  PKTIMER Timer;
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 */
805  KeInitializeSpinLock(&Thread->ThreadLock);
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,
824  KiSuspendNop,
827  KernelMode,
828  NULL);
829 
830  /* Initialize the Suspend Semaphore */
831  KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
832 
833  /* Setup the timer */
834  Timer = &Thread->Timer;
835  KeInitializeTimer(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 */
868  Status = STATUS_SUCCESS;
869  _SEH2_TRY
870  {
871  /* Initialize the Thread Context */
873  SystemRoutine,
874  StartRoutine,
875  StartContext,
876  Context);
877  }
879  {
880  /* Set failure status */
881  Status = STATUS_UNSUCCESSFUL;
882 
883  /* Check if a stack was allocated */
884  if (AllocatedStack)
885  {
886  /* Delete the stack */
887  MmDeleteKernelStack((PVOID)Thread->StackBase, FALSE);
888  Thread->InitialStack = NULL;
889  }
890  }
891  _SEH2_END;
892 
893  /* Set the Thread to initialized */
894  Thread->State = Initialized;
895  return Status;
896 }
897 
898 VOID
899 NTAPI
902  IN PKSYSTEM_ROUTINE SystemRoutine,
904  IN PVOID StartContext,
906  IN PVOID Teb,
907  IN PVOID KernelStack)
908 {
909  /* Initialize and start the thread on success */
910  if (NT_SUCCESS(KeInitThread(Thread,
911  KernelStack,
912  SystemRoutine,
913  StartRoutine,
914  StartContext,
915  Context,
916  Teb,
917  Process)))
918  {
919  /* Start it */
920  KeStartThread(Thread);
921  }
922 }
923 
924 VOID
925 NTAPI
927 {
928  /* Delete the stack */
929  MmDeleteKernelStack((PVOID)Thread->StackBase, FALSE);
930  Thread->InitialStack = NULL;
931 }
932 
933 /* PUBLIC FUNCTIONS **********************************************************/
934 
935 /*
936  * @unimplemented
937  */
938 VOID
939 NTAPI
941  IN ULONG Setting1,
942  IN ULONG Setting2,
943  IN ULONG Setting3,
944  IN ULONG Setting4,
945  IN ULONG Setting5,
946  IN PVOID ThreadState)
947 {
949 }
950 
951 /*
952  * @implemented
953  */
954 #undef KeGetCurrentThread
955 PKTHREAD
956 NTAPI
958 {
959  /* Return the current thread on this PCR */
960  return _KeGetCurrentThread();
961 }
962 
963 /*
964  * @implemented
965  */
966 #undef KeGetPreviousMode
967 UCHAR
968 NTAPI
970 {
971  /* Return the previous mode of this thread */
972  return _KeGetPreviousMode();
973 }
974 
975 /*
976  * @implemented
977  */
978 ULONG
979 NTAPI
982 {
983  ASSERT_THREAD(Thread);
984 
985  /* Return the User Time */
986  *UserTime = Thread->UserTime;
987 
988  /* Return the Kernel Time */
989  return Thread->KernelTime;
990 }
991 
992 /*
993  * @implemented
994  */
995 BOOLEAN
996 NTAPI
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 }
1011 
1012 /*
1013  * @implemented
1014  */
1015 KPRIORITY
1016 NTAPI
1018 {
1019  ASSERT_THREAD(Thread);
1020 
1021  /* Return the current priority */
1022  return Thread->Priority;
1023 }
1024 
1025 /*
1026  * @implemented
1027  */
1028 VOID
1029 NTAPI
1031 {
1032  KIRQL OldIrql;
1033  PKPRCB Prcb;
1034  PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1036  ASSERT(CurrentThread->SystemAffinityActive != FALSE);
1037 
1038  /* Lock the Dispatcher Database */
1039  OldIrql = KiAcquireDispatcherLock();
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 */
1067  KiReleaseDispatcherLock(OldIrql);
1068 }
1069 
1070 /*
1071  * @implemented
1072  */
1073 UCHAR
1074 NTAPI
1076  IN UCHAR Processor)
1077 {
1078  CCHAR OldIdealProcessor;
1079  KIRQL OldIrql;
1080  ASSERT(Processor <= MAXIMUM_PROCESSORS);
1081 
1082  /* Lock the Dispatcher Database */
1083  OldIrql = KiAcquireDispatcherLock();
1084 
1085  /* Save Old Ideal Processor */
1086  OldIdealProcessor = Thread->UserIdealProcessor;
1087 
1088  /* Make sure a valid CPU was given */
1089  if (Processor < KeNumberProcessors)
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 */
1107  KiReleaseDispatcherLock(OldIrql);
1108  return OldIdealProcessor;
1109 }
1110 
1111 /*
1112  * @implemented
1113  */
1114 VOID
1115 NTAPI
1117 {
1118  KIRQL OldIrql;
1119  PKPRCB Prcb;
1120  PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1122  ASSERT((Affinity & KeActiveProcessors) != 0);
1123 
1124  /* Lock the Dispatcher Database */
1125  OldIrql = KiAcquireDispatcherLock();
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 */
1176  KiReleaseDispatcherLock(OldIrql);
1177 }
1178 
1179 /*
1180  * @implemented
1181  */
1182 LONG
1183 NTAPI
1185  IN LONG Increment)
1186 {
1187  KIRQL OldIrql;
1188  KPRIORITY OldBasePriority, Priority, BasePriority;
1189  LONG OldIncrement;
1191  ASSERT_THREAD(Thread);
1193 
1194  /* Get the process */
1195  Process = Thread->ApcState.Process;
1196 
1197  /* Lock the Dispatcher Database */
1198  OldIrql = KiAcquireDispatcherLock();
1199 
1200  /* Lock the thread */
1201  KiAcquireThreadLock(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 */
1259  Priority = KiComputeNewPriority(Thread, 0);
1260  Priority += (BasePriority - OldBasePriority);
1261 
1262  /* Check if it entered the real-time range */
1263  if (Priority >= LOW_REALTIME_PRIORITY)
1264  {
1265  /* Normalize it down to the highest dynamic priority */
1266  Priority = LOW_REALTIME_PRIORITY - 1;
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;
1287  KiSetPriorityThread(Thread, Priority);
1288  }
1289 
1290  /* Release thread lock */
1291  KiReleaseThreadLock(Thread);
1292 
1293  /* Release the dispatcher database and return old increment */
1294  KiReleaseDispatcherLock(OldIrql);
1295  return OldIncrement;
1296 }
1297 
1298 /*
1299  * @implemented
1300  */
1301 KAFFINITY
1302 NTAPI
1305 {
1306  KIRQL OldIrql;
1307  KAFFINITY OldAffinity;
1308  ASSERT_THREAD(Thread);
1310 
1311  /* Lock the dispatcher database */
1312  OldIrql = KiAcquireDispatcherLock();
1313 
1314  /* Call the internal function */
1315  OldAffinity = KiSetAffinityThread(Thread, Affinity);
1316 
1317  /* Release the dispatcher database and return old affinity */
1318  KiReleaseDispatcherLock(OldIrql);
1319  return OldAffinity;
1320 }
1321 
1322 /*
1323  * @implemented
1324  */
1325 KPRIORITY
1326 NTAPI
1329 {
1330  KIRQL OldIrql;
1331  KPRIORITY OldPriority;
1332  ASSERT_THREAD(Thread);
1334  ASSERT((Priority <= HIGH_PRIORITY) && (Priority >= LOW_PRIORITY));
1336 
1337  /* Lock the Dispatcher Database */
1338  OldIrql = KiAcquireDispatcherLock();
1339 
1340  /* Lock the thread */
1341  KiAcquireThreadLock(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 */
1357  KiSetPriorityThread(Thread, Priority);
1358  }
1359 
1360  /* Release thread lock */
1361  KiReleaseThreadLock(Thread);
1362 
1363  /* Release the dispatcher database */
1364  KiReleaseDispatcherLock(OldIrql);
1365 
1366  /* Return Old Priority */
1367  return OldPriority;
1368 }
1369 
1370 /*
1371  * @implemented
1372  */
1373 VOID
1374 NTAPI
1376 {
1377  PLIST_ENTRY *ListHead;
1378  PETHREAD Entry, SavedEntry;
1379  PETHREAD *ThreadAddr;
1382  PKPROCESS Process = Thread->ApcState.Process;
1384 
1385  /* Lock the process */
1386  KiAcquireProcessLock(Process, &LockHandle);
1387 
1388  /* Make sure we won't get Swapped */
1389  KiSetThreadSwapBusy(Thread);
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 */
1396  Entry = (PETHREAD)PspReaperListHead.Flink;
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 */
1410  Entry = InterlockedCompareExchangePointer((PVOID*)ListHead,
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 */
1424  KiInsertQueue(&ExWorkerQueue[HyperCriticalWorkQueue].WorkerQueue,
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);
1434  KiActivateWaiterQueue(Thread->Queue);
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 */
1446  RemoveEntryList(&Thread->ThreadListEntry);
1447 
1448  /* Release the process lock */
1449  KiReleaseProcessLockFromDpcLevel(&LockHandle);
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 */
1464  KiRundownThread(Thread);
1465 
1466  /* Swap to a new thread */
1468  KiSwapThread(Thread, KeGetCurrentPrcb());
1469 }
DWORD *typedef PVOID
Definition: winlogon.h:52
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 MAXIMUM_PROCESSORS
Definition: rwlock.h:5
FORCEINLINE VOID KiReleaseThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:244
SCHAR QuantumReset
Definition: ketypes.h:1418
ULONG NTAPI KeQueryRuntimeThread(IN PKTHREAD Thread, OUT PULONG UserTime)
Definition: thrdobj.c:980
#define abs(i)
Definition: fconv.c:206
KAFFINITY FASTCALL KiSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdschd.c:685
BOOLEAN Alerted[2]
Definition: ketypes.h:944
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:250
ULONG FreezeCount
Definition: ketypes.h:1225
#define IN
Definition: typedefs.h:38
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
VOID FASTCALL KiUnwaitThread(IN PKTHREAD Thread, IN LONG_PTR WaitStatus, IN KPRIORITY Increment)
Definition: wait.c:89
ULONG NTAPI KeForceResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:276
#define TRUE
Definition: types.h:120
ULONG UserIdealProcessor
Definition: ketypes.h:1235
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG DisableBoost
Definition: ketypes.h:1411
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
LIST_ENTRY List
Definition: extypes.h:203
VOID NTAPI KeStartThread(IN OUT PKTHREAD Thread)
Definition: thrdobj.c:498
ULONG EnableStackSwap
Definition: ketypes.h:1085
UCHAR NTAPI KeFindNextRightSetAffinity(IN UCHAR Number, IN ULONG Set)
Definition: thrdobj.c:32
struct _Entry Entry
Definition: kefuncs.h:640
FORCEINLINE VOID KiReleasePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:224
UCHAR State
Definition: ketypes.h:1419
KAFFINITY NTAPI KeSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdobj.c:1303
BOOLEAN Enable
Definition: acefiex.h:245
LIST_ENTRY WaitListEntry
Definition: ketypes.h:444
FORCEINLINE VOID KiReleaseProcessLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:660
_In_ ULONG _In_opt_ POBJECT_ATTRIBUTES _In_opt_ HANDLE _Out_opt_ PCLIENT_ID _In_ PKSTART_ROUTINE StartRoutine
Definition: psfuncs.h:87
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:315
SCHAR BasePriority
Definition: ketypes.h:1417
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
return STATUS_SUCCESS
Definition: btrfs.c:2664
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1030
VOID NTAPI MmDeleteKernelStack(PVOID Stack, BOOLEAN GuiStack)
#define _KeGetPreviousMode()
Definition: ketypes.h:1078
FORCEINLINE VOID KiSetThreadSwapBusy(IN PKTHREAD Thread)
Definition: ke_x.h:204
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1054
VOID NTAPI KeThawAllThreads(VOID)
Definition: thrdobj.c:669
_In_ KPRIORITY Priority
Definition: kefuncs.h:516
FORCEINLINE VOID KiAcquireApcLock(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:600
VOID NTAPI KeReadyThread(IN PKTHREAD Thread)
Definition: thrdobj.c:115
PKTHREAD FASTCALL KiSelectNextThread(IN PKPRCB Prcb)
Definition: thrdschd.c:328
#define MAXULONG_PTR
Definition: basetsd.h:102
_In_ UCHAR Processor
Definition: kefuncs.h:695
VOID FASTCALL KiWaitTest(PVOID Object, KPRIORITY Increment)
LONG NTAPI KeSetBasePriorityThread(IN PKTHREAD Thread, IN LONG Increment)
Definition: thrdobj.c:1184
#define AFFINITY_MASK(Id)
Definition: ke.h:148
KPRIORITY NTAPI KeQueryPriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:1017
VOID FASTCALL KiInsertQueueApc(IN PKAPC Apc, IN KPRIORITY PriorityBoost)
Definition: apc.c:85
_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
FORCEINLINE VOID KiAcquireApcLockAtDpcLevel(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:609
#define InsertTailList(ListHead, Entry)
#define LOW_REALTIME_PRIORITY
#define STATUS_ALERTED
Definition: ntstatus.h:80
FORCEINLINE VOID KiReleaseApcLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:627
void DbgBreakPoint()
Definition: mach.c:558
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
BOOLEAN NTAPI KeIsExecutingDpc(VOID)
Definition: dpc.c:946
struct _KTHREAD * NextThread
Definition: ketypes.h:567
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
LONG KPRIORITY
Definition: compat.h:454
VOID NTAPI KeUninitThread(IN PKTHREAD Thread)
Definition: thrdobj.c:926
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1116
#define ASSERT_THREAD(object)
Definition: ketypes.h:1372
BOOLEAN NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:731
BOOLEAN NTAPI KeAlertThread(IN PKTHREAD Thread, IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:185
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define TIMER_WAIT_BLOCK
Definition: ke.h:155
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
FORCEINLINE SCHAR KiComputeNewPriority(IN PKTHREAD Thread, IN SCHAR Adjustment)
Definition: ke_x.h:1458
LIST_ENTRY PspReaperListHead
Definition: kill.c:19
WORK_QUEUE_ITEM PspReaperWorkItem
Definition: kill.c:20
UCHAR KIRQL
Definition: env_spec_w32.h:591
EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue]
Definition: work.c:35
KPRIORITY NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:61
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: thrdobj.c:900
VOID NTAPI KiInitializeContextThread(PKTHREAD Thread, PKSYSTEM_ROUTINE SystemRoutine, PKSTART_ROUTINE StartRoutine, PVOID StartContext, PCONTEXT Context)
VOID NTAPI KeFreezeAllThreads(VOID)
Definition: thrdobj.c:315
GLenum GLclampf GLint i
Definition: glfuncs.h:14
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
KSEMAPHORE SuspendSemaphore
Definition: ketypes.h:1339
#define FALSE
Definition: types.h:117
KSTART_ROUTINE * PKSTART_ROUTINE
Definition: ketypes.h:472
long LONG
Definition: pedump.c:60
DISPATCHER_HEADER Header
Definition: ketypes.h:825
VOID NTAPI KiSuspendThread(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: thrdobj.c:596
#define _KeGetCurrentThread()
Definition: ketypes.h:1077
KAPC_STATE ApcState
Definition: ketypes.h:969
ULONG SystemAffinityActive
Definition: ketypes.h:953
#define _SEH2_END
Definition: pseh2_64.h:7
VOID FASTCALL KiSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdschd.c:511
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
BOOLEAN NTAPI KeSetDisableBoostThread(IN OUT PKTHREAD Thread, IN BOOLEAN Disable)
Definition: thrdobj.c:95
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define InterlockedBitTestAndReset
Definition: interlocked.h:35
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
FORCEINLINE VOID KiAcquirePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:214
ULONG StackCount
Definition: ketypes.h:1429
LIST_ENTRY MutantListEntry
Definition: ketypes.h:815
#define LOW_PRIORITY
smooth NULL
Definition: ftsmooth.c:557
FORCEINLINE VOID KiReleaseApcLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:635
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
LIST_ENTRY QueueListEntry
Definition: ketypes.h:1180
DISPATCHER_HEADER Header
Definition: ketypes.h:814
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
LIST_ENTRY ThreadListHead
Definition: ketypes.h:1403
VOID NTAPI KeBoostPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Increment)
Definition: thrdobj.c:229
VOID FASTCALL KiExitDispatcher(KIRQL OldIrql)
VOID NTAPI KiReadyThread(IN PKTHREAD Thread)
Definition: thrdschd.c:429
VOID NTAPI KeTerminateThread(IN KPRIORITY Increment)
Definition: thrdobj.c:1375
_Out_ PULONG UserTime
Definition: kefuncs.h:784
#define InterlockedBitTestAndSet
Definition: interlocked.h:30
CCHAR SuspendCount
Definition: ketypes.h:1257
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:660
FORCEINLINE VOID KiAcquireThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:234
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
KAFFINITY Affinity
Definition: ketypes.h:1405
unsigned char BOOLEAN
ULONG KernelTime
Definition: ketypes.h:1305
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
struct _KNODE * ParentNode
Definition: ketypes.h:751
UCHAR WaitType
Definition: ketypes.h:449
if(!(yy_init))
Definition: macro.lex.yy.c:704
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
VOID(NTAPI * PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
Definition: ketypes.h:625
char CCHAR
Definition: typedefs.h:50
USHORT WaitKey
Definition: ketypes.h:448
PVOID Object
Definition: ketypes.h:446
PKNODE KeNodeBlock[1]
Definition: krnlinit.c:39
signed char SCHAR
Definition: sqltypes.h:14
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
PKQUEUE Queue
Definition: ketypes.h:1044
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:632
#define KERNEL_STACK_SIZE
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define MUTANT_INCREMENT
Definition: extypes.h:84
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
FORCEINLINE VOID KiReleaseProcessLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:652
ULONG NTAPI KeAlertResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:133
unsigned char UCHAR
Definition: xmlstorage.h:181
#define ASSERT_MUTANT(Object)
#define MAXIMUM_SUSPEND_COUNT
Definition: winbase.h:377
UCHAR ThreadSeed
Definition: ketypes.h:1420
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
UCHAR IdealNode
Definition: ketypes.h:1422
#define BitScanReverse
Definition: interlocked.h:6
FORCEINLINE VOID KiAcquireProcessLock(IN PKPROCESS Process, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:643
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
ULONG IdealProcessor
Definition: ketypes.h:1234
Definition: ketypes.h:520
Definition: typedefs.h:117
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
static BOOL Set
Definition: gflags.c:18
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:660
UINT64 SetMember
Definition: ketypes.h:578
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
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: thrdobj.c:940
_In_ PLARGE_INTEGER _In_opt_ PTIMER_APC_ROUTINE _In_opt_ PVOID _In_ BOOLEAN _In_opt_ LONG _Out_opt_ PBOOLEAN PreviousState
Definition: zwfuncs.h:428
UINT Timer
Definition: capclock.c:11
LONG NTSTATUS
Definition: DriverTester.h:11
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:152
DISPATCHER_HEADER Header
Definition: ketypes.h:789
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:144
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1327
LONG_PTR FASTCALL KiSwapThread(IN PKTHREAD Thread, IN PKPRCB Prcb)
Definition: thrdschd.c:355
UINT64 MultiThreadProcessorSet
Definition: ketypes.h:752
UCHAR ApcDisable
Definition: ketypes.h:818
ULONG_PTR KAFFINITY
Definition: compat.h:75
PKPRCB KiProcessorBlock[]
Definition: krnlinit.c:32
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LONG NTAPI KiInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry, BOOLEAN Head)
#define _SEH2_TRY
Definition: pseh2_64.h:5
VOID NTAPI KeRundownThread(VOID)
Definition: thrdobj.c:439
FORCEINLINE VOID KiRundownThread(IN PKTHREAD Thread)
Definition: ke.h:206
unsigned int * PULONG
Definition: retypes.h:1
ULONG NTAPI KeResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:397
UCHAR NTAPI KeGetPreviousMode(VOID)
Definition: thrdobj.c:969
ULONG KernelTime
Definition: ketypes.h:1398
VOID FASTCALL KiActivateWaiterQueue(IN PKQUEUE Queue)
Definition: queue.c:24
LIST_ENTRY ThreadListEntry
Definition: ketypes.h:1351
BOOLEAN Abandoned
Definition: ketypes.h:817
ULONG UserTime
Definition: ketypes.h:1335
FORCEINLINE VOID KiReleaseDispatcherLockFromDpcLevel(VOID)
Definition: ke_x.h:168
DISPATCHER_HEADER Header
Definition: ketypes.h:927
struct _KTHREAD *RESTRICTED_POINTER OwnerThread
Definition: ketypes.h:816
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
ULONG KiMask32Array[MAXIMUM_PRIORITY]
Definition: thrdobj.c:18
#define OUT
Definition: typedefs.h:39
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[SSDT_MAX_ENTRIES]
Definition: procobj.c:23
volatile UCHAR State
Definition: ketypes.h:997
GROUP_AFFINITY Affinity
Definition: ketypes.h:1233
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:259
#define UNIMPLEMENTED
Definition: debug.h:114
#define ULONG_PTR
Definition: config.h:101
BOOLEAN Inserted
Definition: ketypes.h:540
PKTHREAD NTAPI KeGetCurrentThread(VOID)
Definition: thrdobj.c:957
BOOLEAN NTAPI KeReadStateThread(IN PKTHREAD Thread)
Definition: thrdobj.c:51
struct _ETHREAD * PETHREAD
Definition: nt_native.h:29
*LockHandle LockHandle _Out_ PKLOCK_QUEUE_HANDLE LockHandle
Definition: kefuncs.h:742
VOID NTAPI KiSuspendRundown(IN PKAPC Apc)
Definition: thrdobj.c:572
#define HIGH_PRIORITY
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
LIST_ENTRY WaitListHead
Definition: ketypes.h:781
KAFFINITY ProcessorMask
Definition: ketypes.h:776
ULONG ApcQueueable
Definition: ketypes.h:1084
UCHAR NTAPI KeSetIdealProcessorThread(IN PKTHREAD Thread, IN UCHAR Processor)
Definition: thrdobj.c:1075
PVOID NTAPI MmCreateKernelStack(BOOLEAN GuiStack, UCHAR Node)
FORCEINLINE VOID KxUnwaitThread(IN DISPATCHER_HEADER *Object, IN KPRIORITY Increment)
Definition: ke_x.h:1250
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:42
ULONG UserTime
Definition: ketypes.h:1399
#define STATUS_SUSPEND_COUNT_EXCEEDED
Definition: ntstatus.h:296
GROUP_AFFINITY UserAffinity
Definition: ketypes.h:1231
#define THREAD_ALERT_INCREMENT
Definition: ketypes.h:126
KAPC SuspendApc
Definition: ketypes.h:1285
union gl_dlist_node Node
Definition: dlist.c:302
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:90
VOID NTAPI KiSuspendNop(IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
Definition: thrdobj.c:580
#define THREAD_WAIT_OBJECTS
Definition: ketypes.h:465
BOOLEAN NTAPI KeSetKernelStackSwapEnable(IN BOOLEAN Enable)
Definition: thrdobj.c:997
struct _KWAIT_BLOCK * NextWaitBlock
Definition: ketypes.h:447
FORCEINLINE VOID KiAcquireDispatcherLockAtDpcLevel(VOID)
Definition: ke_x.h:160
#define MAXIMUM_PRIORITY
LIST_ENTRY MutantListHead
Definition: ketypes.h:1353
ULONG NTAPI KeSuspendThread(PKTHREAD Thread)
Definition: thrdobj.c:610
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: pic.c:156