ReactOS 0.4.15-dev-7934-g1dc8d80
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
24{
25 KAFFINITY Bit;
27 ASSERT(Set != 0);
28
29 /* Calculate the mask */
30 Bit = (AFFINITY_MASK(Number) - 1) & Set;
31
32 /* If it's 0, use the one we got */
33 if (!Bit) Bit = Set;
34
35 /* Now find the right set and return it */
37 return (UCHAR)Result;
38}
39
43{
45
46 /* Return signal state */
47 return (BOOLEAN)Thread->Header.SignalState;
48}
49
53{
54 LONG BaseIncrement;
59
60 /* Raise IRQL to synch level */
62
63 /* Lock the thread */
65
66 /* Get the Process */
67 Process = Thread->ApcStatePointer[0]->Process;
68
69 /* Calculate the base increment */
70 BaseIncrement = Thread->BasePriority - Process->BasePriority;
71
72 /* If saturation occured, return the saturation increment instead */
73 if (Thread->Saturation) BaseIncrement = (HIGH_PRIORITY + 1) / 2 *
74 Thread->Saturation;
75
76 /* Release thread lock */
78
79 /* Lower IRQl and return Increment */
81 return BaseIncrement;
82}
83
87 IN BOOLEAN Disable)
88{
90
91 /* Check if we're enabling or disabling */
92 if (Disable)
93 {
94 /* Set the bit */
95 return InterlockedBitTestAndSet(&Thread->ThreadFlags, 1);
96 }
97 else
98 {
99 /* Remove the bit */
100 return InterlockedBitTestAndReset(&Thread->ThreadFlags, 1);
101 }
102}
103
104VOID
105NTAPI
107{
111
112 /* Lock the Dispatcher Database */
114
115 /* Make the thread ready */
117
118 /* Unlock dispatcher database */
120}
121
122ULONG
123NTAPI
125{
126 ULONG PreviousCount;
127 KLOCK_QUEUE_HANDLE ApcLock;
130
131 /* Lock the Dispatcher Database and the APC Queue */
134
135 /* Return if Thread is already alerted. */
136 if (!Thread->Alerted[KernelMode])
137 {
138 /* If it's Blocked, unblock if it we should */
139 if ((Thread->State == Waiting) && (Thread->Alertable))
140 {
141 /* Abort the wait */
143 }
144 else
145 {
146 /* If not, simply Alert it */
147 Thread->Alerted[KernelMode] = TRUE;
148 }
149 }
150
151 /* Save the old Suspend Count */
152 PreviousCount = Thread->SuspendCount;
153
154 /* If the thread is suspended, decrease one of the suspend counts */
155 if (PreviousCount)
156 {
157 /* Decrease count. If we are now zero, unwait it completely */
158 Thread->SuspendCount--;
159 if (!(Thread->SuspendCount) && !(Thread->FreezeCount))
160 {
161 /* Signal and satisfy */
162 Thread->SuspendSemaphore.Header.SignalState++;
163 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
164 }
165 }
166
167 /* Release Locks and return the Old State */
170 KiExitDispatcher(ApcLock.OldIrql);
171 return PreviousCount;
172}
173
175NTAPI
177 IN KPROCESSOR_MODE AlertMode)
178{
180 KLOCK_QUEUE_HANDLE ApcLock;
183
184 /* Lock the Dispatcher Database and the APC Queue */
187
188 /* Save the Previous State */
189 PreviousState = Thread->Alerted[AlertMode];
190
191 /* Check if it's already alerted */
192 if (!PreviousState)
193 {
194 /* Check if the thread is alertable, and blocked in the given mode */
195 if ((Thread->State == Waiting) &&
196 (Thread->Alertable) &&
197 (AlertMode <= Thread->WaitMode))
198 {
199 /* Abort the wait to alert the thread */
201 }
202 else
203 {
204 /* Otherwise, merely set the alerted state */
205 Thread->Alerted[AlertMode] = TRUE;
206 }
207 }
208
209 /* Release the Dispatcher Lock */
212 KiExitDispatcher(ApcLock.OldIrql);
213
214 /* Return the old state */
215 return PreviousState;
216}
217
218VOID
219NTAPI
222{
226
227 /* Lock the Dispatcher Database */
229
230 /* Only threads in the dynamic range get boosts */
231 if (Thread->Priority < LOW_REALTIME_PRIORITY)
232 {
233 /* Lock the thread */
235
236 /* Check again, and make sure there's not already a boost */
237 if ((Thread->Priority < LOW_REALTIME_PRIORITY) &&
238 !(Thread->PriorityDecrement))
239 {
240 /* Compute the new priority and see if it's higher */
241 Priority = Thread->BasePriority + Increment;
242 if (Priority > Thread->Priority)
243 {
245 {
247 }
248
249 /* Reset the quantum */
250 Thread->Quantum = Thread->QuantumReset;
251
252 /* Set the new Priority */
254 }
255 }
256
257 /* Release thread lock */
259 }
260
261 /* Release the dispatcher lokc */
263}
264
265ULONG
266NTAPI
268{
269 KLOCK_QUEUE_HANDLE ApcLock;
270 ULONG PreviousCount;
273
274 /* Lock the APC Queue */
276
277 /* Save the old Suspend Count */
278 PreviousCount = Thread->SuspendCount + Thread->FreezeCount;
279
280 /* If the thread is suspended, wake it up!!! */
281 if (PreviousCount)
282 {
283 /* Unwait it completely */
284 Thread->SuspendCount = 0;
285 Thread->FreezeCount = 0;
286
287 /* Lock the dispatcher */
289
290 /* Signal and satisfy */
291 Thread->SuspendSemaphore.Header.SignalState++;
292 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
293
294 /* Release the dispatcher */
296 }
297
298 /* Release Lock and return the Old State */
300 KiExitDispatcher(ApcLock.OldIrql);
301 return PreviousCount;
302}
303
304VOID
305NTAPI
307{
309 PKTHREAD Current, CurrentThread = KeGetCurrentThread();
310 PKPROCESS Process = CurrentThread->ApcState.Process;
311 PLIST_ENTRY ListHead, NextEntry;
312 LONG OldCount;
314
315 /* Lock the process */
317
318 /* If someone is already trying to free us, try again */
319 while (CurrentThread->FreezeCount)
320 {
321 /* Release and re-acquire the process lock so the APC will go through */
324 }
325
326 /* Enter a critical region */
328
329 /* Loop the Process's Threads */
330 ListHead = &Process->ThreadListHead;
331 NextEntry = ListHead->Flink;
332 do
333 {
334 /* Get the current thread */
335 Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
336
337 /* Lock it */
338 KiAcquireApcLockAtSynchLevel(Current, &ApcLock);
339
340 /* Make sure it's not ours, and check if APCs are enabled */
341 if ((Current != CurrentThread) && (Current->ApcQueueable))
342 {
343 /* Sanity check */
344 OldCount = Current->SuspendCount;
345 ASSERT(OldCount != MAXIMUM_SUSPEND_COUNT);
346
347 /* Increase the freeze count */
348 Current->FreezeCount++;
349
350 /* Make sure it wasn't already suspended */
351 if (!(OldCount) && !(Current->SuspendCount))
352 {
353 /* Did we already insert it? */
354 if (!Current->SuspendApc.Inserted)
355 {
356 /* Insert the APC */
357 Current->SuspendApc.Inserted = TRUE;
358 KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT);
359 }
360 else
361 {
362 /* Lock the dispatcher */
364
365 /* Unsignal the semaphore, the APC was already inserted */
366 Current->SuspendSemaphore.Header.SignalState--;
367
368 /* Release the dispatcher */
370 }
371 }
372 }
373
374 /* Release the APC lock */
376
377 /* Move to the next thread */
378 NextEntry = NextEntry->Flink;
379 } while (NextEntry != ListHead);
380
381 /* Release the process lock and exit the dispatcher */
384}
385
386ULONG
387NTAPI
389{
390 KLOCK_QUEUE_HANDLE ApcLock;
391 ULONG PreviousCount;
394
395 /* Lock the APC Queue */
397
398 /* Save the Old Count */
399 PreviousCount = Thread->SuspendCount;
400
401 /* Check if it existed */
402 if (PreviousCount)
403 {
404 /* Decrease the suspend count */
405 Thread->SuspendCount--;
406
407 /* Check if the thrad is still suspended or not */
408 if ((!Thread->SuspendCount) && (!Thread->FreezeCount))
409 {
410 /* Acquire the dispatcher lock */
412
413 /* Signal the Suspend Semaphore */
414 Thread->SuspendSemaphore.Header.SignalState++;
415 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
416
417 /* Release the dispatcher lock */
419 }
420 }
421
422 /* Release APC Queue lock and return the Old State */
424 KiExitDispatcher(ApcLock.OldIrql);
425 return PreviousCount;
426}
427
428VOID
429NTAPI
431{
434 PLIST_ENTRY NextEntry, ListHead;
435 PKMUTANT Mutant;
437
438 /* Optimized path if nothing is on the list at the moment */
439 if (IsListEmpty(&Thread->MutantListHead)) return;
440
441 /* Lock the Dispatcher Database */
443
444 /* Get the List Pointers */
445 ListHead = &Thread->MutantListHead;
446 NextEntry = ListHead->Flink;
447 while (NextEntry != ListHead)
448 {
449 /* Get the Mutant */
450 Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry);
451 ASSERT_MUTANT(Mutant);
452
453 /* Make sure it's not terminating with APCs off */
454 if (Mutant->ApcDisable)
455 {
456 /* Bugcheck the system */
457 KeBugCheckEx(THREAD_TERMINATE_HELD_MUTEX,
459 (ULONG_PTR)Mutant,
460 0,
461 0);
462 }
463
464 /* Now we can remove it */
466
467 /* Unconditionally abandon it */
468 Mutant->Header.SignalState = 1;
469 Mutant->Abandoned = TRUE;
470 Mutant->OwnerThread = NULL;
471
472 /* Check if the Wait List isn't empty */
473 if (!IsListEmpty(&Mutant->Header.WaitListHead))
474 {
475 /* Wake the Mutant */
477 }
478
479 /* Move on */
480 NextEntry = Thread->MutantListHead.Flink;
481 }
482
483 /* Release the Lock */
485}
486
487VOID
488NTAPI
490{
492#ifdef CONFIG_SMP
493 PKNODE Node;
494 PKPRCB NodePrcb;
496#endif
497 UCHAR IdealProcessor = 0;
498 PKPROCESS Process = Thread->ApcState.Process;
499
500 /* Setup static fields from parent */
501 Thread->DisableBoost = Process->DisableBoost;
502#if defined(_M_IX86)
503 Thread->Iopl = Process->Iopl;
504#endif
505 Thread->Quantum = Process->QuantumReset;
506 Thread->QuantumReset = Process->QuantumReset;
507 Thread->SystemAffinityActive = FALSE;
508
509 /* Lock the process */
511
512 /* Setup volatile data */
513 Thread->Priority = Process->BasePriority;
514 Thread->BasePriority = Process->BasePriority;
515 Thread->Affinity = Process->Affinity;
516 Thread->UserAffinity = Process->Affinity;
517
518#ifdef CONFIG_SMP
519 /* Get the KNODE and its PRCB */
520 Node = KeNodeBlock[Process->IdealNode];
521 NodePrcb = KiProcessorBlock[Process->ThreadSeed];
522
523 /* Calculate affinity mask */
524#ifdef _M_ARM
526 Set = 0;
527#else
528 Set = ~NodePrcb->MultiThreadProcessorSet;
529#endif
530 Mask = Node->ProcessorMask & Process->Affinity;
531 Set &= Mask;
532 if (Set) Mask = Set;
533
534 /* Get the new thread seed */
535 IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask);
536 Process->ThreadSeed = IdealProcessor;
537
538 /* Sanity check */
539 ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor)));
540#endif
541
542 /* Set the Ideal Processor */
543 Thread->IdealProcessor = IdealProcessor;
544 Thread->UserIdealProcessor = IdealProcessor;
545
546 /* Lock the Dispatcher Database */
548
549 /* Insert the thread into the process list */
550 InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
551
552 /* Increase the stack count */
553 ASSERT(Process->StackCount != MAXULONG_PTR);
554 Process->StackCount++;
555
556 /* Release locks and return */
559}
560
561VOID
562NTAPI
564{
565 /* Does nothing */
567}
568
569VOID
570NTAPI
572 IN PKNORMAL_ROUTINE *NormalRoutine,
573 IN PVOID *NormalContext,
576{
577 /* Does nothing */
579 UNREFERENCED_PARAMETER(NormalRoutine);
580 UNREFERENCED_PARAMETER(NormalContext);
583}
584
585VOID
586NTAPI
590{
591 /* Non-alertable kernel-mode suspended wait */
592 KeWaitForSingleObject(&KeGetCurrentThread()->SuspendSemaphore,
593 Suspended,
595 FALSE,
596 NULL);
597}
598
599ULONG
600NTAPI
602{
603 KLOCK_QUEUE_HANDLE ApcLock;
604 ULONG PreviousCount;
607
608 /* Lock the APC Queue */
610
611 /* Save the Old Count */
612 PreviousCount = Thread->SuspendCount;
613
614 /* Handle the maximum */
615 if (PreviousCount == MAXIMUM_SUSPEND_COUNT)
616 {
617 /* Raise an exception */
618 KiReleaseApcLock(&ApcLock);
620 }
621
622 /* Should we bother to queue at all? */
623 if (Thread->ApcQueueable)
624 {
625 /* Increment the suspend count */
626 Thread->SuspendCount++;
627
628 /* Check if we should suspend it */
629 if (!(PreviousCount) && !(Thread->FreezeCount))
630 {
631 /* Is the APC already inserted? */
632 if (!Thread->SuspendApc.Inserted)
633 {
634 /* Not inserted, insert it */
635 Thread->SuspendApc.Inserted = TRUE;
637 }
638 else
639 {
640 /* Lock the dispatcher */
642
643 /* Unsignal the semaphore, the APC was already inserted */
644 Thread->SuspendSemaphore.Header.SignalState--;
645
646 /* Release the dispatcher */
648 }
649 }
650 }
651
652 /* Release Lock and return the Old State */
654 KiExitDispatcher(ApcLock.OldIrql);
655 return PreviousCount;
656}
657
658VOID
659NTAPI
661{
663 PKTHREAD Current, CurrentThread = KeGetCurrentThread();
664 PKPROCESS Process = CurrentThread->ApcState.Process;
665 PLIST_ENTRY ListHead, NextEntry;
666 LONG OldCount;
668
669 /* Lock the process */
671
672 /* Loop the Process's Threads */
673 ListHead = &Process->ThreadListHead;
674 NextEntry = ListHead->Flink;
675 do
676 {
677 /* Get the current thread */
678 Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
679
680 /* Lock it */
681 KiAcquireApcLockAtSynchLevel(Current, &ApcLock);
682
683 /* Make sure we are frozen */
684 OldCount = Current->FreezeCount;
685 if (OldCount)
686 {
687 /* Decrease the freeze count */
688 Current->FreezeCount--;
689
690 /* Check if both counts are zero now */
691 if (!(Current->SuspendCount) && (!Current->FreezeCount))
692 {
693 /* Lock the dispatcher */
695
696 /* Signal the suspend semaphore and wake it */
697 Current->SuspendSemaphore.Header.SignalState++;
698 KiWaitTest(&Current->SuspendSemaphore, 0);
699
700 /* Unlock the dispatcher */
702 }
703 }
704
705 /* Release the APC lock */
707
708 /* Go to the next one */
709 NextEntry = NextEntry->Flink;
710 } while (NextEntry != ListHead);
711
712 /* Release the process lock and exit the dispatcher */
715
716 /* Leave the critical region */
718}
719
721NTAPI
723{
725 BOOLEAN OldState;
726 KLOCK_QUEUE_HANDLE ApcLock;
729
730 /* Lock the Dispatcher Database and the APC Queue */
732
733 /* Save the old State */
734 OldState = Thread->Alerted[AlertMode];
735
736 /* Check the Thread is alerted */
737 if (OldState)
738 {
739 /* Disable alert for this mode */
740 Thread->Alerted[AlertMode] = FALSE;
741 }
742 else if ((AlertMode != KernelMode) &&
743 (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
744 {
745 /* If the mode is User and the Queue isn't empty, set Pending */
746 Thread->ApcState.UserApcPending = TRUE;
747 }
748
749 /* Release Locks and return the Old State */
750 KiReleaseApcLock(&ApcLock);
751 return OldState;
752}
753
755NTAPI
757 IN PVOID KernelStack,
758 IN PKSYSTEM_ROUTINE SystemRoutine,
760 IN PVOID StartContext,
762 IN PVOID Teb,
764{
765 BOOLEAN AllocatedStack = FALSE;
766 ULONG i;
767 PKWAIT_BLOCK TimerWaitBlock;
770
771 /* Initialize the Dispatcher Header */
772 Thread->Header.Type = ThreadObject;
773 Thread->Header.ThreadControlFlags = 0;
774 Thread->Header.DebugActive = FALSE;
775 Thread->Header.SignalState = 0;
776 InitializeListHead(&(Thread->Header.WaitListHead));
777
778 /* Initialize the Mutant List */
779 InitializeListHead(&Thread->MutantListHead);
780
781 /* Initialize the wait blocks */
782 for (i = 0; i< (THREAD_WAIT_OBJECTS + 1); i++)
783 {
784 /* Put our pointer */
785 Thread->WaitBlock[i].Thread = Thread;
786 }
787
788 /* Set swap settings */
789 Thread->EnableStackSwap = TRUE;
790 Thread->IdealProcessor = 1;
791 Thread->SwapBusy = FALSE;
792 Thread->KernelStackResident = TRUE;
793 Thread->AdjustReason = AdjustNone;
794
795 /* Initialize the lock */
797
798 /* Setup the Service Descriptor Table for Native Calls */
799 Thread->ServiceTable = KeServiceDescriptorTable;
800
801 /* Setup APC Fields */
802 InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
803 InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
804 Thread->ApcState.Process = Process;
805 Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
806 Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
807 Thread->ApcStateIndex = OriginalApcEnvironment;
808 Thread->ApcQueueable = TRUE;
809 KeInitializeSpinLock(&Thread->ApcQueueLock);
810
811 /* Initialize the Suspend APC */
812 KeInitializeApc(&Thread->SuspendApc,
813 Thread,
819 NULL);
820
821 /* Initialize the Suspend Semaphore */
822 KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
823
824 /* Setup the timer */
825 Timer = &Thread->Timer;
827 TimerWaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK];
828 TimerWaitBlock->Object = Timer;
829 TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
830 TimerWaitBlock->WaitType = WaitAny;
831 TimerWaitBlock->NextWaitBlock = NULL;
832
833 /* Link the two wait lists together */
834 TimerWaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead;
835 TimerWaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead;
836
837 /* Set the TEB and process */
838 Thread->Teb = Teb;
839 Thread->Process = Process;
840
841 /* Check if we have a kernel stack */
842 if (!KernelStack)
843 {
844 /* We don't, allocate one */
845 KernelStack = MmCreateKernelStack(FALSE, 0);
846 if (!KernelStack) return STATUS_INSUFFICIENT_RESOURCES;
847
848 /* Remember for later */
849 AllocatedStack = TRUE;
850 }
851
852 /* Set the Thread Stacks */
853 Thread->InitialStack = KernelStack;
854 Thread->StackBase = KernelStack;
855 Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE;
856 Thread->KernelStackResident = TRUE;
857
858 /* Enter SEH to avoid crashes due to user mode */
861 {
862 /* Initialize the Thread Context */
864 SystemRoutine,
866 StartContext,
867 Context);
868 }
870 {
871 /* Set failure status */
873
874 /* Check if a stack was allocated */
875 if (AllocatedStack)
876 {
877 /* Delete the stack */
879 Thread->InitialStack = NULL;
880 }
881 }
882 _SEH2_END;
883
884 /* Set the Thread to initialized */
885 Thread->State = Initialized;
886 return Status;
887}
888
889VOID
890NTAPI
893 IN PKSYSTEM_ROUTINE SystemRoutine,
895 IN PVOID StartContext,
897 IN PVOID Teb,
898 IN PVOID KernelStack)
899{
900 /* Initialize and start the thread on success */
902 KernelStack,
903 SystemRoutine,
905 StartContext,
906 Context,
907 Teb,
908 Process)))
909 {
910 /* Start it */
912 }
913}
914
915VOID
916NTAPI
918{
919 /* Delete the stack */
921 Thread->InitialStack = NULL;
922}
923
924/* PUBLIC FUNCTIONS **********************************************************/
925
926/*
927 * @unimplemented
928 */
929VOID
930NTAPI
932 IN ULONG Setting1,
933 IN ULONG Setting2,
934 IN ULONG Setting3,
935 IN ULONG Setting4,
936 IN ULONG Setting5,
937 IN PVOID ThreadState)
938{
940}
941
942/*
943 * @implemented
944 */
945#undef KeGetCurrentThread
947NTAPI
949{
950 /* Return the current thread on this PCR */
951 return _KeGetCurrentThread();
952}
953
954/*
955 * @implemented
956 */
957#undef KeGetPreviousMode
958UCHAR
959NTAPI
961{
962 /* Return the previous mode of this thread */
963 return _KeGetPreviousMode();
964}
965
966/*
967 * @implemented
968 */
969ULONG
970NTAPI
973{
975
976 /* Return the User Time */
977 *UserTime = Thread->UserTime;
978
979 /* Return the Kernel Time */
980 return Thread->KernelTime;
981}
982
983/*
984 * @implemented
985 */
987NTAPI
989{
992
993 /* Save Old State */
994 PreviousState = Thread->EnableStackSwap;
995
996 /* Set New State */
997 Thread->EnableStackSwap = Enable;
998
999 /* Return Old State */
1000 return PreviousState;
1001}
1002
1003/*
1004 * @implemented
1005 */
1007NTAPI
1009{
1011
1012 /* Return the current priority */
1013 return Thread->Priority;
1014}
1015
1016/*
1017 * @implemented
1018 */
1019VOID
1020NTAPI
1022{
1023 KIRQL OldIrql;
1024 PKPRCB Prcb;
1025 PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1027 ASSERT(CurrentThread->SystemAffinityActive != FALSE);
1028
1029 /* Lock the Dispatcher Database */
1031
1032 /* Set the user affinity and processor and disable system affinity */
1033 CurrentThread->Affinity = CurrentThread->UserAffinity;
1034 CurrentThread->IdealProcessor = CurrentThread->UserIdealProcessor;
1035 CurrentThread->SystemAffinityActive = FALSE;
1036
1037 /* Get the current PRCB and check if it doesn't match this affinity */
1038 Prcb = KeGetCurrentPrcb();
1039 if (!(Prcb->SetMember & CurrentThread->Affinity))
1040 {
1041 /* Lock the PRCB */
1042 KiAcquirePrcbLock(Prcb);
1043
1044 /* Check if there's no next thread scheduled */
1045 if (!Prcb->NextThread)
1046 {
1047 /* Select a new thread and set it on standby */
1048 NextThread = KiSelectNextThread(Prcb);
1049 NextThread->State = Standby;
1050 Prcb->NextThread = NextThread;
1051 }
1052
1053 /* Release the PRCB lock */
1054 KiReleasePrcbLock(Prcb);
1055 }
1056
1057 /* Unlock dispatcher database */
1059}
1060
1061/*
1062 * @implemented
1063 */
1064UCHAR
1065NTAPI
1068{
1069 CCHAR OldIdealProcessor;
1070 KIRQL OldIrql;
1072
1073 /* Lock the Dispatcher Database */
1075
1076 /* Save Old Ideal Processor */
1077 OldIdealProcessor = Thread->UserIdealProcessor;
1078
1079 /* Make sure a valid CPU was given */
1081 {
1082 /* Check if the user ideal CPU is in the affinity */
1083 if (Thread->Affinity & AFFINITY_MASK(Processor))
1084 {
1085 /* Set the ideal processor */
1086 Thread->IdealProcessor = Processor;
1087
1088 /* Check if system affinity is used */
1089 if (!Thread->SystemAffinityActive)
1090 {
1091 /* It's not, so update the user CPU too */
1092 Thread->UserIdealProcessor = Processor;
1093 }
1094 }
1095 }
1096
1097 /* Release dispatcher lock and return the old ideal CPU */
1099 return OldIdealProcessor;
1100}
1101
1102/*
1103 * @implemented
1104 */
1105VOID
1106NTAPI
1108{
1109 KIRQL OldIrql;
1110 PKPRCB Prcb;
1111 PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1114
1115 /* Lock the Dispatcher Database */
1117
1118 /* Restore the affinity and enable system affinity */
1119 CurrentThread->Affinity = Affinity;
1120 CurrentThread->SystemAffinityActive = TRUE;
1121
1122 /* Check if the ideal processor is part of the affinity */
1123#ifdef CONFIG_SMP
1124 if (!(Affinity & AFFINITY_MASK(CurrentThread->IdealProcessor)))
1125 {
1126 KAFFINITY AffinitySet, NodeMask;
1127 ULONG IdealProcessor;
1128
1129 /* It's not! Get the PRCB */
1130 Prcb = KiProcessorBlock[CurrentThread->IdealProcessor];
1131
1132 /* Calculate the affinity set */
1133 AffinitySet = KeActiveProcessors & Affinity;
1134 NodeMask = Prcb->ParentNode->ProcessorMask & AffinitySet;
1135 if (NodeMask)
1136 {
1137 /* Use the Node set instead */
1138 AffinitySet = NodeMask;
1139 }
1140
1141 /* Calculate the ideal CPU from the affinity set */
1142 BitScanReverseAffinity(&IdealProcessor, AffinitySet);
1143 CurrentThread->IdealProcessor = (UCHAR)IdealProcessor;
1144 }
1145#endif
1146
1147 /* Get the current PRCB and check if it doesn't match this affinity */
1148 Prcb = KeGetCurrentPrcb();
1149 if (!(Prcb->SetMember & CurrentThread->Affinity))
1150 {
1151 /* Lock the PRCB */
1152 KiAcquirePrcbLock(Prcb);
1153
1154 /* Check if there's no next thread scheduled */
1155 if (!Prcb->NextThread)
1156 {
1157 /* Select a new thread and set it on standby */
1158 NextThread = KiSelectNextThread(Prcb);
1159 NextThread->State = Standby;
1160 Prcb->NextThread = NextThread;
1161 }
1162
1163 /* Release the PRCB lock */
1164 KiReleasePrcbLock(Prcb);
1165 }
1166
1167 /* Unlock dispatcher database */
1169}
1170
1171/*
1172 * @implemented
1173 */
1174LONG
1175NTAPI
1178{
1179 KIRQL OldIrql;
1180 KPRIORITY OldBasePriority, Priority, BasePriority;
1181 LONG OldIncrement;
1185
1186 /* Get the process */
1187 Process = Thread->ApcState.Process;
1188
1189 /* Lock the Dispatcher Database */
1191
1192 /* Lock the thread */
1194
1195 /* Save the old base priority and increment */
1196 OldBasePriority = Thread->BasePriority;
1197 OldIncrement = OldBasePriority - Process->BasePriority;
1198
1199 /* If priority saturation happened, use the saturated increment */
1200 if (Thread->Saturation) OldIncrement = (HIGH_PRIORITY + 1) / 2 *
1201 Thread->Saturation;
1202
1203 /* Reset the saturation value */
1204 Thread->Saturation = 0;
1205
1206 /* Now check if saturation is being used for the new value */
1207 if (abs(Increment) >= ((HIGH_PRIORITY + 1) / 2))
1208 {
1209 /* Check if we need positive or negative saturation */
1210 Thread->Saturation = (Increment > 0) ? 1 : -1;
1211 }
1212
1213 /* Normalize the Base Priority */
1214 BasePriority = Process->BasePriority + Increment;
1215 if (Process->BasePriority >= LOW_REALTIME_PRIORITY)
1216 {
1217 /* Check if it's too low */
1218 if (BasePriority < LOW_REALTIME_PRIORITY)
1219 {
1220 /* Set it to the lowest real time level */
1221 BasePriority = LOW_REALTIME_PRIORITY;
1222 }
1223
1224 /* Check if it's too high */
1225 if (BasePriority > HIGH_PRIORITY) BasePriority = HIGH_PRIORITY;
1226
1227 /* We are at real time, so use the raw base priority */
1228 Priority = BasePriority;
1229 }
1230 else
1231 {
1232 /* Check if it's entering the real time range */
1233 if (BasePriority >= LOW_REALTIME_PRIORITY)
1234 {
1235 /* Set it to the highest dynamic level */
1236 BasePriority = LOW_REALTIME_PRIORITY - 1;
1237 }
1238
1239 /* Check if it's too low and normalize it */
1240 if (BasePriority <= LOW_PRIORITY) BasePriority = 1;
1241
1242 /* Check if Saturation is used */
1243 if (Thread->Saturation)
1244 {
1245 /* Use the raw base priority */
1246 Priority = BasePriority;
1247 }
1248 else
1249 {
1250 /* Otherwise, calculate the new priority */
1252 Priority += (BasePriority - OldBasePriority);
1253
1254 /* Check if it entered the real-time range */
1256 {
1257 /* Normalize it down to the highest dynamic priority */
1259 }
1260 else if (Priority <= LOW_PRIORITY)
1261 {
1262 /* It went too low, normalize it */
1263 Priority = 1;
1264 }
1265 }
1266 }
1267
1268 /* Finally set the new base priority */
1269 Thread->BasePriority = (SCHAR)BasePriority;
1270
1271 /* Reset the decrements */
1272 Thread->PriorityDecrement = 0;
1273
1274 /* Check if we're changing priority after all */
1275 if (Priority != Thread->Priority)
1276 {
1277 /* Reset the quantum and do the actual priority modification */
1278 Thread->Quantum = Thread->QuantumReset;
1280 }
1281
1282 /* Release thread lock */
1284
1285 /* Release the dispatcher database and return old increment */
1287 return OldIncrement;
1288}
1289
1290/*
1291 * @implemented
1292 */
1294NTAPI
1297{
1298 KIRQL OldIrql;
1299 KAFFINITY OldAffinity;
1302
1303 /* Lock the dispatcher database */
1305
1306 /* Call the internal function */
1307 OldAffinity = KiSetAffinityThread(Thread, Affinity);
1308
1309 /* Release the dispatcher database and return old affinity */
1311 return OldAffinity;
1312}
1313
1314/*
1315 * @implemented
1316 */
1318NTAPI
1321{
1322 KIRQL OldIrql;
1323 KPRIORITY OldPriority;
1328
1329 /* Lock the Dispatcher Database */
1331
1332 /* Lock the thread */
1334
1335 /* Save the old Priority and reset decrement */
1336 OldPriority = Thread->Priority;
1337 Thread->PriorityDecrement = 0;
1338
1339 /* Make sure that an actual change is being done */
1340 if (Priority != Thread->Priority)
1341 {
1342 /* Reset the quantum */
1343 Thread->Quantum = Thread->QuantumReset;
1344
1345 /* Check if priority is being set too low and normalize if so */
1346 if ((Thread->BasePriority != 0) && !(Priority)) Priority = 1;
1347
1348 /* Set the new Priority */
1350 }
1351
1352 /* Release thread lock */
1354
1355 /* Release the dispatcher database */
1357
1358 /* Return Old Priority */
1359 return OldPriority;
1360}
1361
1362/*
1363 * @implemented
1364 */
1365VOID
1366NTAPI
1368{
1369 PLIST_ENTRY *ListHead;
1370 PETHREAD Entry, SavedEntry;
1371 PETHREAD *ThreadAddr;
1374 PKPROCESS Process = Thread->ApcState.Process;
1376
1377 /* Lock the process */
1379
1380 /* Make sure we won't get Swapped */
1382
1383 /* Save the Kernel and User Times */
1384 Process->KernelTime += Thread->KernelTime;
1385 Process->UserTime += Thread->UserTime;
1386
1387 /* Get the current entry and our Port */
1389 ThreadAddr = &((PETHREAD)Thread)->ReaperLink;
1390
1391 /* Add it to the reaper's list */
1392 do
1393 {
1394 /* Get the list head */
1395 ListHead = &PspReaperListHead.Flink;
1396
1397 /* Link ourselves */
1398 *ThreadAddr = Entry;
1399 SavedEntry = Entry;
1400
1401 /* Now try to do the exchange */
1403 ThreadAddr,
1404 Entry);
1405
1406 /* Break out if the change was succesful */
1407 } while (Entry != SavedEntry);
1408
1409 /* Acquire the dispatcher lock */
1411
1412 /* Check if the reaper wasn't active */
1413 if (!Entry)
1414 {
1415 /* Activate it as a work item, directly through its Queue */
1418 FALSE);
1419 }
1420
1421 /* Check the thread has an associated queue */
1422 if (Thread->Queue)
1423 {
1424 /* Remove it from the list, and handle the queue */
1425 RemoveEntryList(&Thread->QueueListEntry);
1427 }
1428
1429 /* Signal the thread */
1430 Thread->Header.SignalState = TRUE;
1431 if (!IsListEmpty(&Thread->Header.WaitListHead))
1432 {
1433 /* Unwait the threads */
1434 KxUnwaitThread(&Thread->Header, Increment);
1435 }
1436
1437 /* Remove the thread from the list */
1439
1440 /* Release the process lock */
1442
1443 /* Set us as terminated, decrease the Process's stack count */
1444 Thread->State = Terminated;
1445
1446 /* Decrease stack count */
1447 ASSERT(Process->StackCount != 0);
1448 ASSERT(Process->State == ProcessInMemory);
1449 Process->StackCount--;
1450 if (!(Process->StackCount) && !(IsListEmpty(&Process->ThreadListHead)))
1451 {
1452 /* FIXME: Swap stacks */
1453 }
1454
1455 /* Rundown arch-specific parts */
1457
1458 /* Swap to a new thread */
1461}
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 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:1472
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:1146
#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
FORCEINLINE KAFFINITY AFFINITY_MASK(ULONG Index)
Definition: kefuncs.h:39
FORCEINLINE BOOLEAN BitScanReverseAffinity(PULONG Index, KAFFINITY Mask)
Definition: kefuncs.h:54
VOID(NTAPI * PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
Definition: ketypes.h:737
@ 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:768
@ OriginalApcEnvironment
Definition: ketypes.h:767
#define THREAD_ALERT_INCREMENT
Definition: ketypes.h:126
#define ASSERT_THREAD(object)
Definition: ketypes.h:2076
@ AdjustNone
Definition: ketypes.h:439
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:744
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
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:164
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:647
struct _KTHREAD * NextThread
Definition: ketypes.h:636
struct _KNODE * ParentNode
Definition: ketypes.h:820
ULONG UserIdealProcessor
Definition: ketypes.h:1783
GROUP_AFFINITY Affinity
Definition: ketypes.h:1938
ULONG IdealProcessor
Definition: ketypes.h:1944
ULONG FreezeCount
Definition: ketypes.h:1737
ULONG SystemAffinityActive
Definition: ketypes.h:1697
GROUP_AFFINITY UserAffinity
Definition: ketypes.h:1912
DISPATCHER_HEADER Header
Definition: ketypes.h:1661
CHAR SuspendCount
Definition: ketypes.h:1965
KAPC_STATE ApcState
Definition: ketypes.h:1778
ULONG ApcQueueable
Definition: ketypes.h:1711
volatile UCHAR State
Definition: ketypes.h:1789
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
UCHAR NTAPI KeFindNextRightSetAffinity(IN UCHAR Number, IN KAFFINITY Set)
Definition: thrdobj.c:22
NTSTATUS NTAPI KeInitThread(IN OUT PKTHREAD Thread, IN PVOID KernelStack, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext, IN PCONTEXT Context, IN PVOID Teb, IN PKPROCESS Process)
Definition: thrdobj.c:756
KPRIORITY NTAPI KeQueryPriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:1008
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:571
KPRIORITY NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:52
ULONG NTAPI KeForceResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:267
VOID NTAPI KeFreezeAllThreads(VOID)
Definition: thrdobj.c:306
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1107
VOID NTAPI KeUninitThread(IN PKTHREAD Thread)
Definition: thrdobj.c:917
VOID NTAPI KeThawAllThreads(VOID)
Definition: thrdobj.c:660
ULONG NTAPI KeSuspendThread(PKTHREAD Thread)
Definition: thrdobj.c:601
UCHAR NTAPI KeSetIdealProcessorThread(IN PKTHREAD Thread, IN UCHAR Processor)
Definition: thrdobj.c:1066
ULONG NTAPI KeResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:388
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:891
VOID NTAPI KeTerminateThread(IN KPRIORITY Increment)
Definition: thrdobj.c:1367
LONG NTAPI KeSetBasePriorityThread(IN PKTHREAD Thread, IN LONG Increment)
Definition: thrdobj.c:1176
BOOLEAN NTAPI KeSetKernelStackSwapEnable(IN BOOLEAN Enable)
Definition: thrdobj.c:988
BOOLEAN NTAPI KeSetDisableBoostThread(IN OUT PKTHREAD Thread, IN BOOLEAN Disable)
Definition: thrdobj.c:86
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1021
BOOLEAN NTAPI KeAlertThread(IN PKTHREAD Thread, IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:176
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1319
KAFFINITY NTAPI KeSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdobj.c:1295
VOID NTAPI KiSuspendRundown(IN PKAPC Apc)
Definition: thrdobj.c:563
BOOLEAN NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:722
ULONG NTAPI KeQueryRuntimeThread(IN PKTHREAD Thread, OUT PULONG UserTime)
Definition: thrdobj.c:971
VOID NTAPI KeRundownThread(VOID)
Definition: thrdobj.c:430
VOID NTAPI KeStartThread(IN OUT PKTHREAD Thread)
Definition: thrdobj.c:489
VOID NTAPI KeReadyThread(IN PKTHREAD Thread)
Definition: thrdobj.c:106
ULONG NTAPI KeAlertResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:124
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:931
BOOLEAN NTAPI KeReadStateThread(IN PKTHREAD Thread)
Definition: thrdobj.c:42
VOID NTAPI KeBoostPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Increment)
Definition: thrdobj.c:220
EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue]
Definition: work.c:31
VOID NTAPI KiSuspendThread(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: thrdobj.c:587
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
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:759
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
*LockHandle LockHandle _Out_ PKLOCK_QUEUE_HANDLE LockHandle
Definition: kefuncs.h:717
_In_ UCHAR Processor
Definition: kefuncs.h:670
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