ReactOS  0.4.14-dev-608-gd495a4f
thrdobj.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ke/thrdobj.c
5  * PURPOSE: Implements routines to manage the Kernel Thread Object
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
17 
19 {
20  0x1, 0x2, 0x4, 0x8, 0x10, 0x20,
21  0x40, 0x80, 0x100, 0x200, 0x400, 0x800,
22  0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000,
23  0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000,
24  0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000,
25  0x40000000, 0x80000000
26 };
27 
28 /* FUNCTIONS *****************************************************************/
29 
30 UCHAR
31 NTAPI
33  IN ULONG Set)
34 {
35  ULONG Bit, Result;
36  ASSERT(Set != 0);
37 
38  /* Calculate the mask */
39  Bit = (AFFINITY_MASK(Number) - 1) & Set;
40 
41  /* If it's 0, use the one we got */
42  if (!Bit) Bit = Set;
43 
44  /* Now find the right set and return it */
45  BitScanReverse(&Result, Bit);
46  return (UCHAR)Result;
47 }
48 
49 BOOLEAN
50 NTAPI
52 {
54 
55  /* Return signal state */
56  return (BOOLEAN)Thread->Header.SignalState;
57 }
58 
60 NTAPI
62 {
63  LONG BaseIncrement;
64  KIRQL OldIrql;
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 
93 BOOLEAN
94 NTAPI
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 
113 VOID
114 NTAPI
116 {
117  KIRQL OldIrql;
120 
121  /* Lock the Dispatcher Database */
123 
124  /* Make the thread ready */
126 
127  /* Unlock dispatcher database */
129 }
130 
131 ULONG
132 NTAPI
134 {
135  ULONG PreviousCount;
136  KLOCK_QUEUE_HANDLE ApcLock;
139 
140  /* Lock the Dispatcher Database and the APC Queue */
141  KiAcquireApcLock(Thread, &ApcLock);
143 
144  /* Return if Thread is already alerted. */
145  if (!Thread->Alerted[KernelMode])
146  {
147  /* If it's Blocked, unblock if it we should */
148  if ((Thread->State == Waiting) && (Thread->Alertable))
149  {
150  /* Abort the wait */
152  }
153  else
154  {
155  /* If not, simply Alert it */
156  Thread->Alerted[KernelMode] = TRUE;
157  }
158  }
159 
160  /* Save the old Suspend Count */
161  PreviousCount = Thread->SuspendCount;
162 
163  /* If the thread is suspended, decrease one of the suspend counts */
164  if (PreviousCount)
165  {
166  /* Decrease count. If we are now zero, unwait it completely */
167  Thread->SuspendCount--;
168  if (!(Thread->SuspendCount) && !(Thread->FreezeCount))
169  {
170  /* Signal and satisfy */
171  Thread->SuspendSemaphore.Header.SignalState++;
172  KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
173  }
174  }
175 
176  /* Release Locks and return the Old State */
179  KiExitDispatcher(ApcLock.OldIrql);
180  return PreviousCount;
181 }
182 
183 BOOLEAN
184 NTAPI
186  IN KPROCESSOR_MODE AlertMode)
187 {
189  KLOCK_QUEUE_HANDLE ApcLock;
192 
193  /* Lock the Dispatcher Database and the APC Queue */
194  KiAcquireApcLock(Thread, &ApcLock);
196 
197  /* Save the Previous State */
198  PreviousState = Thread->Alerted[AlertMode];
199 
200  /* Check if it's already alerted */
201  if (!PreviousState)
202  {
203  /* Check if the thread is alertable, and blocked in the given mode */
204  if ((Thread->State == Waiting) &&
205  (Thread->Alertable) &&
206  (AlertMode <= Thread->WaitMode))
207  {
208  /* Abort the wait to alert the thread */
210  }
211  else
212  {
213  /* Otherwise, merely set the alerted state */
214  Thread->Alerted[AlertMode] = TRUE;
215  }
216  }
217 
218  /* Release the Dispatcher Lock */
221  KiExitDispatcher(ApcLock.OldIrql);
222 
223  /* Return the old state */
224  return PreviousState;
225 }
226 
227 VOID
228 NTAPI
231 {
232  KIRQL OldIrql;
235 
236  /* Lock the Dispatcher Database */
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 
274 ULONG
275 NTAPI
277 {
278  KLOCK_QUEUE_HANDLE ApcLock;
279  ULONG PreviousCount;
282 
283  /* Lock the APC Queue */
284  KiAcquireApcLock(Thread, &ApcLock);
285 
286  /* Save the old Suspend Count */
287  PreviousCount = Thread->SuspendCount + Thread->FreezeCount;
288 
289  /* If the thread is suspended, wake it up!!! */
290  if (PreviousCount)
291  {
292  /* Unwait it completely */
293  Thread->SuspendCount = 0;
294  Thread->FreezeCount = 0;
295 
296  /* Lock the dispatcher */
298 
299  /* Signal and satisfy */
300  Thread->SuspendSemaphore.Header.SignalState++;
301  KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
302 
303  /* Release the dispatcher */
305  }
306 
307  /* Release Lock and return the Old State */
309  KiExitDispatcher(ApcLock.OldIrql);
310  return PreviousCount;
311 }
312 
313 VOID
314 NTAPI
316 {
318  PKTHREAD Current, CurrentThread = KeGetCurrentThread();
319  PKPROCESS Process = CurrentThread->ApcState.Process;
320  PLIST_ENTRY ListHead, NextEntry;
321  LONG OldCount;
323 
324  /* Lock the process */
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  KiAcquireApcLockAtDpcLevel(Current, &ApcLock);
348 
349  /* Make sure it's not ours, and check if APCs are enabled */
350  if ((Current != CurrentThread) && (Current->ApcQueueable))
351  {
352  /* Sanity check */
353  OldCount = Current->SuspendCount;
354  ASSERT(OldCount != MAXIMUM_SUSPEND_COUNT);
355 
356  /* Increase the freeze count */
357  Current->FreezeCount++;
358 
359  /* Make sure it wasn't already suspended */
360  if (!(OldCount) && !(Current->SuspendCount))
361  {
362  /* Did we already insert it? */
363  if (!Current->SuspendApc.Inserted)
364  {
365  /* Insert the APC */
366  Current->SuspendApc.Inserted = TRUE;
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 
395 ULONG
396 NTAPI
398 {
399  KLOCK_QUEUE_HANDLE ApcLock;
400  ULONG PreviousCount;
403 
404  /* Lock the APC Queue */
405  KiAcquireApcLock(Thread, &ApcLock);
406 
407  /* Save the Old Count */
408  PreviousCount = Thread->SuspendCount;
409 
410  /* Check if it existed */
411  if (PreviousCount)
412  {
413  /* Decrease the suspend count */
414  Thread->SuspendCount--;
415 
416  /* Check if the thrad is still suspended or not */
417  if ((!Thread->SuspendCount) && (!Thread->FreezeCount))
418  {
419  /* Acquire the dispatcher lock */
421 
422  /* Signal the Suspend Semaphore */
423  Thread->SuspendSemaphore.Header.SignalState++;
424  KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
425 
426  /* Release the dispatcher lock */
428  }
429  }
430 
431  /* Release APC Queue lock and return the Old State */
433  KiExitDispatcher(ApcLock.OldIrql);
434  return PreviousCount;
435 }
436 
437 VOID
438 NTAPI
440 {
441  KIRQL OldIrql;
443  PLIST_ENTRY NextEntry, ListHead;
444  PKMUTANT Mutant;
446 
447  /* Optimized path if nothing is on the list at the moment */
448  if (IsListEmpty(&Thread->MutantListHead)) return;
449 
450  /* Lock the Dispatcher Database */
452 
453  /* Get the List Pointers */
454  ListHead = &Thread->MutantListHead;
455  NextEntry = ListHead->Flink;
456  while (NextEntry != ListHead)
457  {
458  /* Get the Mutant */
459  Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry);
460  ASSERT_MUTANT(Mutant);
461 
462  /* Make sure it's not terminating with APCs off */
463  if (Mutant->ApcDisable)
464  {
465  /* Bugcheck the system */
466  KeBugCheckEx(THREAD_TERMINATE_HELD_MUTEX,
467  (ULONG_PTR)Thread,
468  (ULONG_PTR)Mutant,
469  0,
470  0);
471  }
472 
473  /* Now we can remove it */
475 
476  /* Unconditionally abandon it */
477  Mutant->Header.SignalState = 1;
478  Mutant->Abandoned = TRUE;
479  Mutant->OwnerThread = NULL;
480 
481  /* Check if the Wait List isn't empty */
482  if (!IsListEmpty(&Mutant->Header.WaitListHead))
483  {
484  /* Wake the Mutant */
486  }
487 
488  /* Move on */
489  NextEntry = Thread->MutantListHead.Flink;
490  }
491 
492  /* Release the Lock */
494 }
495 
496 VOID
497 NTAPI
499 {
501 #ifdef CONFIG_SMP
502  PKNODE Node;
503  PKPRCB NodePrcb;
504  ULONG Set, Mask;
505 #endif
506  UCHAR IdealProcessor = 0;
507  PKPROCESS Process = Thread->ApcState.Process;
508 
509  /* Setup static fields from parent */
510  Thread->DisableBoost = Process->DisableBoost;
511 #if defined(_M_IX86)
512  Thread->Iopl = Process->Iopl;
513 #endif
514  Thread->Quantum = Process->QuantumReset;
515  Thread->QuantumReset = Process->QuantumReset;
516  Thread->SystemAffinityActive = FALSE;
517 
518  /* Lock the process */
520 
521  /* Setup volatile data */
522  Thread->Priority = Process->BasePriority;
523  Thread->BasePriority = Process->BasePriority;
524  Thread->Affinity = Process->Affinity;
525  Thread->UserAffinity = Process->Affinity;
526 
527 #ifdef CONFIG_SMP
528  /* Get the KNODE and its PRCB */
529  Node = KeNodeBlock[Process->IdealNode];
530  NodePrcb = KiProcessorBlock[Process->ThreadSeed];
531 
532  /* Calculate affinity mask */
533 #ifdef _M_ARM
534  DbgBreakPoint();
535  Set = 0;
536 #else
537  Set = ~NodePrcb->MultiThreadProcessorSet;
538 #endif
539  Mask = (ULONG)(Node->ProcessorMask & Process->Affinity);
540  Set &= Mask;
541  if (Set) Mask = Set;
542 
543  /* Get the new thread seed */
544  IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask);
545  Process->ThreadSeed = IdealProcessor;
546 
547  /* Sanity check */
548  ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor)));
549 #endif
550 
551  /* Set the Ideal Processor */
552  Thread->IdealProcessor = IdealProcessor;
553  Thread->UserIdealProcessor = IdealProcessor;
554 
555  /* Lock the Dispatcher Database */
557 
558  /* Insert the thread into the process list */
559  InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
560 
561  /* Increase the stack count */
562  ASSERT(Process->StackCount != MAXULONG_PTR);
563  Process->StackCount++;
564 
565  /* Release locks and return */
568 }
569 
570 VOID
571 NTAPI
573 {
574  /* Does nothing */
576 }
577 
578 VOID
579 NTAPI
581  IN PKNORMAL_ROUTINE *NormalRoutine,
582  IN PVOID *NormalContext,
585 {
586  /* Does nothing */
588  UNREFERENCED_PARAMETER(NormalRoutine);
589  UNREFERENCED_PARAMETER(NormalContext);
592 }
593 
594 VOID
595 NTAPI
596 KiSuspendThread(IN PVOID NormalContext,
599 {
600  /* Non-alertable kernel-mode suspended wait */
601  KeWaitForSingleObject(&KeGetCurrentThread()->SuspendSemaphore,
602  Suspended,
603  KernelMode,
604  FALSE,
605  NULL);
606 }
607 
608 ULONG
609 NTAPI
611 {
612  KLOCK_QUEUE_HANDLE ApcLock;
613  ULONG PreviousCount;
616 
617  /* Lock the APC Queue */
618  KiAcquireApcLock(Thread, &ApcLock);
619 
620  /* Save the Old Count */
621  PreviousCount = Thread->SuspendCount;
622 
623  /* Handle the maximum */
624  if (PreviousCount == MAXIMUM_SUSPEND_COUNT)
625  {
626  /* Raise an exception */
627  KiReleaseApcLock(&ApcLock);
629  }
630 
631  /* Should we bother to queue at all? */
632  if (Thread->ApcQueueable)
633  {
634  /* Increment the suspend count */
635  Thread->SuspendCount++;
636 
637  /* Check if we should suspend it */
638  if (!(PreviousCount) && !(Thread->FreezeCount))
639  {
640  /* Is the APC already inserted? */
641  if (!Thread->SuspendApc.Inserted)
642  {
643  /* Not inserted, insert it */
644  Thread->SuspendApc.Inserted = TRUE;
645  KiInsertQueueApc(&Thread->SuspendApc, IO_NO_INCREMENT);
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 
667 VOID
668 NTAPI
670 {
672  PKTHREAD Current, CurrentThread = KeGetCurrentThread();
673  PKPROCESS Process = CurrentThread->ApcState.Process;
674  PLIST_ENTRY ListHead, NextEntry;
675  LONG OldCount;
677 
678  /* Lock the process */
680 
681  /* Loop the Process's Threads */
682  ListHead = &Process->ThreadListHead;
683  NextEntry = ListHead->Flink;
684  do
685  {
686  /* Get the current thread */
687  Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
688 
689  /* Lock it */
690  KiAcquireApcLockAtDpcLevel(Current, &ApcLock);
691 
692  /* Make sure we are frozen */
693  OldCount = Current->FreezeCount;
694  if (OldCount)
695  {
696  /* Decrease the freeze count */
697  Current->FreezeCount--;
698 
699  /* Check if both counts are zero now */
700  if (!(Current->SuspendCount) && (!Current->FreezeCount))
701  {
702  /* Lock the dispatcher */
704 
705  /* Signal the suspend semaphore and wake it */
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 
729 BOOLEAN
730 NTAPI
732 {
734  BOOLEAN OldState;
735  KLOCK_QUEUE_HANDLE ApcLock;
738 
739  /* Lock the Dispatcher Database and the APC Queue */
740  KiAcquireApcLock(Thread, &ApcLock);
741 
742  /* Save the old State */
743  OldState = Thread->Alerted[AlertMode];
744 
745  /* Check the Thread is alerted */
746  if (OldState)
747  {
748  /* Disable alert for this mode */
749  Thread->Alerted[AlertMode] = FALSE;
750  }
751  else if ((AlertMode != KernelMode) &&
752  (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
753  {
754  /* If the mode is User and the Queue isn't empty, set Pending */
755  Thread->ApcState.UserApcPending = TRUE;
756  }
757 
758  /* Release Locks and return the Old State */
759  KiReleaseApcLock(&ApcLock);
760  return OldState;
761 }
762 
763 NTSTATUS
764 NTAPI
766  IN PVOID KernelStack,
767  IN PKSYSTEM_ROUTINE SystemRoutine,
769  IN PVOID StartContext,
771  IN PVOID Teb,
773 {
774  BOOLEAN AllocatedStack = FALSE;
775  ULONG i;
776  PKWAIT_BLOCK TimerWaitBlock;
777  PKTIMER Timer;
779 
780  /* Initialize the Dispatcher Header */
781  Thread->Header.Type = ThreadObject;
782  Thread->Header.ThreadControlFlags = 0;
783  Thread->Header.DebugActive = FALSE;
784  Thread->Header.SignalState = 0;
785  InitializeListHead(&(Thread->Header.WaitListHead));
786 
787  /* Initialize the Mutant List */
788  InitializeListHead(&Thread->MutantListHead);
789 
790  /* Initialize the wait blocks */
791  for (i = 0; i< (THREAD_WAIT_OBJECTS + 1); i++)
792  {
793  /* Put our pointer */
794  Thread->WaitBlock[i].Thread = Thread;
795  }
796 
797  /* Set swap settings */
798  Thread->EnableStackSwap = TRUE;
799  Thread->IdealProcessor = 1;
800  Thread->SwapBusy = FALSE;
801  Thread->KernelStackResident = TRUE;
802  Thread->AdjustReason = AdjustNone;
803 
804  /* Initialize the lock */
806 
807  /* Setup the Service Descriptor Table for Native Calls */
808  Thread->ServiceTable = KeServiceDescriptorTable;
809 
810  /* Setup APC Fields */
811  InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
812  InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
813  Thread->ApcState.Process = Process;
814  Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
815  Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
816  Thread->ApcStateIndex = OriginalApcEnvironment;
817  Thread->ApcQueueable = TRUE;
818  KeInitializeSpinLock(&Thread->ApcQueueLock);
819 
820  /* Initialize the Suspend APC */
821  KeInitializeApc(&Thread->SuspendApc,
822  Thread,
824  KiSuspendNop,
827  KernelMode,
828  NULL);
829 
830  /* Initialize the Suspend Semaphore */
831  KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
832 
833  /* Setup the timer */
834  Timer = &Thread->Timer;
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 */
869  _SEH2_TRY
870  {
871  /* Initialize the Thread Context */
873  SystemRoutine,
874  StartRoutine,
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 */
887  MmDeleteKernelStack((PVOID)Thread->StackBase, FALSE);
888  Thread->InitialStack = NULL;
889  }
890  }
891  _SEH2_END;
892 
893  /* Set the Thread to initialized */
894  Thread->State = Initialized;
895  return Status;
896 }
897 
898 VOID
899 NTAPI
902  IN PKSYSTEM_ROUTINE SystemRoutine,
904  IN PVOID StartContext,
906  IN PVOID Teb,
907  IN PVOID KernelStack)
908 {
909  /* Initialize and start the thread on success */
911  KernelStack,
912  SystemRoutine,
913  StartRoutine,
914  StartContext,
915  Context,
916  Teb,
917  Process)))
918  {
919  /* Start it */
921  }
922 }
923 
924 VOID
925 NTAPI
927 {
928  /* Delete the stack */
929  MmDeleteKernelStack((PVOID)Thread->StackBase, FALSE);
930  Thread->InitialStack = NULL;
931 }
932 
933 /* PUBLIC FUNCTIONS **********************************************************/
934 
935 /*
936  * @unimplemented
937  */
938 VOID
939 NTAPI
941  IN ULONG Setting1,
942  IN ULONG Setting2,
943  IN ULONG Setting3,
944  IN ULONG Setting4,
945  IN ULONG Setting5,
946  IN PVOID ThreadState)
947 {
949 }
950 
951 /*
952  * @implemented
953  */
954 #undef KeGetCurrentThread
955 PKTHREAD
956 NTAPI
958 {
959  /* Return the current thread on this PCR */
960  return _KeGetCurrentThread();
961 }
962 
963 /*
964  * @implemented
965  */
966 #undef KeGetPreviousMode
967 UCHAR
968 NTAPI
970 {
971  /* Return the previous mode of this thread */
972  return _KeGetPreviousMode();
973 }
974 
975 /*
976  * @implemented
977  */
978 ULONG
979 NTAPI
982 {
984 
985  /* Return the User Time */
986  *UserTime = Thread->UserTime;
987 
988  /* Return the Kernel Time */
989  return Thread->KernelTime;
990 }
991 
992 /*
993  * @implemented
994  */
995 BOOLEAN
996 NTAPI
998 {
1001 
1002  /* Save Old State */
1003  PreviousState = Thread->EnableStackSwap;
1004 
1005  /* Set New State */
1006  Thread->EnableStackSwap = Enable;
1007 
1008  /* Return Old State */
1009  return PreviousState;
1010 }
1011 
1012 /*
1013  * @implemented
1014  */
1015 KPRIORITY
1016 NTAPI
1018 {
1020 
1021  /* Return the current priority */
1022  return Thread->Priority;
1023 }
1024 
1025 /*
1026  * @implemented
1027  */
1028 VOID
1029 NTAPI
1031 {
1032  KIRQL OldIrql;
1033  PKPRCB Prcb;
1034  PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
1036  ASSERT(CurrentThread->SystemAffinityActive != FALSE);
1037 
1038  /* Lock the Dispatcher Database */
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  */
1073 UCHAR
1074 NTAPI
1076  IN UCHAR Processor)
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  */
1114 VOID
1115 NTAPI
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  */
1182 LONG
1183 NTAPI
1185  IN LONG Increment)
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  */
1301 KAFFINITY
1302 NTAPI
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  */
1325 KPRIORITY
1326 NTAPI
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  */
1373 VOID
1374 NTAPI
1376 {
1377  PLIST_ENTRY *ListHead;
1378  PETHREAD Entry, SavedEntry;
1379  PETHREAD *ThreadAddr;
1382  PKPROCESS Process = Thread->ApcState.Process;
1384 
1385  /* Lock the process */
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);
1434  KiActivateWaiterQueue(Thread->Queue);
1435  }
1436 
1437  /* Signal the thread */
1438  Thread->Header.SignalState = TRUE;
1439  if (!IsListEmpty(&Thread->Header.WaitListHead))
1440  {
1441  /* Unwait the threads */
1442  KxUnwaitThread(&Thread->Header, Increment);
1443  }
1444 
1445  /* Remove the thread from the list */
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 }
VOID NTAPI KeInitializeApc(IN PKAPC Apc, IN PKTHREAD Thread, IN KAPC_ENVIRONMENT TargetEnvironment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine, IN KPROCESSOR_MODE Mode, IN PVOID Context)
Definition: apc.c:651
#define MAXIMUM_PROCESSORS
Definition: rwlock.h:5
FORCEINLINE VOID KiReleaseThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:244
#define LOW_PRIORITY
ULONG NTAPI KeQueryRuntimeThread(IN PKTHREAD Thread, OUT PULONG UserTime)
Definition: thrdobj.c:980
#define abs(i)
Definition: fconv.c:206
KAFFINITY FASTCALL KiSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdschd.c:685
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
ULONG FreezeCount
Definition: ketypes.h:1627
#define IN
Definition: typedefs.h:38
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
VOID FASTCALL KiUnwaitThread(IN PKTHREAD Thread, IN LONG_PTR WaitStatus, IN KPRIORITY Increment)
Definition: wait.c:89
ULONG NTAPI KeForceResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:276
#define TRUE
Definition: types.h:120
LIST_ENTRY ThreadListEntry
Definition: pstypes.h:1089
ULONG UserIdealProcessor
Definition: ketypes.h:1673
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
LIST_ENTRY List
Definition: extypes.h:203
VOID NTAPI KeStartThread(IN OUT PKTHREAD Thread)
Definition: thrdobj.c:498
UCHAR NTAPI KeFindNextRightSetAffinity(IN UCHAR Number, IN ULONG Set)
Definition: thrdobj.c:32
struct _Entry Entry
Definition: kefuncs.h:640
FORCEINLINE VOID KiReleasePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:224
KAFFINITY NTAPI KeSetAffinityThread(IN PKTHREAD Thread, IN KAFFINITY Affinity)
Definition: thrdobj.c:1303
LIST_ENTRY WaitListEntry
Definition: ketypes.h:444
FORCEINLINE VOID KiReleaseProcessLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:660
_In_ ULONG _In_opt_ POBJECT_ATTRIBUTES _In_opt_ HANDLE _Out_opt_ PCLIENT_ID _In_ PKSTART_ROUTINE StartRoutine
Definition: psfuncs.h:87
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
VOID NTAPI KeRevertToUserAffinityThread(VOID)
Definition: thrdobj.c:1030
VOID NTAPI MmDeleteKernelStack(PVOID Stack, BOOLEAN GuiStack)
#define _KeGetPreviousMode()
Definition: ketypes.h:1104
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE VOID KiSetThreadSwapBusy(IN PKTHREAD Thread)
Definition: ke_x.h:204
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
VOID NTAPI KeThawAllThreads(VOID)
Definition: thrdobj.c:669
_In_ KPRIORITY Priority
Definition: kefuncs.h:516
FORCEINLINE VOID KiAcquireApcLock(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:600
VOID NTAPI KeReadyThread(IN PKTHREAD Thread)
Definition: thrdobj.c:115
PKTHREAD FASTCALL KiSelectNextThread(IN PKPRCB Prcb)
Definition: thrdschd.c:328
#define MAXULONG_PTR
Definition: basetsd.h:103
_In_ UCHAR Processor
Definition: kefuncs.h:695
#define LOW_REALTIME_PRIORITY
VOID FASTCALL KiWaitTest(PVOID Object, KPRIORITY Increment)
LONG NTAPI KeSetBasePriorityThread(IN PKTHREAD Thread, IN LONG Increment)
Definition: thrdobj.c:1184
#define AFFINITY_MASK(Id)
Definition: ke.h:155
KPRIORITY NTAPI KeQueryPriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:1017
VOID FASTCALL KiInsertQueueApc(IN PKAPC Apc, IN KPRIORITY PriorityBoost)
Definition: apc.c:85
FORCEINLINE VOID KiAcquireApcLockAtDpcLevel(IN PKTHREAD Thread, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:609
#define InsertTailList(ListHead, Entry)
#define STATUS_ALERTED
Definition: ntstatus.h:80
FORCEINLINE VOID KiReleaseApcLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:627
void DbgBreakPoint()
Definition: mach.c:553
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
BOOLEAN NTAPI KeIsExecutingDpc(VOID)
Definition: dpc.c:946
struct _KTHREAD * NextThread
Definition: ketypes.h:567
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
LONG KPRIORITY
Definition: compat.h:462
VOID NTAPI KeUninitThread(IN PKTHREAD Thread)
Definition: thrdobj.c:926
static BOOL Set
Definition: pageheap.c:10
VOID NTAPI KeSetSystemAffinityThread(IN KAFFINITY Affinity)
Definition: thrdobj.c:1116
#define ASSERT_THREAD(object)
Definition: ketypes.h:1966
BOOLEAN NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:731
_SEH2_TRY
Definition: create.c:4250
BOOLEAN NTAPI KeAlertThread(IN PKTHREAD Thread, IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:185
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define TIMER_WAIT_BLOCK
Definition: ke.h:162
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
FORCEINLINE SCHAR KiComputeNewPriority(IN PKTHREAD Thread, IN SCHAR Adjustment)
Definition: ke_x.h:1458
LIST_ENTRY PspReaperListHead
Definition: kill.c:19
WORK_QUEUE_ITEM PspReaperWorkItem
Definition: kill.c:20
UCHAR KIRQL
Definition: env_spec_w32.h:591
EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue]
Definition: work.c:35
KPRIORITY NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread)
Definition: thrdobj.c:61
VOID NTAPI KeInitializeThread(IN PKPROCESS Process, IN OUT PKTHREAD Thread, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext, IN PCONTEXT Context, IN PVOID Teb, IN PVOID KernelStack)
Definition: thrdobj.c:900
VOID NTAPI KiInitializeContextThread(PKTHREAD Thread, PKSYSTEM_ROUTINE SystemRoutine, PKSTART_ROUTINE StartRoutine, PVOID StartContext, PCONTEXT Context)
VOID NTAPI KeFreezeAllThreads(VOID)
Definition: thrdobj.c:315
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
VOID(NTAPI * PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
Definition: ketypes.h:625
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
KSTART_ROUTINE * PKSTART_ROUTINE
Definition: ketypes.h:487
long LONG
Definition: pedump.c:60
union node Node
Definition: types.h:1255
VOID NTAPI KiSuspendThread(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: thrdobj.c:596
#define _KeGetCurrentThread()
Definition: ketypes.h:1103
KAPC_STATE ApcState
Definition: ketypes.h:1668
ULONG SystemAffinityActive
Definition: ketypes.h:1587
VOID FASTCALL KiSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdschd.c:511
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
BOOLEAN NTAPI KeSetDisableBoostThread(IN OUT PKTHREAD Thread, IN BOOLEAN Disable)
Definition: thrdobj.c:95
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define InterlockedBitTestAndReset
Definition: interlocked.h:35
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
unsigned char BOOLEAN
FORCEINLINE VOID KiAcquirePrcbLock(IN PKPRCB Prcb)
Definition: ke_x.h:214
LIST_ENTRY MutantListEntry
Definition: ketypes.h:830
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
FORCEINLINE VOID KiReleaseApcLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:635
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
DISPATCHER_HEADER Header
Definition: ketypes.h:829
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
#define HIGH_PRIORITY
VOID NTAPI KeBoostPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Increment)
Definition: thrdobj.c:229
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
VOID FASTCALL KiExitDispatcher(KIRQL OldIrql)
VOID NTAPI KiReadyThread(IN PKTHREAD Thread)
Definition: thrdschd.c:429
VOID NTAPI KeTerminateThread(IN KPRIORITY Increment)
Definition: thrdobj.c:1375
#define MAXIMUM_PRIORITY
_Out_ PULONG UserTime
Definition: kefuncs.h:784
#define InterlockedBitTestAndSet
Definition: interlocked.h:30
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
FORCEINLINE VOID KiAcquireThreadLock(IN PKTHREAD Thread)
Definition: ke_x.h:234
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
struct _KNODE * ParentNode
Definition: ketypes.h:751
UCHAR WaitType
Definition: ketypes.h:446
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
char CCHAR
Definition: typedefs.h:50
USHORT WaitKey
Definition: ketypes.h:448
PVOID Object
Definition: ketypes.h:456
PKNODE KeNodeBlock[1]
Definition: krnlinit.c:39
signed char SCHAR
Definition: sqltypes.h:14
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define KERNEL_STACK_SIZE
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define MUTANT_INCREMENT
Definition: extypes.h:84
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
FORCEINLINE VOID KiReleaseProcessLock(IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:652
ULONG NTAPI KeAlertResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:133
unsigned char UCHAR
Definition: xmlstorage.h:181
#define ASSERT_MUTANT(Object)
#define MAXIMUM_SUSPEND_COUNT
Definition: winbase.h:386
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define BitScanReverse
Definition: interlocked.h:6
FORCEINLINE VOID KiAcquireProcessLock(IN PKPROCESS Process, IN PKLOCK_QUEUE_HANDLE Handle)
Definition: ke_x.h:643
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
ULONG IdealProcessor
Definition: ketypes.h:1834
Definition: ketypes.h:535
Definition: typedefs.h:117
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
UINT64 SetMember
Definition: ketypes.h:578
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID NTAPI KeCapturePersistentThreadState(IN PVOID CurrentThread, IN ULONG Setting1, IN ULONG Setting2, IN ULONG Setting3, IN ULONG Setting4, IN ULONG Setting5, IN PVOID ThreadState)
Definition: thrdobj.c:940
_In_ PLARGE_INTEGER _In_opt_ PTIMER_APC_ROUTINE _In_opt_ PVOID _In_ BOOLEAN _In_opt_ LONG _Out_opt_ PBOOLEAN PreviousState
Definition: zwfuncs.h:428
_SEH2_END
Definition: create.c:4424
UINT Timer
Definition: capclock.c:11
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
FORCEINLINE VOID KiReleaseDispatcherLock(IN KIRQL OldIrql)
Definition: ke_x.h:152
FORCEINLINE KIRQL KiAcquireDispatcherLock(VOID)
Definition: ke_x.h:144
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1327
LONG_PTR FASTCALL KiSwapThread(IN PKTHREAD Thread, IN PKPRCB Prcb)
Definition: thrdschd.c:355
UINT64 MultiThreadProcessorSet
Definition: ketypes.h:752
UCHAR ApcDisable
Definition: ketypes.h:833
CHAR SuspendCount
Definition: ketypes.h:1855
ULONG_PTR KAFFINITY
Definition: compat.h:75
PKPRCB KiProcessorBlock[]
Definition: krnlinit.c:32
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LONG NTAPI KiInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry, BOOLEAN Head)
VOID NTAPI KeRundownThread(VOID)
Definition: thrdobj.c:439
FORCEINLINE VOID KiRundownThread(IN PKTHREAD Thread)
Definition: ke.h:230
unsigned int * PULONG
Definition: retypes.h:1
ULONG NTAPI KeResumeThread(IN PKTHREAD Thread)
Definition: thrdobj.c:397
UCHAR NTAPI KeGetPreviousMode(VOID)
Definition: thrdobj.c:969
VOID FASTCALL KiActivateWaiterQueue(IN PKQUEUE Queue)
Definition: queue.c:24
BOOLEAN Abandoned
Definition: ketypes.h:832
FORCEINLINE VOID KiReleaseDispatcherLockFromDpcLevel(VOID)
Definition: ke_x.h:168
DISPATCHER_HEADER Header
Definition: ketypes.h:1551
struct _KTHREAD *RESTRICTED_POINTER OwnerThread
Definition: ketypes.h:831
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
ULONG KiMask32Array[MAXIMUM_PRIORITY]
Definition: thrdobj.c:18
#define OUT
Definition: typedefs.h:39
KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[SSDT_MAX_ENTRIES]
Definition: procobj.c:23
volatile UCHAR State
Definition: ketypes.h:1679
GROUP_AFFINITY Affinity
Definition: ketypes.h:1828
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define UNIMPLEMENTED
Definition: debug.h:114
#define ULONG_PTR
Definition: config.h:101
PKTHREAD NTAPI KeGetCurrentThread(VOID)
Definition: thrdobj.c:957
BOOLEAN NTAPI KeReadStateThread(IN PKTHREAD Thread)
Definition: thrdobj.c:51
struct _ETHREAD * PETHREAD
Definition: nt_native.h:29
*LockHandle LockHandle _Out_ PKLOCK_QUEUE_HANDLE LockHandle
Definition: kefuncs.h:742
VOID NTAPI KiSuspendRundown(IN PKAPC Apc)
Definition: thrdobj.c:572
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
LIST_ENTRY WaitListHead
Definition: ketypes.h:796
ULONG ApcQueueable
Definition: ketypes.h:1601
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:632
UCHAR NTAPI KeSetIdealProcessorThread(IN PKTHREAD Thread, IN UCHAR Processor)
Definition: thrdobj.c:1075
PVOID NTAPI MmCreateKernelStack(BOOLEAN GuiStack, UCHAR Node)
FORCEINLINE VOID KxUnwaitThread(IN DISPATCHER_HEADER *Object, IN KPRIORITY Increment)
Definition: ke_x.h:1250
EX_PUSH_LOCK ThreadLock
Definition: pstypes.h:1091
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:42
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define STATUS_SUSPEND_COUNT_EXCEEDED
Definition: ntstatus.h:296
GROUP_AFFINITY UserAffinity
Definition: ketypes.h:1802
#define THREAD_ALERT_INCREMENT
Definition: ketypes.h:126
base of all file and directory entries
Definition: entries.h:82
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:107
VOID NTAPI KiSuspendNop(IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
Definition: thrdobj.c:580
#define THREAD_WAIT_OBJECTS
Definition: ketypes.h:480
BOOLEAN NTAPI KeSetKernelStackSwapEnable(IN BOOLEAN Enable)
Definition: thrdobj.c:997
FORCEINLINE VOID KiAcquireDispatcherLockAtDpcLevel(VOID)
Definition: ke_x.h:160
ULONG NTAPI KeSuspendThread(PKTHREAD Thread)
Definition: thrdobj.c:610
Definition: dlist.c:348
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: pic.c:156