ReactOS 0.4.15-dev-7098-ge0c17c3
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
18/* FUNCTIONS *****************************************************************/
19
23 IN ULONG Set)
24{
25 ULONG Bit, Result;
26 ASSERT(Set != 0);
27
28 /* Calculate the mask */
29 Bit = (AFFINITY_MASK(Number) - 1) & Set;
30
31 /* If it's 0, use the one we got */
32 if (!Bit) Bit = Set;
33
34 /* Now find the right set and return it */
36 return (UCHAR)Result;
37}
38
42{
44
45 /* Return signal state */
46 return (BOOLEAN)Thread->Header.SignalState;
47}
48
52{
53 LONG BaseIncrement;
58
59 /* Raise IRQL to synch level */
61
62 /* Lock the thread */
64
65 /* Get the Process */
66 Process = Thread->ApcStatePointer[0]->Process;
67
68 /* Calculate the base increment */
69 BaseIncrement = Thread->BasePriority - Process->BasePriority;
70
71 /* If saturation occured, return the saturation increment instead */
72 if (Thread->Saturation) BaseIncrement = (HIGH_PRIORITY + 1) / 2 *
73 Thread->Saturation;
74
75 /* Release thread lock */
77
78 /* Lower IRQl and return Increment */
80 return BaseIncrement;
81}
82
86 IN BOOLEAN Disable)
87{
89
90 /* Check if we're enabling or disabling */
91 if (Disable)
92 {
93 /* Set the bit */
94 return InterlockedBitTestAndSet(&Thread->ThreadFlags, 1);
95 }
96 else
97 {
98 /* Remove the bit */
99 return InterlockedBitTestAndReset(&Thread->ThreadFlags, 1);
100 }
101}
102
103VOID
104NTAPI
106{
110
111 /* Lock the Dispatcher Database */
113
114 /* Make the thread ready */
116
117 /* Unlock dispatcher database */
119}
120
121ULONG
122NTAPI
124{
125 ULONG PreviousCount;
126 KLOCK_QUEUE_HANDLE ApcLock;
129
130 /* Lock the Dispatcher Database and the APC Queue */
133
134 /* Return if Thread is already alerted. */
135 if (!Thread->Alerted[KernelMode])
136 {
137 /* If it's Blocked, unblock if it we should */
138 if ((Thread->State == Waiting) && (Thread->Alertable))
139 {
140 /* Abort the wait */
142 }
143 else
144 {
145 /* If not, simply Alert it */
146 Thread->Alerted[KernelMode] = TRUE;
147 }
148 }
149
150 /* Save the old Suspend Count */
151 PreviousCount = Thread->SuspendCount;
152
153 /* If the thread is suspended, decrease one of the suspend counts */
154 if (PreviousCount)
155 {
156 /* Decrease count. If we are now zero, unwait it completely */
157 Thread->SuspendCount--;
158 if (!(Thread->SuspendCount) && !(Thread->FreezeCount))
159 {
160 /* Signal and satisfy */
161 Thread->SuspendSemaphore.Header.SignalState++;
162 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
163 }
164 }
165
166 /* Release Locks and return the Old State */
169 KiExitDispatcher(ApcLock.OldIrql);
170 return PreviousCount;
171}
172
174NTAPI
176 IN KPROCESSOR_MODE AlertMode)
177{
179 KLOCK_QUEUE_HANDLE ApcLock;
182
183 /* Lock the Dispatcher Database and the APC Queue */
186
187 /* Save the Previous State */
188 PreviousState = Thread->Alerted[AlertMode];
189
190 /* Check if it's already alerted */
191 if (!PreviousState)
192 {
193 /* Check if the thread is alertable, and blocked in the given mode */
194 if ((Thread->State == Waiting) &&
195 (Thread->Alertable) &&
196 (AlertMode <= Thread->WaitMode))
197 {
198 /* Abort the wait to alert the thread */
200 }
201 else
202 {
203 /* Otherwise, merely set the alerted state */
204 Thread->Alerted[AlertMode] = TRUE;
205 }
206 }
207
208 /* Release the Dispatcher Lock */
211 KiExitDispatcher(ApcLock.OldIrql);
212
213 /* Return the old state */
214 return PreviousState;
215}
216
217VOID
218NTAPI
221{
225
226 /* Lock the Dispatcher Database */
228
229 /* Only threads in the dynamic range get boosts */
230 if (Thread->Priority < LOW_REALTIME_PRIORITY)
231 {
232 /* Lock the thread */
234
235 /* Check again, and make sure there's not already a boost */
236 if ((Thread->Priority < LOW_REALTIME_PRIORITY) &&
237 !(Thread->PriorityDecrement))
238 {
239 /* Compute the new priority and see if it's higher */
240 Priority = Thread->BasePriority + Increment;
241 if (Priority > Thread->Priority)
242 {
244 {
246 }
247
248 /* Reset the quantum */
249 Thread->Quantum = Thread->QuantumReset;
250
251 /* Set the new Priority */
253 }
254 }
255
256 /* Release thread lock */
258 }
259
260 /* Release the dispatcher lokc */
262}
263
264ULONG
265NTAPI
267{
268 KLOCK_QUEUE_HANDLE ApcLock;
269 ULONG PreviousCount;
272
273 /* Lock the APC Queue */
275
276 /* Save the old Suspend Count */
277 PreviousCount = Thread->SuspendCount + Thread->FreezeCount;
278
279 /* If the thread is suspended, wake it up!!! */
280 if (PreviousCount)
281 {
282 /* Unwait it completely */
283 Thread->SuspendCount = 0;
284 Thread->FreezeCount = 0;
285
286 /* Lock the dispatcher */
288
289 /* Signal and satisfy */
290 Thread->SuspendSemaphore.Header.SignalState++;
291 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
292
293 /* Release the dispatcher */
295 }
296
297 /* Release Lock and return the Old State */
299 KiExitDispatcher(ApcLock.OldIrql);
300 return PreviousCount;
301}
302
303VOID
304NTAPI
306{
308 PKTHREAD Current, CurrentThread = KeGetCurrentThread();
309 PKPROCESS Process = CurrentThread->ApcState.Process;
310 PLIST_ENTRY ListHead, NextEntry;
311 LONG OldCount;
313
314 /* Lock the process */
316
317 /* If someone is already trying to free us, try again */
318 while (CurrentThread->FreezeCount)
319 {
320 /* Release and re-acquire the process lock so the APC will go through */
323 }
324
325 /* Enter a critical region */
327
328 /* Loop the Process's Threads */
329 ListHead = &Process->ThreadListHead;
330 NextEntry = ListHead->Flink;
331 do
332 {
333 /* Get the current thread */
334 Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
335
336 /* Lock it */
337 KiAcquireApcLockAtSynchLevel(Current, &ApcLock);
338
339 /* Make sure it's not ours, and check if APCs are enabled */
340 if ((Current != CurrentThread) && (Current->ApcQueueable))
341 {
342 /* Sanity check */
343 OldCount = Current->SuspendCount;
344 ASSERT(OldCount != MAXIMUM_SUSPEND_COUNT);
345
346 /* Increase the freeze count */
347 Current->FreezeCount++;
348
349 /* Make sure it wasn't already suspended */
350 if (!(OldCount) && !(Current->SuspendCount))
351 {
352 /* Did we already insert it? */
353 if (!Current->SuspendApc.Inserted)
354 {
355 /* Insert the APC */
356 Current->SuspendApc.Inserted = TRUE;
357 KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT);
358 }
359 else
360 {
361 /* Lock the dispatcher */
363
364 /* Unsignal the semaphore, the APC was already inserted */
365 Current->SuspendSemaphore.Header.SignalState--;
366
367 /* Release the dispatcher */
369 }
370 }
371 }
372
373 /* Release the APC lock */
375
376 /* Move to the next thread */
377 NextEntry = NextEntry->Flink;
378 } while (NextEntry != ListHead);
379
380 /* Release the process lock and exit the dispatcher */
383}
384
385ULONG
386NTAPI
388{
389 KLOCK_QUEUE_HANDLE ApcLock;
390 ULONG PreviousCount;
393
394 /* Lock the APC Queue */
396
397 /* Save the Old Count */
398 PreviousCount = Thread->SuspendCount;
399
400 /* Check if it existed */
401 if (PreviousCount)
402 {
403 /* Decrease the suspend count */
404 Thread->SuspendCount--;
405
406 /* Check if the thrad is still suspended or not */
407 if ((!Thread->SuspendCount) && (!Thread->FreezeCount))
408 {
409 /* Acquire the dispatcher lock */
411
412 /* Signal the Suspend Semaphore */
413 Thread->SuspendSemaphore.Header.SignalState++;
414 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
415
416 /* Release the dispatcher lock */
418 }
419 }
420
421 /* Release APC Queue lock and return the Old State */
423 KiExitDispatcher(ApcLock.OldIrql);
424 return PreviousCount;
425}
426
427VOID
428NTAPI
430{
433 PLIST_ENTRY NextEntry, ListHead;
434 PKMUTANT Mutant;
436
437 /* Optimized path if nothing is on the list at the moment */
438 if (IsListEmpty(&Thread->MutantListHead)) return;
439
440 /* Lock the Dispatcher Database */
442
443 /* Get the List Pointers */
444 ListHead = &Thread->MutantListHead;
445 NextEntry = ListHead->Flink;
446 while (NextEntry != ListHead)
447 {
448 /* Get the Mutant */
449 Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry);
450 ASSERT_MUTANT(Mutant);
451
452 /* Make sure it's not terminating with APCs off */
453 if (Mutant->ApcDisable)
454 {
455 /* Bugcheck the system */
456 KeBugCheckEx(THREAD_TERMINATE_HELD_MUTEX,
458 (ULONG_PTR)Mutant,
459 0,
460 0);
461 }
462
463 /* Now we can remove it */
465
466 /* Unconditionally abandon it */
467 Mutant->Header.SignalState = 1;
468 Mutant->Abandoned = TRUE;
469 Mutant->OwnerThread = NULL;
470
471 /* Check if the Wait List isn't empty */
472 if (!IsListEmpty(&Mutant->Header.WaitListHead))
473 {
474 /* Wake the Mutant */
476 }
477
478 /* Move on */
479 NextEntry = Thread->MutantListHead.Flink;
480 }
481
482 /* Release the Lock */
484}
485
486VOID
487NTAPI
489{
491#ifdef CONFIG_SMP
492 PKNODE Node;
493 PKPRCB NodePrcb;
494 ULONG Set, Mask;
495#endif
496 UCHAR IdealProcessor = 0;
497 PKPROCESS Process = Thread->ApcState.Process;
498
499 /* Setup static fields from parent */
500 Thread->DisableBoost = Process->DisableBoost;
501#if defined(_M_IX86)
502 Thread->Iopl = Process->Iopl;
503#endif
504 Thread->Quantum = Process->QuantumReset;
505 Thread->QuantumReset = Process->QuantumReset;
506 Thread->SystemAffinityActive = FALSE;
507
508 /* Lock the process */
510
511 /* Setup volatile data */
512 Thread->Priority = Process->BasePriority;
513 Thread->BasePriority = Process->BasePriority;
514 Thread->Affinity = Process->Affinity;
515 Thread->UserAffinity = Process->Affinity;
516
517#ifdef CONFIG_SMP
518 /* Get the KNODE and its PRCB */
519 Node = KeNodeBlock[Process->IdealNode];
520 NodePrcb = KiProcessorBlock[Process->ThreadSeed];
521
522 /* Calculate affinity mask */
523#ifdef _M_ARM
525 Set = 0;
526#else
527 Set = ~NodePrcb->MultiThreadProcessorSet;
528#endif
529 Mask = (ULONG)(Node->ProcessorMask & Process->Affinity);
530 Set &= Mask;
531 if (Set) Mask = Set;
532
533 /* Get the new thread seed */
534 IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask);
535 Process->ThreadSeed = IdealProcessor;
536
537 /* Sanity check */
538 ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor)));
539#endif
540
541 /* Set the Ideal Processor */
542 Thread->IdealProcessor = IdealProcessor;
543 Thread->UserIdealProcessor = IdealProcessor;
544
545 /* Lock the Dispatcher Database */
547
548 /* Insert the thread into the process list */
549 InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
550
551 /* Increase the stack count */
552 ASSERT(Process->StackCount != MAXULONG_PTR);
553 Process->StackCount++;
554
555 /* Release locks and return */
558}
559
560VOID
561NTAPI
563{
564 /* Does nothing */
566}
567
568VOID
569NTAPI
571 IN PKNORMAL_ROUTINE *NormalRoutine,
572 IN PVOID *NormalContext,
575{
576 /* Does nothing */
578 UNREFERENCED_PARAMETER(NormalRoutine);
579 UNREFERENCED_PARAMETER(NormalContext);
582}
583
584VOID
585NTAPI
589{
590 /* Non-alertable kernel-mode suspended wait */
591 KeWaitForSingleObject(&KeGetCurrentThread()->SuspendSemaphore,
592 Suspended,
594 FALSE,
595 NULL);
596}
597
598ULONG
599NTAPI
601{
602 KLOCK_QUEUE_HANDLE ApcLock;
603 ULONG PreviousCount;
606
607 /* Lock the APC Queue */
609
610 /* Save the Old Count */
611 PreviousCount = Thread->SuspendCount;
612
613 /* Handle the maximum */
614 if (PreviousCount == MAXIMUM_SUSPEND_COUNT)
615 {
616 /* Raise an exception */
617 KiReleaseApcLock(&ApcLock);
619 }
620
621 /* Should we bother to queue at all? */
622 if (Thread->ApcQueueable)
623 {
624 /* Increment the suspend count */
625 Thread->SuspendCount++;
626
627 /* Check if we should suspend it */
628 if (!(PreviousCount) && !(Thread->FreezeCount))
629 {
630 /* Is the APC already inserted? */
631 if (!Thread->SuspendApc.Inserted)
632 {
633 /* Not inserted, insert it */
634 Thread->SuspendApc.Inserted = TRUE;
636 }
637 else
638 {
639 /* Lock the dispatcher */
641
642 /* Unsignal the semaphore, the APC was already inserted */
643 Thread->SuspendSemaphore.Header.SignalState--;
644
645 /* Release the dispatcher */
647 }
648 }
649 }
650
651 /* Release Lock and return the Old State */
653 KiExitDispatcher(ApcLock.OldIrql);
654 return PreviousCount;
655}
656
657VOID
658NTAPI
660{
662 PKTHREAD Current, CurrentThread = KeGetCurrentThread();
663 PKPROCESS Process = CurrentThread->ApcState.Process;
664 PLIST_ENTRY ListHead, NextEntry;
665 LONG OldCount;
667
668 /* Lock the process */
670
671 /* Loop the Process's Threads */
672 ListHead = &Process->ThreadListHead;
673 NextEntry = ListHead->Flink;
674 do
675 {
676 /* Get the current thread */
677 Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
678
679 /* Lock it */
680 KiAcquireApcLockAtSynchLevel(Current, &ApcLock);
681
682 /* Make sure we are frozen */
683 OldCount = Current->FreezeCount;
684 if (OldCount)
685 {
686 /* Decrease the freeze count */
687 Current->FreezeCount--;
688
689 /* Check if both counts are zero now */
690 if (!(Current->SuspendCount) && (!Current->FreezeCount))
691 {
692 /* Lock the dispatcher */
694
695 /* Signal the suspend semaphore and wake it */
696 Current->SuspendSemaphore.Header.SignalState++;
697 KiWaitTest(&Current->SuspendSemaphore, 0);
698
699 /* Unlock the dispatcher */
701 }
702 }
703
704 /* Release the APC lock */
706
707 /* Go to the next one */
708 NextEntry = NextEntry->Flink;
709 } while (NextEntry != ListHead);
710
711 /* Release the process lock and exit the dispatcher */
714
715 /* Leave the critical region */
717}
718
720NTAPI
722{
724 BOOLEAN OldState;
725 KLOCK_QUEUE_HANDLE ApcLock;
728
729 /* Lock the Dispatcher Database and the APC Queue */
731
732 /* Save the old State */
733 OldState = Thread->Alerted[AlertMode];
734
735 /* Check the Thread is alerted */
736 if (OldState)
737 {
738 /* Disable alert for this mode */
739 Thread->Alerted[AlertMode] = FALSE;
740 }
741 else if ((AlertMode != KernelMode) &&
742 (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
743 {
744 /* If the mode is User and the Queue isn't empty, set Pending */
745 Thread->ApcState.UserApcPending = TRUE;
746 }
747
748 /* Release Locks and return the Old State */
749 KiReleaseApcLock(&ApcLock);
750 return OldState;
751}
752
754NTAPI
756 IN PVOID KernelStack,
757 IN PKSYSTEM_ROUTINE SystemRoutine,
759 IN PVOID StartContext,
761 IN PVOID Teb,
763{
764 BOOLEAN AllocatedStack = FALSE;
765 ULONG i;
766 PKWAIT_BLOCK TimerWaitBlock;
769
770 /* Initialize the Dispatcher Header */
771 Thread->Header.Type = ThreadObject;
772 Thread->Header.ThreadControlFlags = 0;
773 Thread->Header.DebugActive = FALSE;
774 Thread->Header.SignalState = 0;
775 InitializeListHead(&(Thread->Header.WaitListHead));
776
777 /* Initialize the Mutant List */
778 InitializeListHead(&Thread->MutantListHead);
779
780 /* Initialize the wait blocks */
781 for (i = 0; i< (THREAD_WAIT_OBJECTS + 1); i++)
782 {
783 /* Put our pointer */
784 Thread->WaitBlock[i].Thread = Thread;
785 }
786
787 /* Set swap settings */
788 Thread->EnableStackSwap = TRUE;
789 Thread->IdealProcessor = 1;
790 Thread->SwapBusy = FALSE;
791 Thread->KernelStackResident = TRUE;
792 Thread->AdjustReason = AdjustNone;
793
794 /* Initialize the lock */
796
797 /* Setup the Service Descriptor Table for Native Calls */
798 Thread->ServiceTable = KeServiceDescriptorTable;
799
800 /* Setup APC Fields */
801 InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
802 InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
803 Thread->ApcState.Process = Process;
804 Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
805 Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
806 Thread->ApcStateIndex = OriginalApcEnvironment;
807 Thread->ApcQueueable = TRUE;
808 KeInitializeSpinLock(&Thread->ApcQueueLock);
809
810 /* Initialize the Suspend APC */
811 KeInitializeApc(&Thread->SuspendApc,
812 Thread,
818 NULL);
819
820 /* Initialize the Suspend Semaphore */
821 KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
822
823 /* Setup the timer */
824 Timer = &Thread->Timer;
826 TimerWaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK];
827 TimerWaitBlock->Object = Timer;
828 TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
829 TimerWaitBlock->WaitType = WaitAny;
830 TimerWaitBlock->NextWaitBlock = NULL;
831
832 /* Link the two wait lists together */
833 TimerWaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead;
834 TimerWaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead;
835
836 /* Set the TEB and process */
837 Thread->Teb = Teb;
838 Thread->Process = Process;
839
840 /* Check if we have a kernel stack */
841 if (!KernelStack)
842 {
843 /* We don't, allocate one */
844 KernelStack = MmCreateKernelStack(FALSE, 0);
845 if (!KernelStack) return STATUS_INSUFFICIENT_RESOURCES;
846
847 /* Remember for later */
848 AllocatedStack = TRUE;
849 }
850
851 /* Set the Thread Stacks */
852 Thread->InitialStack = KernelStack;
853 Thread->StackBase = KernelStack;
854 Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE;
855 Thread->KernelStackResident = TRUE;
856
857 /* Enter SEH to avoid crashes due to user mode */
860 {
861 /* Initialize the Thread Context */
863 SystemRoutine,
865 StartContext,
866 Context);
867 }
869 {
870 /* Set failure status */
872
873 /* Check if a stack was allocated */
874 if (AllocatedStack)
875 {
876 /* Delete the stack */
878 Thread->InitialStack = NULL;
879 }
880 }
881 _SEH2_END;
882
883 /* Set the Thread to initialized */
884 Thread->State = Initialized;
885 return Status;
886}
887
888VOID
889NTAPI
892 IN PKSYSTEM_ROUTINE SystemRoutine,
894 IN PVOID StartContext,
896 IN PVOID Teb,
897 IN PVOID KernelStack)
898{
899 /* Initialize and start the thread on success */
901 KernelStack,
902 SystemRoutine,
904 StartContext,
905 Context,
906 Teb,
907 Process)))
908 {
909 /* Start it */
911 }
912}
913
914VOID
915NTAPI
917{
918 /* Delete the stack */
920 Thread->InitialStack = NULL;
921}
922
923/* PUBLIC FUNCTIONS **********************************************************/
924
925/*
926 * @unimplemented
927 */
928VOID
929NTAPI
931 IN ULONG Setting1,
932 IN ULONG Setting2,
933 IN ULONG Setting3,
934 IN ULONG Setting4,
935 IN ULONG Setting5,
936 IN PVOID ThreadState)
937{
939}
940
941/*
942 * @implemented
943 */
944#undef KeGetCurrentThread
946NTAPI
948{
949 /* Return the current thread on this PCR */
950 return _KeGetCurrentThread();
951}
952
953/*
954 * @implemented
955 */
956#undef KeGetPreviousMode
957UCHAR
958NTAPI
960{
961 /* Return the previous mode of this thread */
962 return _KeGetPreviousMode();
963}
964
965/*
966 * @implemented
967 */
968ULONG
969NTAPI
972{
974
975 /* Return the User Time */
976 *UserTime = Thread->UserTime;
977
978 /* Return the Kernel Time */
979 return Thread->KernelTime;
980}
981
982/*
983 * @implemented
984 */
986NTAPI
988{
991
992 /* Save Old State */
993 PreviousState = Thread->EnableStackSwap;
994
995 /* Set New State */
996 Thread->EnableStackSwap = Enable;
997
998 /* Return Old State */
999 return PreviousState;
1000}
1001
1002/*
1003 * @implemented
1004 */
1006NTAPI
1008{
1010
1011 /* Return the current priority */
1012 return Thread->Priority;
1013}
1014
1015/*
1016 * @implemented
1017 */
1018VOID
1019NTAPI
1021{
1022 KIRQL OldIrql;
1023 PKPRCB Prcb;
1024 PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1026 ASSERT(CurrentThread->SystemAffinityActive != FALSE);
1027
1028 /* Lock the Dispatcher Database */
1030
1031 /* Set the user affinity and processor and disable system affinity */
1032 CurrentThread->Affinity = CurrentThread->UserAffinity;
1033 CurrentThread->IdealProcessor = CurrentThread->UserIdealProcessor;
1034 CurrentThread->SystemAffinityActive = FALSE;
1035
1036 /* Get the current PRCB and check if it doesn't match this affinity */
1037 Prcb = KeGetCurrentPrcb();
1038 if (!(Prcb->SetMember & CurrentThread->Affinity))
1039 {
1040 /* Lock the PRCB */
1041 KiAcquirePrcbLock(Prcb);
1042
1043 /* Check if there's no next thread scheduled */
1044 if (!Prcb->NextThread)
1045 {
1046 /* Select a new thread and set it on standby */
1047 NextThread = KiSelectNextThread(Prcb);
1048 NextThread->State = Standby;
1049 Prcb->NextThread = NextThread;
1050 }
1051
1052 /* Release the PRCB lock */
1053 KiReleasePrcbLock(Prcb);
1054 }
1055
1056 /* Unlock dispatcher database */
1058}
1059
1060/*
1061 * @implemented
1062 */
1063UCHAR
1064NTAPI
1067{
1068 CCHAR OldIdealProcessor;
1069 KIRQL OldIrql;
1071
1072 /* Lock the Dispatcher Database */
1074
1075 /* Save Old Ideal Processor */
1076 OldIdealProcessor = Thread->UserIdealProcessor;
1077
1078 /* Make sure a valid CPU was given */
1080 {
1081 /* Check if the user ideal CPU is in the affinity */
1082 if (Thread->Affinity & AFFINITY_MASK(Processor))
1083 {
1084 /* Set the ideal processor */
1085 Thread->IdealProcessor = Processor;
1086
1087 /* Check if system affinity is used */
1088 if (!Thread->SystemAffinityActive)
1089 {
1090 /* It's not, so update the user CPU too */
1091 Thread->UserIdealProcessor = Processor;
1092 }
1093 }
1094 }
1095
1096 /* Release dispatcher lock and return the old ideal CPU */
1098 return OldIdealProcessor;
1099}
1100
1101/*
1102 * @implemented
1103 */
1104VOID
1105NTAPI
1107{
1108 KIRQL OldIrql;
1109 PKPRCB Prcb;
1110 PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1113
1114 /* Lock the Dispatcher Database */
1116
1117 /* Restore the affinity and enable system affinity */
1118 CurrentThread->Affinity = Affinity;
1119 CurrentThread->SystemAffinityActive = TRUE;
1120
1121 /* Check if the ideal processor is part of the affinity */
1122#ifdef CONFIG_SMP
1123 if (!(Affinity & AFFINITY_MASK(CurrentThread->IdealProcessor)))
1124 {
1125 ULONG AffinitySet, NodeMask;
1126
1127 /* It's not! Get the PRCB */
1128 Prcb = KiProcessorBlock[CurrentThread->IdealProcessor];
1129
1130 /* Calculate the affinity set */
1131 AffinitySet = KeActiveProcessors & Affinity;
1132 NodeMask = Prcb->ParentNode->ProcessorMask & AffinitySet;
1133 if (NodeMask)
1134 {
1135 /* Use the Node set instead */
1136 AffinitySet = NodeMask;
1137 }
1138
1139 /* Calculate the ideal CPU from the affinity set */
1140 BitScanReverse(&NodeMask, AffinitySet);
1141 CurrentThread->IdealProcessor = (UCHAR)NodeMask;
1142 }
1143#endif
1144
1145 /* Get the current PRCB and check if it doesn't match this affinity */
1146 Prcb = KeGetCurrentPrcb();
1147 if (!(Prcb->SetMember & CurrentThread->Affinity))
1148 {
1149 /* Lock the PRCB */
1150 KiAcquirePrcbLock(Prcb);
1151
1152 /* Check if there's no next thread scheduled */
1153 if (!Prcb->NextThread)
1154 {
1155 /* Select a new thread and set it on standby */
1156 NextThread = KiSelectNextThread(Prcb);
1157 NextThread->State = Standby;
1158 Prcb->NextThread = NextThread;
1159 }
1160
1161 /* Release the PRCB lock */
1162 KiReleasePrcbLock(Prcb);
1163 }
1164
1165 /* Unlock dispatcher database */
1167}
1168
1169/*
1170 * @implemented
1171 */
1172LONG
1173NTAPI
1176{
1177 KIRQL OldIrql;
1178 KPRIORITY OldBasePriority, Priority, BasePriority;
1179 LONG OldIncrement;
1183
1184 /* Get the process */
1185 Process = Thread->ApcState.Process;
1186
1187 /* Lock the Dispatcher Database */
1189
1190 /* Lock the thread */
1192
1193 /* Save the old base priority and increment */
1194 OldBasePriority = Thread->BasePriority;
1195 OldIncrement = OldBasePriority - Process->BasePriority;
1196
1197 /* If priority saturation happened, use the saturated increment */
1198 if (Thread->Saturation) OldIncrement = (HIGH_PRIORITY + 1) / 2 *
1199 Thread->Saturation;
1200
1201 /* Reset the saturation value */
1202 Thread->Saturation = 0;
1203
1204 /* Now check if saturation is being used for the new value */
1205 if (abs(Increment) >= ((HIGH_PRIORITY + 1) / 2))
1206 {
1207 /* Check if we need positive or negative saturation */
1208 Thread->Saturation = (Increment > 0) ? 1 : -1;
1209 }
1210
1211 /* Normalize the Base Priority */
1212 BasePriority = Process->BasePriority + Increment;
1213 if (Process->BasePriority >= LOW_REALTIME_PRIORITY)
1214 {
1215 /* Check if it's too low */
1216 if (BasePriority < LOW_REALTIME_PRIORITY)
1217 {
1218 /* Set it to the lowest real time level */
1219 BasePriority = LOW_REALTIME_PRIORITY;
1220 }
1221
1222 /* Check if it's too high */
1223 if (BasePriority > HIGH_PRIORITY) BasePriority = HIGH_PRIORITY;
1224
1225 /* We are at real time, so use the raw base priority */
1226 Priority = BasePriority;
1227 }
1228 else
1229 {
1230 /* Check if it's entering the real time range */
1231 if (BasePriority >= LOW_REALTIME_PRIORITY)
1232 {
1233 /* Set it to the highest dynamic level */
1234 BasePriority = LOW_REALTIME_PRIORITY - 1;
1235 }
1236
1237 /* Check if it's too low and normalize it */
1238 if (BasePriority <= LOW_PRIORITY) BasePriority = 1;
1239
1240 /* Check if Saturation is used */
1241 if (Thread->Saturation)
1242 {
1243 /* Use the raw base priority */
1244 Priority = BasePriority;
1245 }
1246 else
1247 {
1248 /* Otherwise, calculate the new priority */
1250 Priority += (BasePriority - OldBasePriority);
1251
1252 /* Check if it entered the real-time range */
1254 {
1255 /* Normalize it down to the highest dynamic priority */
1257 }
1258 else if (Priority <= LOW_PRIORITY)
1259 {
1260 /* It went too low, normalize it */
1261 Priority = 1;
1262 }
1263 }
1264 }
1265
1266 /* Finally set the new base priority */
1267 Thread->BasePriority = (SCHAR)BasePriority;
1268
1269 /* Reset the decrements */
1270 Thread->PriorityDecrement = 0;
1271
1272 /* Check if we're changing priority after all */
1273 if (Priority != Thread->Priority)
1274 {
1275 /* Reset the quantum and do the actual priority modification */
1276 Thread->Quantum = Thread->QuantumReset;
1278 }
1279
1280 /* Release thread lock */
1282
1283 /* Release the dispatcher database and return old increment */
1285 return OldIncrement;
1286}
1287
1288/*
1289 * @implemented
1290 */
1292NTAPI
1295{
1296 KIRQL OldIrql;
1297 KAFFINITY OldAffinity;
1300
1301 /* Lock the dispatcher database */
1303
1304 /* Call the internal function */
1305 OldAffinity = KiSetAffinityThread(Thread, Affinity);
1306
1307 /* Release the dispatcher database and return old affinity */
1309 return OldAffinity;
1310}
1311
1312/*
1313 * @implemented
1314 */
1316NTAPI
1319{
1320 KIRQL OldIrql;
1321 KPRIORITY OldPriority;
1326
1327 /* Lock the Dispatcher Database */
1329
1330 /* Lock the thread */
1332
1333 /* Save the old Priority and reset decrement */
1334 OldPriority = Thread->Priority;
1335 Thread->PriorityDecrement = 0;
1336
1337 /* Make sure that an actual change is being done */
1338 if (Priority != Thread->Priority)
1339 {
1340 /* Reset the quantum */
1341 Thread->Quantum = Thread->QuantumReset;
1342
1343 /* Check if priority is being set too low and normalize if so */
1344 if ((Thread->BasePriority != 0) && !(Priority)) Priority = 1;
1345
1346 /* Set the new Priority */
1348 }
1349
1350 /* Release thread lock */
1352
1353 /* Release the dispatcher database */
1355
1356 /* Return Old Priority */
1357 return OldPriority;
1358}
1359
1360/*
1361 * @implemented
1362 */
1363VOID
1364NTAPI
1366{
1367 PLIST_ENTRY *ListHead;
1368 PETHREAD Entry, SavedEntry;
1369 PETHREAD *ThreadAddr;
1372 PKPROCESS Process = Thread->ApcState.Process;
1374
1375 /* Lock the process */
1377
1378 /* Make sure we won't get Swapped */
1380
1381 /* Save the Kernel and User Times */
1382 Process->KernelTime += Thread->KernelTime;
1383 Process->UserTime += Thread->UserTime;
1384
1385 /* Get the current entry and our Port */
1387 ThreadAddr = &((PETHREAD)Thread)->ReaperLink;
1388
1389 /* Add it to the reaper's list */
1390 do
1391 {
1392 /* Get the list head */
1393 ListHead = &PspReaperListHead.Flink;
1394
1395 /* Link ourselves */
1396 *ThreadAddr = Entry;
1397 SavedEntry = Entry;
1398
1399 /* Now try to do the exchange */
1401 ThreadAddr,
1402 Entry);
1403
1404 /* Break out if the change was succesful */
1405 } while (Entry != SavedEntry);
1406
1407 /* Acquire the dispatcher lock */
1409
1410 /* Check if the reaper wasn't active */
1411 if (!Entry)
1412 {
1413 /* Activate it as a work item, directly through its Queue */
1416 FALSE);
1417 }
1418
1419 /* Check the thread has an associated queue */
1420 if (Thread->Queue)
1421 {
1422 /* Remove it from the list, and handle the queue */
1423 RemoveEntryList(&Thread->QueueListEntry);
1425 }
1426
1427 /* Signal the thread */
1428 Thread->Header.SignalState = TRUE;
1429 if (!IsListEmpty(&Thread->Header.WaitListHead))
1430 {
1431 /* Unwait the threads */
1432 KxUnwaitThread(&Thread->Header, Increment);
1433 }
1434
1435 /* Remove the thread from the list */
1437
1438 /* Release the process lock */
1440
1441 /* Set us as terminated, decrease the Process's stack count */
1442 Thread->State = Terminated;
1443
1444 /* Decrease stack count */
1445 ASSERT(Process->StackCount != 0);
1446 ASSERT(Process->State == ProcessInMemory);
1447 Process->StackCount--;
1448 if (!(Process->StackCount) && !(IsListEmpty(&Process->ThreadListHead)))
1449 {
1450 /* FIXME: Swap stacks */
1451 }
1452
1453 /* Rundown arch-specific parts */
1455
1456 /* Swap to a new thread */
1459}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define MAXULONG_PTR
Definition: basetsd.h:103
#define UNIMPLEMENTED
Definition: debug.h:115
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
union node Node
Definition: types.h:1255
ULONG_PTR KAFFINITY
Definition: compat.h:85
LONG KPRIORITY
Definition: compat.h:803
BOOLEAN NTAPI KeIsExecutingDpc(VOID)
Definition: dpc.c:947
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define abs(i)
Definition: fconv.c:206
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:46
#define MAXIMUM_PROCESSORS
Definition: rwlock.h:5
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
unsigned int Mask
Definition: fpcontrol.c:82
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
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
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: pic.c:156
#define KeGetCurrentThread
Definition: hal.h:55
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define LOW_PRIORITY
#define LOW_REALTIME_PRIORITY
#define HIGH_PRIORITY
#define BitScanReverse
Definition: interlocked.h:6
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define InterlockedBitTestAndSet
Definition: interlocked.h:30
#define InterlockedBitTestAndReset
Definition: interlocked.h:35
FORCEINLINE VOID KiAcquireApcLockRaiseToSynch(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:607
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:157
FORCEINLINE VOID KiSetThreadSwapBusy(IN PKTHREAD Thread)
Definition: ke_x.h:210
FORCEINLINE VOID KiReleaseProcessLockFromSynchLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:668
FORCEINLINE VOID KiReleasePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:230
FORCEINLINE VOID KiAcquireThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:240
FORCEINLINE VOID KxUnwaitThread(IN DISPATCHER_HEADER *Object, IN KPRIORITY Increment)
Definition: ke_x.h:1259
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
FORCEINLINE VOID KiReleaseDispatcherLockFromSynchLevel(VOID)
Definition: ke_x.h:174
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
FORCEINLINE VOID KiReleaseProcessLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:660
FORCEINLINE VOID KiReleaseThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:250
FORCEINLINE VOID KiAcquireDispatcherLockAtSynchLevel(VOID)
Definition: ke_x.h:165
FORCEINLINE VOID KiAcquireApcLockAtSynchLevel(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:616
FORCEINLINE VOID KiReleaseApcLockFromSynchLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:643
FORCEINLINE VOID KiAcquirePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:220
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:149
FORCEINLINE VOID KiAcquireProcessLockRaiseToSynch(IN PKPROCESS Process, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:651
FORCEINLINE SCHAR KiComputeNewPriority(IN PKTHREAD Thread, IN SCHAR Adjustment)
Definition: ke_x.h:1469
FORCEINLINE VOID KiReleaseApcLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:635
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1148
#define _KeGetPreviousMode()
Definition: ketypes.h:1112
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define _KeGetCurrentThread()
Definition: ketypes.h:1111
#define MUTANT_INCREMENT
Definition: extypes.h:84
VOID(NTAPI * PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
Definition: ketypes.h:644
@ ProcessInMemory
Definition: ketypes.h:460
@ ThreadObject
Definition: ketypes.h:412
@ Terminated
Definition: ketypes.h:392
@ Standby
Definition: ketypes.h:391
@ Waiting
Definition: ketypes.h:393
@ Initialized
Definition: ketypes.h:388
@ AttachedApcEnvironment
Definition: ketypes.h:675
@ OriginalApcEnvironment
Definition: ketypes.h:674
#define THREAD_ALERT_INCREMENT
Definition: ketypes.h:126
#define ASSERT_THREAD(object)
Definition: ketypes.h:1983
@ AdjustNone
Definition: ketypes.h:439
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:651
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
struct _ETHREAD * PETHREAD
Definition: nt_native.h:29
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
@ WaitAny
FORCEINLINE VOID KiRundownThread(IN PKTHREAD Thread)
Definition: ke.h:293
VOID NTAPI KiReadyThread(IN PKTHREAD Thread)
Definition: thrdschd.c:429
PKPRCB KiProcessorBlock[]
Definition: krnlinit.c:32
#define AFFINITY_MASK(ProcessorIndex)
Definition: ke.h:158
LONG_PTR FASTCALL KiSwapThread(IN PKTHREAD Thread, IN PKPRCB Prcb)
Definition: thrdschd.c:355
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
KAFFINITY FASTCALL KiSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdschd.c:685
PKNODE KeNodeBlock[1]
Definition: krnlinit.c:39
VOID FASTCALL KiUnwaitThread(IN PKTHREAD Thread, IN LONG_PTR WaitStatus, IN KPRIORITY Increment)
Definition: wait.c:89
VOID NTAPI KiInitializeContextThread(PKTHREAD Thread, PKSYSTEM_ROUTINE SystemRoutine, PKSTART_ROUTINE StartRoutine, PVOID StartContext, PCONTEXT Context)
#define TIMER_WAIT_BLOCK
Definition: ke.h:165
PKTHREAD FASTCALL KiSelectNextThread(IN PKPRCB Prcb)
Definition: thrdschd.c:328
VOID FASTCALL KiActivateWaiterQueue(IN PKQUEUE Queue)
Definition: queue.c:24
VOID FASTCALL KiInsertQueueApc(IN PKAPC Apc, IN KPRIORITY PriorityBoost)
Definition: apc.c:85
VOID FASTCALL KiSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdschd.c:511
LONG NTAPI KiInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry, BOOLEAN Head)
VOID FASTCALL KiWaitTest(PVOID Object, KPRIORITY Increment)
VOID FASTCALL KiExitDispatcher(KIRQL OldIrql)
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
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:207
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_ALERTED
Definition: ntstatus.h:80
#define STATUS_SUSPEND_COUNT_EXCEEDED
Definition: ntstatus.h:310
static BOOL Set
Definition: pageheap.c:10
long LONG
Definition: pedump.c:60
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[SSDT_MAX_ENTRIES]
Definition: procobj.c:23
WORK_QUEUE_ITEM PspReaperWorkItem
Definition: kill.c:20
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
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
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
#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
signed char SCHAR
Definition: sqltypes.h:14
base of all file and directory entries
Definition: entries.h:83
LIST_ENTRY WaitListHead
Definition: ketypes.h:808
EX_PUSH_LOCK ThreadLock
Definition: pstypes.h:1160
LIST_ENTRY ThreadListEntry
Definition: pstypes.h:1158
Definition: ketypes.h:547
DISPATCHER_HEADER Header
Definition: ketypes.h:841
LIST_ENTRY MutantListEntry
Definition: ketypes.h:842
BOOLEAN Abandoned
Definition: ketypes.h:844
struct _KTHREAD *RESTRICTED_POINTER OwnerThread
Definition: ketypes.h:843
UCHAR ApcDisable
Definition: ketypes.h:845
UINT64 SetMember
Definition: ketypes.h:648
struct _KTHREAD * NextThread
Definition: ketypes.h:637
struct _KNODE * ParentNode
Definition: ketypes.h:821
ULONG UserIdealProcessor
Definition: ketypes.h:1690
GROUP_AFFINITY Affinity
Definition: ketypes.h:1845
ULONG IdealProcessor
Definition: ketypes.h:1851
ULONG FreezeCount
Definition: ketypes.h:1644
ULONG SystemAffinityActive
Definition: ketypes.h:1604
GROUP_AFFINITY UserAffinity
Definition: ketypes.h:1819
DISPATCHER_HEADER Header
Definition: ketypes.h:1568
CHAR SuspendCount
Definition: ketypes.h:1872
KAPC_STATE ApcState
Definition: ketypes.h:1685
ULONG ApcQueueable
Definition: ketypes.h:1618
volatile UCHAR State
Definition: ketypes.h:1696
PVOID Object
Definition: ketypes.h:468
LIST_ENTRY WaitListEntry
Definition: ketypes.h:456
UCHAR WaitType
Definition: ketypes.h:458
USHORT WaitKey
Definition: ketypes.h:460
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY List
Definition: extypes.h:203
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:755
KPRIORITY NTAPI KeQueryPriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:1007
LIST_ENTRY PspReaperListHead
Definition: kill.c:19
VOID NTAPI KiSuspendNop(IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
Definition: thrdobj.c:570
KPRIORITY NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:51
ULONG NTAPI KeForceResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:266
VOID NTAPI KeFreezeAllThreads(VOID)
Definition: thrdobj.c:305
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1106
VOID NTAPI KeUninitThread(IN PKTHREAD Thread)
Definition: thrdobj.c:916
VOID NTAPI KeThawAllThreads(VOID)
Definition: thrdobj.c:659
UCHAR NTAPI KeFindNextRightSetAffinity(IN UCHAR Number, IN ULONG Set)
Definition: thrdobj.c:22
ULONG NTAPI KeSuspendThread(PKTHREAD Thread)
Definition: thrdobj.c:600
UCHAR NTAPI KeSetIdealProcessorThread(IN PKTHREAD Thread, IN UCHAR Processor)
Definition: thrdobj.c:1065
ULONG NTAPI KeResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:387
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:890
VOID NTAPI KeTerminateThread(IN KPRIORITY Increment)
Definition: thrdobj.c:1365
LONG NTAPI KeSetBasePriorityThread(IN PKTHREAD Thread, IN LONG Increment)
Definition: thrdobj.c:1174
BOOLEAN NTAPI KeSetKernelStackSwapEnable(IN BOOLEAN Enable)
Definition: thrdobj.c:987
BOOLEAN NTAPI KeSetDisableBoostThread(IN OUT PKTHREAD Thread, IN BOOLEAN Disable)
Definition: thrdobj.c:85
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1020
BOOLEAN NTAPI KeAlertThread(IN PKTHREAD Thread, IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:175
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1317
KAFFINITY NTAPI KeSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdobj.c:1293
VOID NTAPI KiSuspendRundown(IN PKAPC Apc)
Definition: thrdobj.c:562
BOOLEAN NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:721
ULONG NTAPI KeQueryRuntimeThread(IN PKTHREAD Thread, OUT PULONG UserTime)
Definition: thrdobj.c:970
VOID NTAPI KeRundownThread(VOID)
Definition: thrdobj.c:429
VOID NTAPI KeStartThread(IN OUT PKTHREAD Thread)
Definition: thrdobj.c:488
VOID NTAPI KeReadyThread(IN PKTHREAD Thread)
Definition: thrdobj.c:105
ULONG NTAPI KeAlertResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:123
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:930
BOOLEAN NTAPI KeReadStateThread(IN PKTHREAD Thread)
Definition: thrdobj.c:41
VOID NTAPI KeBoostPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Increment)
Definition: thrdobj.c:219
EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue]
Definition: work.c:31
VOID NTAPI KiSuspendThread(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: thrdobj.c:586
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char CCHAR
Definition: typedefs.h:51
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Definition: dlist.c:348
_In_ WDF_POWER_DEVICE_STATE PreviousState
Definition: wdfdevice.h:829
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
#define MAXIMUM_SUSPEND_COUNT
Definition: winbase.h:405
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
@ HyperCriticalWorkQueue
Definition: extypes.h:191
@ MaximumWorkQueue
Definition: extypes.h:192
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174
#define IO_NO_INCREMENT
Definition: iotypes.h:598
_Out_ PULONG UserTime
Definition: kefuncs.h:773
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
*LockHandle LockHandle _Out_ PKLOCK_QUEUE_HANDLE LockHandle
Definition: kefuncs.h:731
_In_ UCHAR Processor
Definition: kefuncs.h:684
KSTART_ROUTINE * PKSTART_ROUTINE
Definition: ketypes.h:499
@ Suspended
Definition: ketypes.h:420
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
#define THREAD_WAIT_OBJECTS
Definition: ketypes.h:492
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689
#define ASSERT_MUTANT(Object)
_In_ ULONG _In_opt_ POBJECT_ATTRIBUTES _In_opt_ HANDLE _Out_opt_ PCLIENT_ID _In_ PKSTART_ROUTINE StartRoutine
Definition: psfuncs.h:91
unsigned char UCHAR
Definition: xmlstorage.h:181