ReactOS 0.4.15-dev-7942-gd23573b
thrdschd.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/thrdschd.c
5 * PURPOSE: Kernel Thread Scheduler (Affinity, Priority, Scheduling)
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
15#ifdef _WIN64
16# define InterlockedOrSetMember(Destination, SetMember) \
17 InterlockedOr64((PLONG64)Destination, SetMember);
18#else
19# define InterlockedOrSetMember(Destination, SetMember) \
20 InterlockedOr((PLONG)Destination, SetMember);
21#endif
22
23/* GLOBALS *******************************************************************/
24
27
28/* FUNCTIONS *****************************************************************/
29
33{
34 /* FIXME: TODO */
35 ASSERTMSG("SMP: Not yet implemented\n", FALSE);
36 return NULL;
37}
38
39VOID
42{
43 PSINGLE_LIST_ENTRY ListEntry;
45
46 /* Make sure there is something on the ready list */
47 ASSERT(Prcb->DeferredReadyListHead.Next != NULL);
48
49 /* Get the first entry and clear the list */
50 ListEntry = Prcb->DeferredReadyListHead.Next;
51 Prcb->DeferredReadyListHead.Next = NULL;
52
53 /* Start processing loop */
54 do
55 {
56 /* Get the thread and advance to the next entry */
57 Thread = CONTAINING_RECORD(ListEntry, KTHREAD, SwapListEntry);
58 ListEntry = ListEntry->Next;
59
60 /* Make the thread ready */
62 } while (ListEntry != NULL);
63
64 /* Make sure the ready list is still empty */
65 ASSERT(Prcb->DeferredReadyListHead.Next == NULL);
66}
67
68VOID
71 IN PKPRCB Prcb)
72{
73 /* Call the macro. We keep the API for compatibility with ASM code */
74 KxQueueReadyThread(Thread, Prcb);
75}
76
77VOID
80{
81 PKPRCB Prcb;
82 BOOLEAN Preempted;
83 ULONG Processor = 0;
84 KPRIORITY OldPriority;
85 PKTHREAD NextThread;
86
87 /* Sanity checks */
88 ASSERT(Thread->State == DeferredReady);
89 ASSERT((Thread->Priority >= 0) && (Thread->Priority <= HIGH_PRIORITY));
90
91 /* Check if we have any adjusts to do */
92 if (Thread->AdjustReason == AdjustBoost)
93 {
94 /* Lock the thread */
96
97 /* Check if the priority is low enough to qualify for boosting */
98 if ((Thread->Priority <= Thread->AdjustIncrement) &&
99 (Thread->Priority < (LOW_REALTIME_PRIORITY - 3)) &&
100 !(Thread->DisableBoost))
101 {
102 /* Calculate the new priority based on the adjust increment */
103 OldPriority = min(Thread->AdjustIncrement + 1,
105
106 /* Make sure we're not decreasing outside of the priority range */
107 ASSERT((Thread->PriorityDecrement >= 0) &&
108 (Thread->PriorityDecrement <= Thread->Priority));
109
110 /* Calculate the new priority decrement based on the boost */
111 Thread->PriorityDecrement += ((SCHAR)OldPriority - Thread->Priority);
112
113 /* Again verify that this decrement is valid */
114 ASSERT((Thread->PriorityDecrement >= 0) &&
115 (Thread->PriorityDecrement <= OldPriority));
116
117 /* Set the new priority */
118 Thread->Priority = (SCHAR)OldPriority;
119 }
120
121 /* We need 4 quanta, make sure we have them, then decrease by one */
122 if (Thread->Quantum < 4) Thread->Quantum = 4;
123 Thread->Quantum--;
124
125 /* Make sure the priority is still valid */
126 ASSERT((Thread->Priority >= 0) && (Thread->Priority <= HIGH_PRIORITY));
127
128 /* Release the lock and clear the adjust reason */
130 Thread->AdjustReason = AdjustNone;
131 }
132 else if (Thread->AdjustReason == AdjustUnwait)
133 {
134 /* Acquire the thread lock and check if this is a real-time thread */
136 if (Thread->Priority < LOW_REALTIME_PRIORITY)
137 {
138 /* It's not real time, but is it time critical? */
139 if (Thread->BasePriority >= (LOW_REALTIME_PRIORITY - 2))
140 {
141 /* It is, so simply reset its quantum */
142 Thread->Quantum = Thread->QuantumReset;
143 }
144 else
145 {
146 /* Has the priority been adjusted previously? */
147 if (!(Thread->PriorityDecrement) && (Thread->AdjustIncrement))
148 {
149 /* Yes, reset its quantum */
150 Thread->Quantum = Thread->QuantumReset;
151 }
152
153 /* Wait code already handles quantum adjustment during APCs */
154 if (Thread->WaitStatus != STATUS_KERNEL_APC)
155 {
156 /* Decrease the quantum by one and check if we're out */
157 if (--Thread->Quantum <= 0)
158 {
159 /* We are, reset the quantum and get a new priority */
160 Thread->Quantum = Thread->QuantumReset;
161 Thread->Priority = KiComputeNewPriority(Thread, 1);
162 }
163 }
164 }
165
166 /* Now check if we have no decrement and boosts are enabled */
167 if (!(Thread->PriorityDecrement) && !(Thread->DisableBoost))
168 {
169 /* Make sure we have an increment */
170 ASSERT(Thread->AdjustIncrement >= 0);
171
172 /* Calculate the new priority after the increment */
173 OldPriority = Thread->BasePriority + Thread->AdjustIncrement;
174
175 /* Check if this is a foreground process */
176 if (CONTAINING_RECORD(Thread->ApcState.Process, EPROCESS, Pcb)->
177 Vm.Flags.MemoryPriority == MEMORY_PRIORITY_FOREGROUND)
178 {
179 /* Apply the foreground boost */
180 OldPriority += PsPrioritySeparation;
181 }
182
183 /* Check if this new priority is higher */
184 if (OldPriority > Thread->Priority)
185 {
186 /* Make sure we don't go into the real time range */
187 if (OldPriority >= LOW_REALTIME_PRIORITY)
188 {
189 /* Normalize it back down one notch */
190 OldPriority = LOW_REALTIME_PRIORITY - 1;
191 }
192
193 /* Check if the priority is higher then the boosted base */
194 if (OldPriority > (Thread->BasePriority +
195 Thread->AdjustIncrement))
196 {
197 /* Setup a priority decrement to nullify the boost */
198 Thread->PriorityDecrement = ((SCHAR)OldPriority -
199 Thread->BasePriority -
200 Thread->AdjustIncrement);
201 }
202
203 /* Make sure that the priority decrement is valid */
204 ASSERT((Thread->PriorityDecrement >= 0) &&
205 (Thread->PriorityDecrement <= OldPriority));
206
207 /* Set this new priority */
208 Thread->Priority = (SCHAR)OldPriority;
209 }
210 }
211 }
212 else
213 {
214 /* It's a real-time thread, so just reset its quantum */
215 Thread->Quantum = Thread->QuantumReset;
216 }
217
218 /* Make sure the priority makes sense */
219 ASSERT((Thread->Priority >= 0) && (Thread->Priority <= HIGH_PRIORITY));
220
221 /* Release the thread lock and reset the adjust reason */
223 Thread->AdjustReason = AdjustNone;
224 }
225
226 /* Clear thread preemption status and save current values */
227 Preempted = Thread->Preempted;
228 OldPriority = Thread->Priority;
229 Thread->Preempted = FALSE;
230
231 /* Queue the thread on CPU 0 and get the PRCB and lock it */
232 Thread->NextProcessor = 0;
233 Prcb = KiProcessorBlock[0];
234 KiAcquirePrcbLock(Prcb);
235
236 /* Check if we have an idle summary */
237 if (KiIdleSummary)
238 {
239 /* Clear it and set this thread as the next one */
240 KiIdleSummary = 0;
241 Thread->State = Standby;
242 Prcb->NextThread = Thread;
243
244 /* Unlock the PRCB and return */
245 KiReleasePrcbLock(Prcb);
246 return;
247 }
248
249 /* Set the CPU number */
250 Thread->NextProcessor = (UCHAR)Processor;
251
252 /* Get the next scheduled thread */
253 NextThread = Prcb->NextThread;
254 if (NextThread)
255 {
256 /* Sanity check */
257 ASSERT(NextThread->State == Standby);
258
259 /* Check if priority changed */
260 if (OldPriority > NextThread->Priority)
261 {
262 /* Preempt the thread */
263 NextThread->Preempted = TRUE;
264
265 /* Put this one as the next one */
266 Thread->State = Standby;
267 Prcb->NextThread = Thread;
268
269 /* Set it in deferred ready mode */
270 NextThread->State = DeferredReady;
271 NextThread->DeferredProcessor = Prcb->Number;
272 KiReleasePrcbLock(Prcb);
273 KiDeferredReadyThread(NextThread);
274 return;
275 }
276 }
277 else
278 {
279 /* Set the next thread as the current thread */
280 NextThread = Prcb->CurrentThread;
281 if (OldPriority > NextThread->Priority)
282 {
283 /* Preempt it if it's already running */
284 if (NextThread->State == Running) NextThread->Preempted = TRUE;
285
286 /* Set the thread on standby and as the next thread */
287 Thread->State = Standby;
288 Prcb->NextThread = Thread;
289
290 /* Release the lock */
291 KiReleasePrcbLock(Prcb);
292
293 /* Check if we're running on another CPU */
294 if (KeGetCurrentProcessorNumber() != Thread->NextProcessor)
295 {
296 /* We are, send an IPI */
297 KiIpiSend(AFFINITY_MASK(Thread->NextProcessor), IPI_DPC);
298 }
299 return;
300 }
301 }
302
303 /* Sanity check */
304 ASSERT((OldPriority >= 0) && (OldPriority <= HIGH_PRIORITY));
305
306 /* Set this thread as ready */
307 Thread->State = Ready;
308 Thread->WaitTime = KeTickCount.LowPart;
309
310 /* Insert this thread in the appropriate order */
311 Preempted ? InsertHeadList(&Prcb->DispatcherReadyListHead[OldPriority],
312 &Thread->WaitListEntry) :
313 InsertTailList(&Prcb->DispatcherReadyListHead[OldPriority],
314 &Thread->WaitListEntry);
315
316 /* Update the ready summary */
317 Prcb->ReadySummary |= PRIORITY_MASK(OldPriority);
318
319 /* Sanity check */
320 ASSERT(OldPriority == Thread->Priority);
321
322 /* Release the lock */
323 KiReleasePrcbLock(Prcb);
324}
325
329{
331
332 /* Select a ready thread */
333 Thread = KiSelectReadyThread(0, Prcb);
334 if (!Thread)
335 {
336 /* Didn't find any, get the current idle thread */
337 Thread = Prcb->IdleThread;
338
339 /* Enable idle scheduling */
340 InterlockedOrSetMember(&KiIdleSummary, Prcb->SetMember);
341 Prcb->IdleSchedule = TRUE;
342
343 /* FIXME: SMT support */
344 ASSERTMSG("SMP: Not yet implemented\n", FALSE);
345 }
346
347 /* Sanity checks and return the thread */
348 ASSERT(Thread != NULL);
349 ASSERT((Thread->BasePriority == 0) || (Thread->Priority != 0));
350 return Thread;
351}
352
356 IN PKPRCB Prcb)
357{
359 KIRQL WaitIrql;
360 LONG_PTR WaitStatus;
361 PKTHREAD NextThread;
363
364 /* Acquire the PRCB lock */
365 KiAcquirePrcbLock(Prcb);
366
367 /* Get the next thread */
368 NextThread = Prcb->NextThread;
369 if (NextThread)
370 {
371 /* Already got a thread, set it up */
372 Prcb->NextThread = NULL;
373 Prcb->CurrentThread = NextThread;
374 NextThread->State = Running;
375 }
376 else
377 {
378 /* Try to find a ready thread */
379 NextThread = KiSelectReadyThread(0, Prcb);
380 if (NextThread)
381 {
382 /* Switch to it */
383 Prcb->CurrentThread = NextThread;
384 NextThread->State = Running;
385 }
386 else
387 {
388 /* Set the idle summary */
389 InterlockedOrSetMember(&KiIdleSummary, Prcb->SetMember);
390
391 /* Schedule the idle thread */
392 NextThread = Prcb->IdleThread;
393 Prcb->CurrentThread = NextThread;
394 NextThread->State = Running;
395 }
396 }
397
398 /* Sanity check and release the PRCB */
399 ASSERT(CurrentThread != Prcb->IdleThread);
400 KiReleasePrcbLock(Prcb);
401
402 /* Save the wait IRQL */
403 WaitIrql = CurrentThread->WaitIrql;
404
405 /* Swap contexts */
406 ApcState = KiSwapContext(WaitIrql, CurrentThread);
407
408 /* Get the wait status */
409 WaitStatus = CurrentThread->WaitStatus;
410
411 /* Check if we need to deliver APCs */
412 if (ApcState)
413 {
414 /* Lower to APC_LEVEL */
416
417 /* Deliver APCs */
419 ASSERT(WaitIrql == 0);
420 }
421
422 /* Lower IRQL back to what it was and return the wait status */
423 KeLowerIrql(WaitIrql);
424 return WaitStatus;
425}
426
427VOID
428NTAPI
430{
431 IN PKPROCESS Process = Thread->ApcState.Process;
432
433 /* Check if the process is paged out */
434 if (Process->State != ProcessInMemory)
435 {
436 /* We don't page out processes in ROS */
437 ASSERT(FALSE);
438 }
439 else if (!Thread->KernelStackResident)
440 {
441 /* Increase the stack count */
442 ASSERT(Process->StackCount != MAXULONG_PTR);
443 Process->StackCount++;
444
445 /* Set the thread to transition */
446 ASSERT(Thread->State != Transition);
447 Thread->State = Transition;
448
449 /* The stack is always resident in ROS */
450 ASSERT(FALSE);
451 }
452 else
453 {
454 /* Insert the thread on the deferred ready list */
456 }
457}
458
459VOID
460NTAPI
462{
463 PKPRCB Prcb = KeGetCurrentPrcb();
464 PKTHREAD NextThread;
465
466 /* Acquire thread and PRCB lock */
468 KiAcquirePrcbLock(Prcb);
469
470 /* Don't adjust for RT threads */
471 if ((Thread->Priority < LOW_REALTIME_PRIORITY) &&
472 (Thread->BasePriority < (LOW_REALTIME_PRIORITY - 2)))
473 {
474 /* Decrease Quantum by one and see if we've ran out */
475 if (--Thread->Quantum <= 0)
476 {
477 /* Return quantum */
478 Thread->Quantum = Thread->QuantumReset;
479
480 /* Calculate new Priority */
481 Thread->Priority = KiComputeNewPriority(Thread, 1);
482
483 /* Check if there's no next thread scheduled */
484 if (!Prcb->NextThread)
485 {
486 /* Select a ready thread and check if we found one */
487 NextThread = KiSelectReadyThread(Thread->Priority, Prcb);
488 if (NextThread)
489 {
490 /* Set it on standby and switch to it */
491 NextThread->State = Standby;
492 Prcb->NextThread = NextThread;
493 }
494 }
495 else
496 {
497 /* This thread can be preempted again */
498 Thread->Preempted = FALSE;
499 }
500 }
501 }
502
503 /* Release locks */
504 KiReleasePrcbLock(Prcb);
506 KiExitDispatcher(Thread->WaitIrql);
507}
508
509VOID
513{
514 PKPRCB Prcb;
516 BOOLEAN RequestInterrupt = FALSE;
517 KPRIORITY OldPriority;
518 PKTHREAD NewThread;
519 ASSERT((Priority >= 0) && (Priority <= HIGH_PRIORITY));
520
521 /* Check if priority changed */
522 if (Thread->Priority != Priority)
523 {
524 /* Loop priority setting in case we need to start over */
525 for (;;)
526 {
527 /* Choose action based on thread's state */
528 if (Thread->State == Ready)
529 {
530 /* Make sure we're not on the ready queue */
531 if (!Thread->ProcessReadyQueue)
532 {
533 /* Get the PRCB for the thread and lock it */
534 Processor = Thread->NextProcessor;
536 KiAcquirePrcbLock(Prcb);
537
538 /* Make sure the thread is still ready and on this CPU */
539 if ((Thread->State == Ready) &&
540 (Thread->NextProcessor == Prcb->Number))
541 {
542 /* Sanity check */
543 ASSERT((Prcb->ReadySummary &
544 PRIORITY_MASK(Thread->Priority)));
545
546 /* Remove it from the current queue */
547 if (RemoveEntryList(&Thread->WaitListEntry))
548 {
549 /* Update the ready summary */
551 Priority);
552 }
553
554 /* Update priority */
555 Thread->Priority = (SCHAR)Priority;
556
557 /* Re-insert it at its current priority */
559
560 /* Release the PRCB Lock */
561 KiReleasePrcbLock(Prcb);
562 }
563 else
564 {
565 /* Release the lock and loop again */
566 KiReleasePrcbLock(Prcb);
567 continue;
568 }
569 }
570 else
571 {
572 /* It's already on the ready queue, just update priority */
573 Thread->Priority = (SCHAR)Priority;
574 }
575 }
576 else if (Thread->State == Standby)
577 {
578 /* Get the PRCB for the thread and lock it */
579 Processor = Thread->NextProcessor;
581 KiAcquirePrcbLock(Prcb);
582
583 /* Check if we're still the next thread to run */
584 if (Thread == Prcb->NextThread)
585 {
586 /* Get the old priority and update ours */
587 OldPriority = Thread->Priority;
588 Thread->Priority = (SCHAR)Priority;
589
590 /* Check if there was a change */
591 if (Priority < OldPriority)
592 {
593 /* Find a new thread */
594 NewThread = KiSelectReadyThread(Priority + 1, Prcb);
595 if (NewThread)
596 {
597 /* Found a new one, set it on standby */
598 NewThread->State = Standby;
599 Prcb->NextThread = NewThread;
600
601 /* Dispatch our thread */
603 }
604 }
605
606 /* Release the PRCB lock */
607 KiReleasePrcbLock(Prcb);
608 }
609 else
610 {
611 /* Release the lock and try again */
612 KiReleasePrcbLock(Prcb);
613 continue;
614 }
615 }
616 else if (Thread->State == Running)
617 {
618 /* Get the PRCB for the thread and lock it */
619 Processor = Thread->NextProcessor;
621 KiAcquirePrcbLock(Prcb);
622
623 /* Check if we're still the current thread running */
624 if (Thread == Prcb->CurrentThread)
625 {
626 /* Get the old priority and update ours */
627 OldPriority = Thread->Priority;
628 Thread->Priority = (SCHAR)Priority;
629
630 /* Check if there was a change and there's no new thread */
631 if ((Priority < OldPriority) && !(Prcb->NextThread))
632 {
633 /* Find a new thread */
634 NewThread = KiSelectReadyThread(Priority + 1, Prcb);
635 if (NewThread)
636 {
637 /* Found a new one, set it on standby */
638 NewThread->State = Standby;
639 Prcb->NextThread = NewThread;
640
641 /* Request an interrupt */
642 RequestInterrupt = TRUE;
643 }
644 }
645
646 /* Release the lock and check if we need an interrupt */
647 KiReleasePrcbLock(Prcb);
648 if (RequestInterrupt)
649 {
650 /* Check if we're running on another CPU */
652 {
653 /* We are, send an IPI */
655 }
656 }
657 }
658 else
659 {
660 /* Thread changed, release lock and restart */
661 KiReleasePrcbLock(Prcb);
662 continue;
663 }
664 }
665 else if (Thread->State == DeferredReady)
666 {
667 /* FIXME: TODO */
668 DPRINT1("Deferred state not yet supported\n");
669 ASSERT(FALSE);
670 }
671 else
672 {
673 /* Any other state, just change priority */
674 Thread->Priority = (SCHAR)Priority;
675 }
676
677 /* If we got here, then thread state was consistent, so bail out */
678 break;
679 }
680 }
681}
682
687{
688 KAFFINITY OldAffinity;
689
690 /* Get the current affinity */
691 OldAffinity = Thread->UserAffinity;
692
693 /* Make sure that the affinity is valid */
694 if (((Affinity & Thread->ApcState.Process->Affinity) != (Affinity)) ||
695 (!Affinity))
696 {
697 /* Bugcheck the system */
698 KeBugCheck(INVALID_AFFINITY_SET);
699 }
700
701 /* Update the new affinity */
702 Thread->UserAffinity = Affinity;
703
704 /* Check if system affinity is disabled */
705 if (!Thread->SystemAffinityActive)
706 {
707#ifdef CONFIG_SMP
708 /* FIXME: TODO */
709 DPRINT1("Affinity support disabled!\n");
710#endif
711 }
712
713 /* Return the old affinity */
714 return OldAffinity;
715}
716
717//
718// This macro exists because NtYieldExecution locklessly attempts to read from
719// the KPRCB's ready summary, and the usual way of going through KeGetCurrentPrcb
720// would require getting fs:1C first (or gs), and then doing another dereference.
721// In an attempt to minimize the amount of instructions and potential race/tear
722// that could happen, Windows seems to define this as a macro that directly acceses
723// the ready summary through a single fs: read by going through the KPCR's PrcbData.
724//
725// See http://research.microsoft.com/en-us/collaboration/global/asia-pacific/
726// programs/trk_case4_process-thread_management.pdf
727//
728// We need this per-arch because sometimes it's Prcb and sometimes PrcbData, and
729// because on x86 it's FS, and on x64 it's GS (not sure what it is on ARM/PPC).
730//
731#ifdef _M_IX86
732#define KiGetCurrentReadySummary() __readfsdword(FIELD_OFFSET(KIPCR, PrcbData.ReadySummary))
733#elif _M_AMD64
734#define KiGetCurrentReadySummary() __readgsdword(FIELD_OFFSET(KIPCR, Prcb.ReadySummary))
735#else
736#define KiGetCurrentReadySummary() KeGetCurrentPrcb()->ReadySummary
737#endif
738
739/*
740 * @implemented
741 */
743NTAPI
745{
748 PKPRCB Prcb;
749 PKTHREAD Thread, NextThread;
750
751 /* NB: No instructions (other than entry code) should preceed this line */
752
753 /* Fail if there's no ready summary */
755
756 /* Now get the current thread, set the status... */
759
760 /* Raise IRQL to synch and get the KPRCB now */
762 Prcb = KeGetCurrentPrcb();
763
764 /* Now check if there's still a ready summary */
765 if (Prcb->ReadySummary)
766 {
767 /* Acquire thread and PRCB lock */
769 KiAcquirePrcbLock(Prcb);
770
771 /* Find a new thread to run if none was selected */
772 if (!Prcb->NextThread) Prcb->NextThread = KiSelectReadyThread(1, Prcb);
773
774 /* Make sure we still have a next thread to schedule */
775 NextThread = Prcb->NextThread;
776 if (NextThread)
777 {
778 /* Reset quantum and recalculate priority */
779 Thread->Quantum = Thread->QuantumReset;
780 Thread->Priority = KiComputeNewPriority(Thread, 1);
781
782 /* Release the thread lock */
784
785 /* Set context swap busy */
787
788 /* Set the new thread as running */
789 Prcb->NextThread = NULL;
790 Prcb->CurrentThread = NextThread;
791 NextThread->State = Running;
792
793 /* Setup a yield wait and queue the thread */
794 Thread->WaitReason = WrYieldExecution;
795 KxQueueReadyThread(Thread, Prcb);
796
797 /* Make it wait at APC_LEVEL */
798 Thread->WaitIrql = APC_LEVEL;
799
800 /* Sanity check */
802
803 /* Swap to new thread */
806 }
807 else
808 {
809 /* Release the PRCB and thread lock */
810 KiReleasePrcbLock(Prcb);
812 }
813 }
814
815 /* Lower IRQL and return */
817 return Status;
818}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define MAXULONG_PTR
Definition: basetsd.h:103
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1430
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG_PTR KAFFINITY
Definition: compat.h:85
LONG KPRIORITY
Definition: compat.h:803
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_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
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: pic.c:156
#define KeGetCurrentThread
Definition: hal.h:55
#define MEMORY_PRIORITY_FOREGROUND
Definition: pstypes.h:126
NTSYSAPI NTSTATUS WINAPI NtYieldExecution(void)
Definition: thrdschd.c:744
#define LOW_REALTIME_PRIORITY
#define HIGH_PRIORITY
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
FORCEINLINE PKTHREAD KiSelectReadyThread(IN KPRIORITY Priority, IN PKPRCB Prcb)
Definition: ke_x.h:1422
FORCEINLINE VOID KiSetThreadSwapBusy(IN PKTHREAD Thread)
Definition: ke_x.h:210
FORCEINLINE VOID KiReleasePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:230
FORCEINLINE VOID KiAcquireThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:240
FORCEINLINE VOID KiInsertDeferredReadyList(IN PKTHREAD Thread)
Definition: ke_x.h:185
FORCEINLINE VOID KiReleaseThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:250
FORCEINLINE VOID KiAcquirePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:220
FORCEINLINE SCHAR KiComputeNewPriority(IN PKTHREAD Thread, IN SCHAR Adjustment)
Definition: ke_x.h:1472
#define ASSERT(a)
Definition: mode.c:44
#define min(a, b)
Definition: monoChain.cc:55
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define KernelMode
Definition: asm.h:34
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1161
#define IPI_DPC
Definition: ketypes.h:298
FORCEINLINE KAFFINITY AFFINITY_MASK(ULONG Index)
Definition: kefuncs.h:39
@ ProcessInMemory
Definition: ketypes.h:460
@ Ready
Definition: ketypes.h:389
@ Running
Definition: ketypes.h:390
@ Standby
Definition: ketypes.h:391
@ DeferredReady
Definition: ketypes.h:395
@ Transition
Definition: ketypes.h:394
@ AdjustUnwait
Definition: ketypes.h:440
@ AdjustNone
Definition: ketypes.h:439
@ AdjustBoost
Definition: ketypes.h:441
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define FASTCALL
Definition: nt_native.h:50
NTKERNELAPI volatile KSYSTEM_TIME KeTickCount
Definition: clock.c:19
#define PRIORITY_MASK(Priority)
Definition: ke.h:158
PKPRCB KiProcessorBlock[]
Definition: krnlinit.c:32
BOOLEAN FASTCALL KiSwapContext(IN KIRQL WaitIrql, IN PKTHREAD CurrentThread)
VOID FASTCALL KiIpiSend(KAFFINITY TargetSet, ULONG IpiRequest)
VOID FASTCALL KiExitDispatcher(KIRQL OldIrql)
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
VOID NTAPI KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: apc.c:302
#define STATUS_KERNEL_APC
Definition: ntstatus.h:79
#define STATUS_NO_YIELD_PERFORMED
Definition: ntstatus.h:150
ULONG PsPrioritySeparation
Definition: process.c:28
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:341
#define STATUS_SUCCESS
Definition: shellext.h:65
signed char SCHAR
Definition: sqltypes.h:14
struct _KTHREAD * CurrentThread
Definition: ketypes.h:650
struct _KTHREAD * NextThread
Definition: ketypes.h:651
USHORT Number
Definition: ketypes.h:643
ULONG ReadySummary
Definition: ketypes.h:810
LIST_ENTRY DispatcherReadyListHead[32]
Definition: ketypes.h:815
ULONG LowPart
Definition: ketypes.h:929
SCHAR Priority
Definition: ketypes.h:1782
ULONG DeferredProcessor
Definition: ketypes.h:1906
UCHAR Preempted
Definition: ketypes.h:1927
volatile UCHAR State
Definition: ketypes.h:1789
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
VOID NTAPI KiReadyThread(IN PKTHREAD Thread)
Definition: thrdschd.c:429
LONG_PTR FASTCALL KiSwapThread(IN PKTHREAD CurrentThread, IN PKPRCB Prcb)
Definition: thrdschd.c:355
PKTHREAD FASTCALL KiIdleSchedule(IN PKPRCB Prcb)
Definition: thrdschd.c:32
#define KiGetCurrentReadySummary()
Definition: thrdschd.c:736
VOID FASTCALL KiQueueReadyThread(IN PKTHREAD Thread, IN PKPRCB Prcb)
Definition: thrdschd.c:70
KAFFINITY KiIdleSummary
Definition: thrdschd.c:25
VOID NTAPI KiAdjustQuantumThread(IN PKTHREAD Thread)
Definition: thrdschd.c:461
KAFFINITY FASTCALL KiSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdschd.c:685
VOID FASTCALL KiProcessDeferredReadyList(IN PKPRCB Prcb)
Definition: thrdschd.c:41
VOID FASTCALL KiDeferredReadyThread(IN PKTHREAD Thread)
Definition: thrdschd.c:79
KAFFINITY KiIdleSMTSummary
Definition: thrdschd.c:26
PKTHREAD FASTCALL KiSelectNextThread(IN PKPRCB Prcb)
Definition: thrdschd.c:328
VOID FASTCALL KiSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdschd.c:511
#define InterlockedOrSetMember(Destination, SetMember)
Definition: thrdschd.c:19
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
_In_ UCHAR Processor
Definition: kefuncs.h:670
@ WrYieldExecution
Definition: ketypes.h:448
unsigned char UCHAR
Definition: xmlstorage.h:181