ReactOS 0.4.15-dev-6055-g36cdd34
thrdobj.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ke/thrdobj.c
5 * PURPOSE: Implements routines to manage the Kernel Thread Object
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
17
19{
20 0x1, 0x2, 0x4, 0x8, 0x10, 0x20,
21 0x40, 0x80, 0x100, 0x200, 0x400, 0x800,
22 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000,
23 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000,
24 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000,
25 0x40000000, 0x80000000
26};
27
28/* FUNCTIONS *****************************************************************/
29
33 IN ULONG Set)
34{
35 ULONG Bit, Result;
36 ASSERT(Set != 0);
37
38 /* Calculate the mask */
39 Bit = (AFFINITY_MASK(Number) - 1) & Set;
40
41 /* If it's 0, use the one we got */
42 if (!Bit) Bit = Set;
43
44 /* Now find the right set and return it */
46 return (UCHAR)Result;
47}
48
52{
54
55 /* Return signal state */
56 return (BOOLEAN)Thread->Header.SignalState;
57}
58
62{
63 LONG BaseIncrement;
68
69 /* Raise IRQL to synch level */
71
72 /* Lock the thread */
74
75 /* Get the Process */
76 Process = Thread->ApcStatePointer[0]->Process;
77
78 /* Calculate the base increment */
79 BaseIncrement = Thread->BasePriority - Process->BasePriority;
80
81 /* If saturation occured, return the saturation increment instead */
82 if (Thread->Saturation) BaseIncrement = (HIGH_PRIORITY + 1) / 2 *
83 Thread->Saturation;
84
85 /* Release thread lock */
87
88 /* Lower IRQl and return Increment */
90 return BaseIncrement;
91}
92
96 IN BOOLEAN Disable)
97{
99
100 /* Check if we're enabling or disabling */
101 if (Disable)
102 {
103 /* Set the bit */
104 return InterlockedBitTestAndSet(&Thread->ThreadFlags, 1);
105 }
106 else
107 {
108 /* Remove the bit */
109 return InterlockedBitTestAndReset(&Thread->ThreadFlags, 1);
110 }
111}
112
113VOID
114NTAPI
116{
120
121 /* Lock the Dispatcher Database */
123
124 /* Make the thread ready */
126
127 /* Unlock dispatcher database */
129}
130
131ULONG
132NTAPI
134{
135 ULONG PreviousCount;
136 KLOCK_QUEUE_HANDLE ApcLock;
139
140 /* Lock the Dispatcher Database and the APC Queue */
143
144 /* Return if Thread is already alerted. */
145 if (!Thread->Alerted[KernelMode])
146 {
147 /* If it's Blocked, unblock if it we should */
148 if ((Thread->State == Waiting) && (Thread->Alertable))
149 {
150 /* Abort the wait */
152 }
153 else
154 {
155 /* If not, simply Alert it */
156 Thread->Alerted[KernelMode] = TRUE;
157 }
158 }
159
160 /* Save the old Suspend Count */
161 PreviousCount = Thread->SuspendCount;
162
163 /* If the thread is suspended, decrease one of the suspend counts */
164 if (PreviousCount)
165 {
166 /* Decrease count. If we are now zero, unwait it completely */
167 Thread->SuspendCount--;
168 if (!(Thread->SuspendCount) && !(Thread->FreezeCount))
169 {
170 /* Signal and satisfy */
171 Thread->SuspendSemaphore.Header.SignalState++;
172 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
173 }
174 }
175
176 /* Release Locks and return the Old State */
179 KiExitDispatcher(ApcLock.OldIrql);
180 return PreviousCount;
181}
182
184NTAPI
186 IN KPROCESSOR_MODE AlertMode)
187{
189 KLOCK_QUEUE_HANDLE ApcLock;
192
193 /* Lock the Dispatcher Database and the APC Queue */
196
197 /* Save the Previous State */
198 PreviousState = Thread->Alerted[AlertMode];
199
200 /* Check if it's already alerted */
201 if (!PreviousState)
202 {
203 /* Check if the thread is alertable, and blocked in the given mode */
204 if ((Thread->State == Waiting) &&
205 (Thread->Alertable) &&
206 (AlertMode <= Thread->WaitMode))
207 {
208 /* Abort the wait to alert the thread */
210 }
211 else
212 {
213 /* Otherwise, merely set the alerted state */
214 Thread->Alerted[AlertMode] = TRUE;
215 }
216 }
217
218 /* Release the Dispatcher Lock */
221 KiExitDispatcher(ApcLock.OldIrql);
222
223 /* Return the old state */
224 return PreviousState;
225}
226
227VOID
228NTAPI
231{
235
236 /* Lock the Dispatcher Database */
238
239 /* Only threads in the dynamic range get boosts */
240 if (Thread->Priority < LOW_REALTIME_PRIORITY)
241 {
242 /* Lock the thread */
244
245 /* Check again, and make sure there's not already a boost */
246 if ((Thread->Priority < LOW_REALTIME_PRIORITY) &&
247 !(Thread->PriorityDecrement))
248 {
249 /* Compute the new priority and see if it's higher */
250 Priority = Thread->BasePriority + Increment;
251 if (Priority > Thread->Priority)
252 {
254 {
256 }
257
258 /* Reset the quantum */
259 Thread->Quantum = Thread->QuantumReset;
260
261 /* Set the new Priority */
263 }
264 }
265
266 /* Release thread lock */
268 }
269
270 /* Release the dispatcher lokc */
272}
273
274ULONG
275NTAPI
277{
278 KLOCK_QUEUE_HANDLE ApcLock;
279 ULONG PreviousCount;
282
283 /* Lock the APC Queue */
285
286 /* Save the old Suspend Count */
287 PreviousCount = Thread->SuspendCount + Thread->FreezeCount;
288
289 /* If the thread is suspended, wake it up!!! */
290 if (PreviousCount)
291 {
292 /* Unwait it completely */
293 Thread->SuspendCount = 0;
294 Thread->FreezeCount = 0;
295
296 /* Lock the dispatcher */
298
299 /* Signal and satisfy */
300 Thread->SuspendSemaphore.Header.SignalState++;
301 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
302
303 /* Release the dispatcher */
305 }
306
307 /* Release Lock and return the Old State */
309 KiExitDispatcher(ApcLock.OldIrql);
310 return PreviousCount;
311}
312
313VOID
314NTAPI
316{
318 PKTHREAD Current, CurrentThread = KeGetCurrentThread();
319 PKPROCESS Process = CurrentThread->ApcState.Process;
320 PLIST_ENTRY ListHead, NextEntry;
321 LONG OldCount;
323
324 /* Lock the process */
326
327 /* If someone is already trying to free us, try again */
328 while (CurrentThread->FreezeCount)
329 {
330 /* Release and re-acquire the process lock so the APC will go through */
333 }
334
335 /* Enter a critical region */
337
338 /* Loop the Process's Threads */
339 ListHead = &Process->ThreadListHead;
340 NextEntry = ListHead->Flink;
341 do
342 {
343 /* Get the current thread */
344 Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
345
346 /* Lock it */
347 KiAcquireApcLockAtSynchLevel(Current, &ApcLock);
348
349 /* Make sure it's not ours, and check if APCs are enabled */
350 if ((Current != CurrentThread) && (Current->ApcQueueable))
351 {
352 /* Sanity check */
353 OldCount = Current->SuspendCount;
354 ASSERT(OldCount != MAXIMUM_SUSPEND_COUNT);
355
356 /* Increase the freeze count */
357 Current->FreezeCount++;
358
359 /* Make sure it wasn't already suspended */
360 if (!(OldCount) && !(Current->SuspendCount))
361 {
362 /* Did we already insert it? */
363 if (!Current->SuspendApc.Inserted)
364 {
365 /* Insert the APC */
366 Current->SuspendApc.Inserted = TRUE;
367 KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT);
368 }
369 else
370 {
371 /* Lock the dispatcher */
373
374 /* Unsignal the semaphore, the APC was already inserted */
375 Current->SuspendSemaphore.Header.SignalState--;
376
377 /* Release the dispatcher */
379 }
380 }
381 }
382
383 /* Release the APC lock */
385
386 /* Move to the next thread */
387 NextEntry = NextEntry->Flink;
388 } while (NextEntry != ListHead);
389
390 /* Release the process lock and exit the dispatcher */
393}
394
395ULONG
396NTAPI
398{
399 KLOCK_QUEUE_HANDLE ApcLock;
400 ULONG PreviousCount;
403
404 /* Lock the APC Queue */
406
407 /* Save the Old Count */
408 PreviousCount = Thread->SuspendCount;
409
410 /* Check if it existed */
411 if (PreviousCount)
412 {
413 /* Decrease the suspend count */
414 Thread->SuspendCount--;
415
416 /* Check if the thrad is still suspended or not */
417 if ((!Thread->SuspendCount) && (!Thread->FreezeCount))
418 {
419 /* Acquire the dispatcher lock */
421
422 /* Signal the Suspend Semaphore */
423 Thread->SuspendSemaphore.Header.SignalState++;
424 KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
425
426 /* Release the dispatcher lock */
428 }
429 }
430
431 /* Release APC Queue lock and return the Old State */
433 KiExitDispatcher(ApcLock.OldIrql);
434 return PreviousCount;
435}
436
437VOID
438NTAPI
440{
443 PLIST_ENTRY NextEntry, ListHead;
444 PKMUTANT Mutant;
446
447 /* Optimized path if nothing is on the list at the moment */
448 if (IsListEmpty(&Thread->MutantListHead)) return;
449
450 /* Lock the Dispatcher Database */
452
453 /* Get the List Pointers */
454 ListHead = &Thread->MutantListHead;
455 NextEntry = ListHead->Flink;
456 while (NextEntry != ListHead)
457 {
458 /* Get the Mutant */
459 Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry);
460 ASSERT_MUTANT(Mutant);
461
462 /* Make sure it's not terminating with APCs off */
463 if (Mutant->ApcDisable)
464 {
465 /* Bugcheck the system */
466 KeBugCheckEx(THREAD_TERMINATE_HELD_MUTEX,
468 (ULONG_PTR)Mutant,
469 0,
470 0);
471 }
472
473 /* Now we can remove it */
475
476 /* Unconditionally abandon it */
477 Mutant->Header.SignalState = 1;
478 Mutant->Abandoned = TRUE;
479 Mutant->OwnerThread = NULL;
480
481 /* Check if the Wait List isn't empty */
482 if (!IsListEmpty(&Mutant->Header.WaitListHead))
483 {
484 /* Wake the Mutant */
486 }
487
488 /* Move on */
489 NextEntry = Thread->MutantListHead.Flink;
490 }
491
492 /* Release the Lock */
494}
495
496VOID
497NTAPI
499{
501#ifdef CONFIG_SMP
502 PKNODE Node;
503 PKPRCB NodePrcb;
504 ULONG Set, Mask;
505#endif
506 UCHAR IdealProcessor = 0;
507 PKPROCESS Process = Thread->ApcState.Process;
508
509 /* Setup static fields from parent */
510 Thread->DisableBoost = Process->DisableBoost;
511#if defined(_M_IX86)
512 Thread->Iopl = Process->Iopl;
513#endif
514 Thread->Quantum = Process->QuantumReset;
515 Thread->QuantumReset = Process->QuantumReset;
516 Thread->SystemAffinityActive = FALSE;
517
518 /* Lock the process */
520
521 /* Setup volatile data */
522 Thread->Priority = Process->BasePriority;
523 Thread->BasePriority = Process->BasePriority;
524 Thread->Affinity = Process->Affinity;
525 Thread->UserAffinity = Process->Affinity;
526
527#ifdef CONFIG_SMP
528 /* Get the KNODE and its PRCB */
529 Node = KeNodeBlock[Process->IdealNode];
530 NodePrcb = KiProcessorBlock[Process->ThreadSeed];
531
532 /* Calculate affinity mask */
533#ifdef _M_ARM
535 Set = 0;
536#else
537 Set = ~NodePrcb->MultiThreadProcessorSet;
538#endif
539 Mask = (ULONG)(Node->ProcessorMask & Process->Affinity);
540 Set &= Mask;
541 if (Set) Mask = Set;
542
543 /* Get the new thread seed */
544 IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask);
545 Process->ThreadSeed = IdealProcessor;
546
547 /* Sanity check */
548 ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor)));
549#endif
550
551 /* Set the Ideal Processor */
552 Thread->IdealProcessor = IdealProcessor;
553 Thread->UserIdealProcessor = IdealProcessor;
554
555 /* Lock the Dispatcher Database */
557
558 /* Insert the thread into the process list */
559 InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
560
561 /* Increase the stack count */
562 ASSERT(Process->StackCount != MAXULONG_PTR);
563 Process->StackCount++;
564
565 /* Release locks and return */
568}
569
570VOID
571NTAPI
573{
574 /* Does nothing */
576}
577
578VOID
579NTAPI
581 IN PKNORMAL_ROUTINE *NormalRoutine,
582 IN PVOID *NormalContext,
585{
586 /* Does nothing */
588 UNREFERENCED_PARAMETER(NormalRoutine);
589 UNREFERENCED_PARAMETER(NormalContext);
592}
593
594VOID
595NTAPI
599{
600 /* Non-alertable kernel-mode suspended wait */
601 KeWaitForSingleObject(&KeGetCurrentThread()->SuspendSemaphore,
602 Suspended,
604 FALSE,
605 NULL);
606}
607
608ULONG
609NTAPI
611{
612 KLOCK_QUEUE_HANDLE ApcLock;
613 ULONG PreviousCount;
616
617 /* Lock the APC Queue */
619
620 /* Save the Old Count */
621 PreviousCount = Thread->SuspendCount;
622
623 /* Handle the maximum */
624 if (PreviousCount == MAXIMUM_SUSPEND_COUNT)
625 {
626 /* Raise an exception */
627 KiReleaseApcLock(&ApcLock);
629 }
630
631 /* Should we bother to queue at all? */
632 if (Thread->ApcQueueable)
633 {
634 /* Increment the suspend count */
635 Thread->SuspendCount++;
636
637 /* Check if we should suspend it */
638 if (!(PreviousCount) && !(Thread->FreezeCount))
639 {
640 /* Is the APC already inserted? */
641 if (!Thread->SuspendApc.Inserted)
642 {
643 /* Not inserted, insert it */
644 Thread->SuspendApc.Inserted = TRUE;
646 }
647 else
648 {
649 /* Lock the dispatcher */
651
652 /* Unsignal the semaphore, the APC was already inserted */
653 Thread->SuspendSemaphore.Header.SignalState--;
654
655 /* Release the dispatcher */
657 }
658 }
659 }
660
661 /* Release Lock and return the Old State */
663 KiExitDispatcher(ApcLock.OldIrql);
664 return PreviousCount;
665}
666
667VOID
668NTAPI
670{
672 PKTHREAD Current, CurrentThread = KeGetCurrentThread();
673 PKPROCESS Process = CurrentThread->ApcState.Process;
674 PLIST_ENTRY ListHead, NextEntry;
675 LONG OldCount;
677
678 /* Lock the process */
680
681 /* Loop the Process's Threads */
682 ListHead = &Process->ThreadListHead;
683 NextEntry = ListHead->Flink;
684 do
685 {
686 /* Get the current thread */
687 Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
688
689 /* Lock it */
690 KiAcquireApcLockAtSynchLevel(Current, &ApcLock);
691
692 /* Make sure we are frozen */
693 OldCount = Current->FreezeCount;
694 if (OldCount)
695 {
696 /* Decrease the freeze count */
697 Current->FreezeCount--;
698
699 /* Check if both counts are zero now */
700 if (!(Current->SuspendCount) && (!Current->FreezeCount))
701 {
702 /* Lock the dispatcher */
704
705 /* Signal the suspend semaphore and wake it */
706 Current->SuspendSemaphore.Header.SignalState++;
707 KiWaitTest(&Current->SuspendSemaphore, 0);
708
709 /* Unlock the dispatcher */
711 }
712 }
713
714 /* Release the APC lock */
716
717 /* Go to the next one */
718 NextEntry = NextEntry->Flink;
719 } while (NextEntry != ListHead);
720
721 /* Release the process lock and exit the dispatcher */
724
725 /* Leave the critical region */
727}
728
730NTAPI
732{
734 BOOLEAN OldState;
735 KLOCK_QUEUE_HANDLE ApcLock;
738
739 /* Lock the Dispatcher Database and the APC Queue */
741
742 /* Save the old State */
743 OldState = Thread->Alerted[AlertMode];
744
745 /* Check the Thread is alerted */
746 if (OldState)
747 {
748 /* Disable alert for this mode */
749 Thread->Alerted[AlertMode] = FALSE;
750 }
751 else if ((AlertMode != KernelMode) &&
752 (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
753 {
754 /* If the mode is User and the Queue isn't empty, set Pending */
755 Thread->ApcState.UserApcPending = TRUE;
756 }
757
758 /* Release Locks and return the Old State */
759 KiReleaseApcLock(&ApcLock);
760 return OldState;
761}
762
764NTAPI
766 IN PVOID KernelStack,
767 IN PKSYSTEM_ROUTINE SystemRoutine,
769 IN PVOID StartContext,
771 IN PVOID Teb,
773{
774 BOOLEAN AllocatedStack = FALSE;
775 ULONG i;
776 PKWAIT_BLOCK TimerWaitBlock;
779
780 /* Initialize the Dispatcher Header */
781 Thread->Header.Type = ThreadObject;
782 Thread->Header.ThreadControlFlags = 0;
783 Thread->Header.DebugActive = FALSE;
784 Thread->Header.SignalState = 0;
785 InitializeListHead(&(Thread->Header.WaitListHead));
786
787 /* Initialize the Mutant List */
788 InitializeListHead(&Thread->MutantListHead);
789
790 /* Initialize the wait blocks */
791 for (i = 0; i< (THREAD_WAIT_OBJECTS + 1); i++)
792 {
793 /* Put our pointer */
794 Thread->WaitBlock[i].Thread = Thread;
795 }
796
797 /* Set swap settings */
798 Thread->EnableStackSwap = TRUE;
799 Thread->IdealProcessor = 1;
800 Thread->SwapBusy = FALSE;
801 Thread->KernelStackResident = TRUE;
802 Thread->AdjustReason = AdjustNone;
803
804 /* Initialize the lock */
806
807 /* Setup the Service Descriptor Table for Native Calls */
808 Thread->ServiceTable = KeServiceDescriptorTable;
809
810 /* Setup APC Fields */
811 InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
812 InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
813 Thread->ApcState.Process = Process;
814 Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
815 Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
816 Thread->ApcStateIndex = OriginalApcEnvironment;
817 Thread->ApcQueueable = TRUE;
818 KeInitializeSpinLock(&Thread->ApcQueueLock);
819
820 /* Initialize the Suspend APC */
821 KeInitializeApc(&Thread->SuspendApc,
822 Thread,
828 NULL);
829
830 /* Initialize the Suspend Semaphore */
831 KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
832
833 /* Setup the timer */
834 Timer = &Thread->Timer;
836 TimerWaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK];
837 TimerWaitBlock->Object = Timer;
838 TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
839 TimerWaitBlock->WaitType = WaitAny;
840 TimerWaitBlock->NextWaitBlock = NULL;
841
842 /* Link the two wait lists together */
843 TimerWaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead;
844 TimerWaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead;
845
846 /* Set the TEB and process */
847 Thread->Teb = Teb;
848 Thread->Process = Process;
849
850 /* Check if we have a kernel stack */
851 if (!KernelStack)
852 {
853 /* We don't, allocate one */
854 KernelStack = MmCreateKernelStack(FALSE, 0);
855 if (!KernelStack) return STATUS_INSUFFICIENT_RESOURCES;
856
857 /* Remember for later */
858 AllocatedStack = TRUE;
859 }
860
861 /* Set the Thread Stacks */
862 Thread->InitialStack = KernelStack;
863 Thread->StackBase = KernelStack;
864 Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE;
865 Thread->KernelStackResident = TRUE;
866
867 /* Enter SEH to avoid crashes due to user mode */
870 {
871 /* Initialize the Thread Context */
873 SystemRoutine,
875 StartContext,
876 Context);
877 }
879 {
880 /* Set failure status */
882
883 /* Check if a stack was allocated */
884 if (AllocatedStack)
885 {
886 /* Delete the stack */
888 Thread->InitialStack = NULL;
889 }
890 }
891 _SEH2_END;
892
893 /* Set the Thread to initialized */
894 Thread->State = Initialized;
895 return Status;
896}
897
898VOID
899NTAPI
902 IN PKSYSTEM_ROUTINE SystemRoutine,
904 IN PVOID StartContext,
906 IN PVOID Teb,
907 IN PVOID KernelStack)
908{
909 /* Initialize and start the thread on success */
911 KernelStack,
912 SystemRoutine,
914 StartContext,
915 Context,
916 Teb,
917 Process)))
918 {
919 /* Start it */
921 }
922}
923
924VOID
925NTAPI
927{
928 /* Delete the stack */
930 Thread->InitialStack = NULL;
931}
932
933/* PUBLIC FUNCTIONS **********************************************************/
934
935/*
936 * @unimplemented
937 */
938VOID
939NTAPI
941 IN ULONG Setting1,
942 IN ULONG Setting2,
943 IN ULONG Setting3,
944 IN ULONG Setting4,
945 IN ULONG Setting5,
946 IN PVOID ThreadState)
947{
949}
950
951/*
952 * @implemented
953 */
954#undef KeGetCurrentThread
956NTAPI
958{
959 /* Return the current thread on this PCR */
960 return _KeGetCurrentThread();
961}
962
963/*
964 * @implemented
965 */
966#undef KeGetPreviousMode
967UCHAR
968NTAPI
970{
971 /* Return the previous mode of this thread */
972 return _KeGetPreviousMode();
973}
974
975/*
976 * @implemented
977 */
978ULONG
979NTAPI
982{
984
985 /* Return the User Time */
986 *UserTime = Thread->UserTime;
987
988 /* Return the Kernel Time */
989 return Thread->KernelTime;
990}
991
992/*
993 * @implemented
994 */
996NTAPI
998{
1001
1002 /* Save Old State */
1003 PreviousState = Thread->EnableStackSwap;
1004
1005 /* Set New State */
1006 Thread->EnableStackSwap = Enable;
1007
1008 /* Return Old State */
1009 return PreviousState;
1010}
1011
1012/*
1013 * @implemented
1014 */
1016NTAPI
1018{
1020
1021 /* Return the current priority */
1022 return Thread->Priority;
1023}
1024
1025/*
1026 * @implemented
1027 */
1028VOID
1029NTAPI
1031{
1032 KIRQL OldIrql;
1033 PKPRCB Prcb;
1034 PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1036 ASSERT(CurrentThread->SystemAffinityActive != FALSE);
1037
1038 /* Lock the Dispatcher Database */
1040
1041 /* Set the user affinity and processor and disable system affinity */
1042 CurrentThread->Affinity = CurrentThread->UserAffinity;
1043 CurrentThread->IdealProcessor = CurrentThread->UserIdealProcessor;
1044 CurrentThread->SystemAffinityActive = FALSE;
1045
1046 /* Get the current PRCB and check if it doesn't match this affinity */
1047 Prcb = KeGetCurrentPrcb();
1048 if (!(Prcb->SetMember & CurrentThread->Affinity))
1049 {
1050 /* Lock the PRCB */
1051 KiAcquirePrcbLock(Prcb);
1052
1053 /* Check if there's no next thread scheduled */
1054 if (!Prcb->NextThread)
1055 {
1056 /* Select a new thread and set it on standby */
1057 NextThread = KiSelectNextThread(Prcb);
1058 NextThread->State = Standby;
1059 Prcb->NextThread = NextThread;
1060 }
1061
1062 /* Release the PRCB lock */
1063 KiReleasePrcbLock(Prcb);
1064 }
1065
1066 /* Unlock dispatcher database */
1068}
1069
1070/*
1071 * @implemented
1072 */
1073UCHAR
1074NTAPI
1077{
1078 CCHAR OldIdealProcessor;
1079 KIRQL OldIrql;
1081
1082 /* Lock the Dispatcher Database */
1084
1085 /* Save Old Ideal Processor */
1086 OldIdealProcessor = Thread->UserIdealProcessor;
1087
1088 /* Make sure a valid CPU was given */
1090 {
1091 /* Check if the user ideal CPU is in the affinity */
1092 if (Thread->Affinity & AFFINITY_MASK(Processor))
1093 {
1094 /* Set the ideal processor */
1095 Thread->IdealProcessor = Processor;
1096
1097 /* Check if system affinity is used */
1098 if (!Thread->SystemAffinityActive)
1099 {
1100 /* It's not, so update the user CPU too */
1101 Thread->UserIdealProcessor = Processor;
1102 }
1103 }
1104 }
1105
1106 /* Release dispatcher lock and return the old ideal CPU */
1108 return OldIdealProcessor;
1109}
1110
1111/*
1112 * @implemented
1113 */
1114VOID
1115NTAPI
1117{
1118 KIRQL OldIrql;
1119 PKPRCB Prcb;
1120 PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1123
1124 /* Lock the Dispatcher Database */
1126
1127 /* Restore the affinity and enable system affinity */
1128 CurrentThread->Affinity = Affinity;
1129 CurrentThread->SystemAffinityActive = TRUE;
1130
1131 /* Check if the ideal processor is part of the affinity */
1132#ifdef CONFIG_SMP
1133 if (!(Affinity & AFFINITY_MASK(CurrentThread->IdealProcessor)))
1134 {
1135 ULONG AffinitySet, NodeMask;
1136
1137 /* It's not! Get the PRCB */
1138 Prcb = KiProcessorBlock[CurrentThread->IdealProcessor];
1139
1140 /* Calculate the affinity set */
1141 AffinitySet = KeActiveProcessors & Affinity;
1142 NodeMask = Prcb->ParentNode->ProcessorMask & AffinitySet;
1143 if (NodeMask)
1144 {
1145 /* Use the Node set instead */
1146 AffinitySet = NodeMask;
1147 }
1148
1149 /* Calculate the ideal CPU from the affinity set */
1150 BitScanReverse(&NodeMask, AffinitySet);
1151 CurrentThread->IdealProcessor = (UCHAR)NodeMask;
1152 }
1153#endif
1154
1155 /* Get the current PRCB and check if it doesn't match this affinity */
1156 Prcb = KeGetCurrentPrcb();
1157 if (!(Prcb->SetMember & CurrentThread->Affinity))
1158 {
1159 /* Lock the PRCB */
1160 KiAcquirePrcbLock(Prcb);
1161
1162 /* Check if there's no next thread scheduled */
1163 if (!Prcb->NextThread)
1164 {
1165 /* Select a new thread and set it on standby */
1166 NextThread = KiSelectNextThread(Prcb);
1167 NextThread->State = Standby;
1168 Prcb->NextThread = NextThread;
1169 }
1170
1171 /* Release the PRCB lock */
1172 KiReleasePrcbLock(Prcb);
1173 }
1174
1175 /* Unlock dispatcher database */
1177}
1178
1179/*
1180 * @implemented
1181 */
1182LONG
1183NTAPI
1186{
1187 KIRQL OldIrql;
1188 KPRIORITY OldBasePriority, Priority, BasePriority;
1189 LONG OldIncrement;
1193
1194 /* Get the process */
1195 Process = Thread->ApcState.Process;
1196
1197 /* Lock the Dispatcher Database */
1199
1200 /* Lock the thread */
1202
1203 /* Save the old base priority and increment */
1204 OldBasePriority = Thread->BasePriority;
1205 OldIncrement = OldBasePriority - Process->BasePriority;
1206
1207 /* If priority saturation happened, use the saturated increment */
1208 if (Thread->Saturation) OldIncrement = (HIGH_PRIORITY + 1) / 2 *
1209 Thread->Saturation;
1210
1211 /* Reset the saturation value */
1212 Thread->Saturation = 0;
1213
1214 /* Now check if saturation is being used for the new value */
1215 if (abs(Increment) >= ((HIGH_PRIORITY + 1) / 2))
1216 {
1217 /* Check if we need positive or negative saturation */
1218 Thread->Saturation = (Increment > 0) ? 1 : -1;
1219 }
1220
1221 /* Normalize the Base Priority */
1222 BasePriority = Process->BasePriority + Increment;
1223 if (Process->BasePriority >= LOW_REALTIME_PRIORITY)
1224 {
1225 /* Check if it's too low */
1226 if (BasePriority < LOW_REALTIME_PRIORITY)
1227 {
1228 /* Set it to the lowest real time level */
1229 BasePriority = LOW_REALTIME_PRIORITY;
1230 }
1231
1232 /* Check if it's too high */
1233 if (BasePriority > HIGH_PRIORITY) BasePriority = HIGH_PRIORITY;
1234
1235 /* We are at real time, so use the raw base priority */
1236 Priority = BasePriority;
1237 }
1238 else
1239 {
1240 /* Check if it's entering the real time range */
1241 if (BasePriority >= LOW_REALTIME_PRIORITY)
1242 {
1243 /* Set it to the highest dynamic level */
1244 BasePriority = LOW_REALTIME_PRIORITY - 1;
1245 }
1246
1247 /* Check if it's too low and normalize it */
1248 if (BasePriority <= LOW_PRIORITY) BasePriority = 1;
1249
1250 /* Check if Saturation is used */
1251 if (Thread->Saturation)
1252 {
1253 /* Use the raw base priority */
1254 Priority = BasePriority;
1255 }
1256 else
1257 {
1258 /* Otherwise, calculate the new priority */
1260 Priority += (BasePriority - OldBasePriority);
1261
1262 /* Check if it entered the real-time range */
1264 {
1265 /* Normalize it down to the highest dynamic priority */
1267 }
1268 else if (Priority <= LOW_PRIORITY)
1269 {
1270 /* It went too low, normalize it */
1271 Priority = 1;
1272 }
1273 }
1274 }
1275
1276 /* Finally set the new base priority */
1277 Thread->BasePriority = (SCHAR)BasePriority;
1278
1279 /* Reset the decrements */
1280 Thread->PriorityDecrement = 0;
1281
1282 /* Check if we're changing priority after all */
1283 if (Priority != Thread->Priority)
1284 {
1285 /* Reset the quantum and do the actual priority modification */
1286 Thread->Quantum = Thread->QuantumReset;
1288 }
1289
1290 /* Release thread lock */
1292
1293 /* Release the dispatcher database and return old increment */
1295 return OldIncrement;
1296}
1297
1298/*
1299 * @implemented
1300 */
1302NTAPI
1305{
1306 KIRQL OldIrql;
1307 KAFFINITY OldAffinity;
1310
1311 /* Lock the dispatcher database */
1313
1314 /* Call the internal function */
1315 OldAffinity = KiSetAffinityThread(Thread, Affinity);
1316
1317 /* Release the dispatcher database and return old affinity */
1319 return OldAffinity;
1320}
1321
1322/*
1323 * @implemented
1324 */
1326NTAPI
1329{
1330 KIRQL OldIrql;
1331 KPRIORITY OldPriority;
1336
1337 /* Lock the Dispatcher Database */
1339
1340 /* Lock the thread */
1342
1343 /* Save the old Priority and reset decrement */
1344 OldPriority = Thread->Priority;
1345 Thread->PriorityDecrement = 0;
1346
1347 /* Make sure that an actual change is being done */
1348 if (Priority != Thread->Priority)
1349 {
1350 /* Reset the quantum */
1351 Thread->Quantum = Thread->QuantumReset;
1352
1353 /* Check if priority is being set too low and normalize if so */
1354 if ((Thread->BasePriority != 0) && !(Priority)) Priority = 1;
1355
1356 /* Set the new Priority */
1358 }
1359
1360 /* Release thread lock */
1362
1363 /* Release the dispatcher database */
1365
1366 /* Return Old Priority */
1367 return OldPriority;
1368}
1369
1370/*
1371 * @implemented
1372 */
1373VOID
1374NTAPI
1376{
1377 PLIST_ENTRY *ListHead;
1378 PETHREAD Entry, SavedEntry;
1379 PETHREAD *ThreadAddr;
1382 PKPROCESS Process = Thread->ApcState.Process;
1384
1385 /* Lock the process */
1387
1388 /* Make sure we won't get Swapped */
1390
1391 /* Save the Kernel and User Times */
1392 Process->KernelTime += Thread->KernelTime;
1393 Process->UserTime += Thread->UserTime;
1394
1395 /* Get the current entry and our Port */
1397 ThreadAddr = &((PETHREAD)Thread)->ReaperLink;
1398
1399 /* Add it to the reaper's list */
1400 do
1401 {
1402 /* Get the list head */
1403 ListHead = &PspReaperListHead.Flink;
1404
1405 /* Link ourselves */
1406 *ThreadAddr = Entry;
1407 SavedEntry = Entry;
1408
1409 /* Now try to do the exchange */
1411 ThreadAddr,
1412 Entry);
1413
1414 /* Break out if the change was succesful */
1415 } while (Entry != SavedEntry);
1416
1417 /* Acquire the dispatcher lock */
1419
1420 /* Check if the reaper wasn't active */
1421 if (!Entry)
1422 {
1423 /* Activate it as a work item, directly through its Queue */
1426 FALSE);
1427 }
1428
1429 /* Check the thread has an associated queue */
1430 if (Thread->Queue)
1431 {
1432 /* Remove it from the list, and handle the queue */
1433 RemoveEntryList(&Thread->QueueListEntry);
1435 }
1436
1437 /* Signal the thread */
1438 Thread->Header.SignalState = TRUE;
1439 if (!IsListEmpty(&Thread->Header.WaitListHead))
1440 {
1441 /* Unwait the threads */
1442 KxUnwaitThread(&Thread->Header, Increment);
1443 }
1444
1445 /* Remove the thread from the list */
1447
1448 /* Release the process lock */
1450
1451 /* Set us as terminated, decrease the Process's stack count */
1452 Thread->State = Terminated;
1453
1454 /* Decrease stack count */
1455 ASSERT(Process->StackCount != 0);
1456 ASSERT(Process->State == ProcessInMemory);
1457 Process->StackCount--;
1458 if (!(Process->StackCount) && !(IsListEmpty(&Process->ThreadListHead)))
1459 {
1460 /* FIXME: Swap stacks */
1461 }
1462
1463 /* Rundown arch-specific parts */
1465
1466 /* Swap to a new thread */
1469}
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 MAXIMUM_PRIORITY
#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:1080
#define _KeGetPreviousMode()
Definition: ketypes.h:1105
#define KeGetPreviousMode()
Definition: ketypes.h:1108
#define _KeGetCurrentThread()
Definition: ketypes.h:1104
#define MUTANT_INCREMENT
Definition: extypes.h:84
VOID(NTAPI * PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
Definition: ketypes.h:677
@ ProcessInMemory
Definition: ketypes.h:493
@ ThreadObject
Definition: ketypes.h:445
@ Terminated
Definition: ketypes.h:425
@ Standby
Definition: ketypes.h:424
@ Waiting
Definition: ketypes.h:426
@ Initialized
Definition: ketypes.h:421
@ AttachedApcEnvironment
Definition: ketypes.h:708
@ OriginalApcEnvironment
Definition: ketypes.h:707
#define THREAD_ALERT_INCREMENT
Definition: ketypes.h:126
#define ASSERT_THREAD(object)
Definition: ketypes.h:2016
@ AdjustNone
Definition: ketypes.h:472
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:684
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:166
#define AFFINITY_MASK(Id)
Definition: ke.h:159
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:796
EX_PUSH_LOCK ThreadLock
Definition: pstypes.h:1160
LIST_ENTRY ThreadListEntry
Definition: pstypes.h:1158
Definition: ketypes.h:535
DISPATCHER_HEADER Header
Definition: ketypes.h:829
LIST_ENTRY MutantListEntry
Definition: ketypes.h:830
BOOLEAN Abandoned
Definition: ketypes.h:832
struct _KTHREAD *RESTRICTED_POINTER OwnerThread
Definition: ketypes.h:831
UCHAR ApcDisable
Definition: ketypes.h:833
UINT64 SetMember
Definition: ketypes.h:583
struct _KTHREAD * NextThread
Definition: ketypes.h:572
struct _KNODE * ParentNode
Definition: ketypes.h:756
ULONG UserIdealProcessor
Definition: ketypes.h:1723
GROUP_AFFINITY Affinity
Definition: ketypes.h:1878
ULONG IdealProcessor
Definition: ketypes.h:1884
ULONG FreezeCount
Definition: ketypes.h:1677
ULONG SystemAffinityActive
Definition: ketypes.h:1637
GROUP_AFFINITY UserAffinity
Definition: ketypes.h:1852
DISPATCHER_HEADER Header
Definition: ketypes.h:1601
CHAR SuspendCount
Definition: ketypes.h:1905
KAPC_STATE ApcState
Definition: ketypes.h:1718
ULONG ApcQueueable
Definition: ketypes.h:1651
volatile UCHAR State
Definition: ketypes.h:1729
PVOID Object
Definition: ketypes.h:456
LIST_ENTRY WaitListEntry
Definition: ketypes.h:444
UCHAR WaitType
Definition: ketypes.h:446
USHORT WaitKey
Definition: ketypes.h:448
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:765
KPRIORITY NTAPI KeQueryPriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:1017
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:580
KPRIORITY NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:61
ULONG NTAPI KeForceResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:276
VOID NTAPI KeFreezeAllThreads(VOID)
Definition: thrdobj.c:315
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1116
VOID NTAPI KeUninitThread(IN PKTHREAD Thread)
Definition: thrdobj.c:926
VOID NTAPI KeThawAllThreads(VOID)
Definition: thrdobj.c:669
UCHAR NTAPI KeFindNextRightSetAffinity(IN UCHAR Number, IN ULONG Set)
Definition: thrdobj.c:32
ULONG NTAPI KeSuspendThread(PKTHREAD Thread)
Definition: thrdobj.c:610
UCHAR NTAPI KeSetIdealProcessorThread(IN PKTHREAD Thread, IN UCHAR Processor)
Definition: thrdobj.c:1075
ULONG NTAPI KeResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:397
VOID NTAPI KeInitializeThread(IN PKPROCESS Process, IN OUT PKTHREAD Thread, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext, IN PCONTEXT Context, IN PVOID Teb, IN PVOID KernelStack)
Definition: thrdobj.c:900
VOID NTAPI KeTerminateThread(IN KPRIORITY Increment)
Definition: thrdobj.c:1375
LONG NTAPI KeSetBasePriorityThread(IN PKTHREAD Thread, IN LONG Increment)
Definition: thrdobj.c:1184
BOOLEAN NTAPI KeSetKernelStackSwapEnable(IN BOOLEAN Enable)
Definition: thrdobj.c:997
ULONG KiMask32Array[MAXIMUM_PRIORITY]
Definition: thrdobj.c:18
BOOLEAN NTAPI KeSetDisableBoostThread(IN OUT PKTHREAD Thread, IN BOOLEAN Disable)
Definition: thrdobj.c:95
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1030
BOOLEAN NTAPI KeAlertThread(IN PKTHREAD Thread, IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:185
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1327
KAFFINITY NTAPI KeSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdobj.c:1303
VOID NTAPI KiSuspendRundown(IN PKAPC Apc)
Definition: thrdobj.c:572
BOOLEAN NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:731
ULONG NTAPI KeQueryRuntimeThread(IN PKTHREAD Thread, OUT PULONG UserTime)
Definition: thrdobj.c:980
VOID NTAPI KeRundownThread(VOID)
Definition: thrdobj.c:439
VOID NTAPI KeStartThread(IN OUT PKTHREAD Thread)
Definition: thrdobj.c:498
VOID NTAPI KeReadyThread(IN PKTHREAD Thread)
Definition: thrdobj.c:115
ULONG NTAPI KeAlertResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:133
VOID NTAPI KeCapturePersistentThreadState(IN PVOID CurrentThread, IN ULONG Setting1, IN ULONG Setting2, IN ULONG Setting3, IN ULONG Setting4, IN ULONG Setting5, IN PVOID ThreadState)
Definition: thrdobj.c:940
BOOLEAN NTAPI KeReadStateThread(IN PKTHREAD Thread)
Definition: thrdobj.c:51
VOID NTAPI KeBoostPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Increment)
Definition: thrdobj.c:229
EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue]
Definition: work.c:31
VOID NTAPI KiSuspendThread(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: thrdobj.c:596
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
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:426
@ 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:487
@ Suspended
Definition: ketypes.h:408
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:676
#define THREAD_WAIT_OBJECTS
Definition: ketypes.h:480
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:677
#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