Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

thredobj.c File Reference

#include "ki.h"

Go to the source code of this file.

Defines

#define ASSERT_THREAD(E)

Functions

VOID KeInitializeThread (IN PKTHREAD Thread, IN PVOID KernelStack, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext OPTIONAL, IN PCONTEXT ContextFrame OPTIONAL, IN PVOID Teb OPTIONAL, IN PKPROCESS Process)
BOOLEAN KeAlertThread (IN PKTHREAD Thread, IN KPROCESSOR_MODE AlertMode)
ULONG KeAlertResumeThread (IN PKTHREAD Thread)
VOID KeBoostPriorityThread (IN PKTHREAD Thread, IN KPRIORITY Increment)
KAFFINITY KeConfineThread (VOID)
BOOLEAN KeDisableApcQueuingThread (IN PKTHREAD Thread)
BOOLEAN KeEnableApcQueuingThread (IN PKTHREAD Thread)
ULONG KeForceResumeThread (IN PKTHREAD Thread)
VOID KeFreezeAllThreads (VOID)
BOOLEAN KeQueryAutoAlignmentThread (IN PKTHREAD Thread)
LONG KeQueryBasePriorityThread (IN PKTHREAD Thread)
KPRIORITY KeQueryPriorityThread (IN PKTHREAD Thread)
BOOLEAN KeReadStateThread (IN PKTHREAD Thread)
VOID KeReadyThread (IN PKTHREAD Thread)
ULONG KeResumeThread (IN PKTHREAD Thread)
VOID KeRevertToUserAffinityThread (VOID)
VOID KeRundownThread ()
KAFFINITY KeSetAffinityThread (IN PKTHREAD Thread, IN KAFFINITY Affinity)
VOID KeSetSystemAffinityThread (IN KAFFINITY Affinity)
LONG KeSetBasePriorityThread (IN PKTHREAD Thread, IN LONG Increment)
LOGICAL KeSetDisableBoostThread (IN PKTHREAD Thread, IN LOGICAL Disable)
CCHAR KeSetIdealProcessorThread (IN PKTHREAD Thread, IN CCHAR Processor)
BOOLEAN KeSetKernelStackSwapEnable (IN BOOLEAN Enable)
KPRIORITY KeSetPriorityThread (IN PKTHREAD Thread, IN KPRIORITY Priority)
ULONG KeSuspendThread (IN PKTHREAD Thread)
VOID KeTerminateThread (IN KPRIORITY Increment)
BOOLEAN KeTestAlertThread (IN KPROCESSOR_MODE AlertMode)
VOID KeThawAllThreads (VOID)


Define Documentation

#define ASSERT_THREAD  ) 
 

Value:

{ \ ASSERT((E)->Header.Type == ThreadObject); \ }

Definition at line 38 of file thredobj.c.


Function Documentation

ULONG KeAlertResumeThread IN PKTHREAD  Thread  ) 
 

Definition at line 365 of file thredobj.c.

References ALERT_INCREMENT, ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, FALSE, KernelMode, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiUnwaitThread(), KiWaitTest(), RESUME_INCREMENT, TRUE, and Waiting.

Referenced by NtAlertResumeThread().

00371 : 00372 00373 This function attempts to alert a thread in kernel mode and cause its 00374 execution to be continued if it is currently in an alertable Wait state. 00375 In addition, a resume operation is performed on the specified thread. 00376 00377 Arguments: 00378 00379 Thread - Supplies a pointer to a dispatcher object of type thread. 00380 00381 Return Value: 00382 00383 The previous suspend count. 00384 00385 --*/ 00386 00387 { 00388 00389 ULONG OldCount; 00390 KIRQL OldIrql; 00391 00392 ASSERT_THREAD(Thread); 00393 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00394 00395 // 00396 // Raise IRQL to dispatcher level, lock dispatcher database, and lock 00397 // APC queue. 00398 // 00399 00400 KiLockDispatcherDatabase(&OldIrql); 00401 KiAcquireSpinLock(&Thread->ApcQueueLock); 00402 00403 // 00404 // If the kernel mode alerted state is FALSE, then attempt to alert 00405 // the thread for kernel mode. 00406 // 00407 00408 if (Thread->Alerted[KernelMode] == FALSE) { 00409 00410 // 00411 // If the thread is currently in a Wait state and the Wait is alertable, 00412 // then the thread is unwaited with a status of "alerted". Else set the 00413 // kernel mode alerted variable. 00414 // 00415 00416 if ((Thread->State == Waiting) && (Thread->Alertable == TRUE)) { 00417 KiUnwaitThread(Thread, STATUS_ALERTED, ALERT_INCREMENT); 00418 00419 } else { 00420 Thread->Alerted[KernelMode] = TRUE; 00421 } 00422 } 00423 00424 // 00425 // Capture the current suspend count. 00426 // 00427 00428 OldCount = Thread->SuspendCount; 00429 00430 // 00431 // If the thread is currently suspended, then decrement its suspend count. 00432 // 00433 00434 if (OldCount != 0) { 00435 Thread->SuspendCount -= 1; 00436 00437 // 00438 // If the resultant suspend count is zero and the freeze count is 00439 // zero, then resume the thread by releasing its suspend semaphore. 00440 // 00441 00442 if ((Thread->SuspendCount == 0) && (Thread->FreezeCount == 0)) { 00443 Thread->SuspendSemaphore.Header.SignalState += 1; 00444 KiWaitTest(&Thread->SuspendSemaphore, RESUME_INCREMENT); 00445 } 00446 } 00447 00448 // 00449 // Unlock APC queue, unlock dispatcher database, lower IRQL to its 00450 // previous value, and return the previous suspend count. 00451 // 00452 00453 KiReleaseSpinLock(&Thread->ApcQueueLock); 00454 KiUnlockDispatcherDatabase(OldIrql); 00455 return OldCount; 00456 }

BOOLEAN KeAlertThread IN PKTHREAD  Thread,
IN KPROCESSOR_MODE  AlertMode
 

Definition at line 281 of file thredobj.c.

References ALERT_INCREMENT, ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, FALSE, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiUnwaitThread(), TRUE, and Waiting.

Referenced by NtAlertThread().

00288 : 00289 00290 This function attempts to alert a thread and cause its execution to 00291 be continued if it is currently in an alertable Wait state. Otherwise 00292 it just sets the alerted variable for the specified processor mode. 00293 00294 Arguments: 00295 00296 Thread - Supplies a pointer to a dispatcher object of type thread. 00297 00298 AlertMode - Supplies the processor mode for which the thread is 00299 to be alerted. 00300 00301 Return Value: 00302 00303 The previous state of the alerted variable for the specified processor 00304 mode. 00305 00306 --*/ 00307 00308 { 00309 00310 BOOLEAN Alerted; 00311 KIRQL OldIrql; 00312 00313 ASSERT_THREAD(Thread); 00314 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00315 00316 // 00317 // Raise IRQL to dispatcher level, lock dispatcher database, and lock 00318 // APC queue. 00319 // 00320 00321 KiLockDispatcherDatabase(&OldIrql); 00322 KiAcquireSpinLock(&Thread->ApcQueueLock); 00323 00324 // 00325 // Capture the current state of the alerted variable for the specified 00326 // processor mode. 00327 // 00328 00329 Alerted = Thread->Alerted[AlertMode]; 00330 00331 // 00332 // If the alerted state for the specified processor mode is Not-Alerted, 00333 // then attempt to alert the thread. 00334 // 00335 00336 if (Alerted == FALSE) { 00337 00338 // 00339 // If the thread is currently in a Wait state, the Wait is alertable, 00340 // and the specified processor mode is less than or equal to the Wait 00341 // mode, then the thread is unwaited with a status of "alerted". 00342 // 00343 00344 if ((Thread->State == Waiting) && (Thread->Alertable == TRUE) && 00345 (AlertMode <= Thread->WaitMode)) { 00346 KiUnwaitThread(Thread, STATUS_ALERTED, ALERT_INCREMENT); 00347 00348 } else { 00349 Thread->Alerted[AlertMode] = TRUE; 00350 } 00351 } 00352 00353 // 00354 // Unlock APC queue, unlock dispatcher database, lower IRQL to its 00355 // previous value, and return the previous alerted state for the 00356 // specified mode. 00357 // 00358 00359 KiReleaseSpinLock(&Thread->ApcQueueLock); 00360 KiUnlockDispatcherDatabase(OldIrql); 00361 return Alerted; 00362 }

VOID KeBoostPriorityThread IN PKTHREAD  Thread,
IN KPRIORITY  Increment
 

Definition at line 459 of file thredobj.c.

References ASSERT, DISPATCH_LEVEL, Increment, KiBoostPriorityThread, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by ExpWaitForResourceDdk(), NtReadFile(), NtSetInformationProcess(), and VdmDispatchInterrupts().

00466 : 00467 00468 This function boosts the priority of the specified thread using the 00469 same algorithm used when a thread gets a boost from a wait operation. 00470 00471 Arguments: 00472 00473 Thread - Supplies a pointer to a dispatcher object of type thread. 00474 00475 Increment - Supplies the priority increment that is to be applied to 00476 the thread's priority. 00477 00478 Return Value: 00479 00480 None. 00481 00482 --*/ 00483 00484 { 00485 00486 KIRQL OldIrql; 00487 00488 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00489 00490 // 00491 // Raise IRQL to dispatcher level and lock dispatcher database. 00492 // 00493 00494 KiLockDispatcherDatabase(&OldIrql); 00495 00496 // 00497 // If the thread does not run at a realtime priority level, then boost 00498 // the thread priority. 00499 // 00500 00501 if (Thread->Priority < LOW_REALTIME_PRIORITY) { 00502 KiBoostPriorityThread(Thread, Increment); 00503 } 00504 00505 // 00506 // Unlock dispatcher database and lower IRQL to its previous 00507 // value. 00508 // 00509 00510 KiUnlockDispatcherDatabase(OldIrql); 00511 return; 00512 }

KAFFINITY KeConfineThread VOID   ) 
 

Definition at line 515 of file thredobj.c.

References _KTHREAD::Affinity, ASSERT, DISPATCH_LEVEL, KeGetCurrentThread, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), and _KTHREAD::NextProcessor.

00521 : 00522 00523 This function confines the execution of the current thread to the current 00524 processor. 00525 00526 Arguments: 00527 00528 Thread - Supplies a pointer to a dispatcher object of type thread. 00529 00530 Return Value: 00531 00532 The previous affinity value. 00533 00534 --*/ 00535 00536 { 00537 00538 KAFFINITY Affinity; 00539 KIRQL OldIrql; 00540 PKTHREAD Thread; 00541 00542 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00543 00544 // 00545 // Raise IRQL to dispatcher level and lock dispatcher database. 00546 // 00547 00548 Thread = KeGetCurrentThread(); 00549 KiLockDispatcherDatabase(&OldIrql); 00550 00551 // 00552 // Capture the current affinity and compute new affinity value by 00553 // shifting a one bit left by the current processor number. 00554 // 00555 00556 Affinity = Thread->Affinity; 00557 Thread->Affinity = (KAFFINITY)(1 << Thread->NextProcessor); 00558 00559 // 00560 // Unlock dispatcher database and lower IRQL to its previous 00561 // value. 00562 // 00563 00564 KiUnlockDispatcherDatabase(OldIrql); 00565 00566 // 00567 // Return the previous affinity value. 00568 // 00569 00570 return Affinity; 00571 }

BOOLEAN KeDisableApcQueuingThread IN PKTHREAD  Thread  ) 
 

Definition at line 574 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, FALSE, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by PspExitThread().

00580 : 00581 00582 This function disables the queuing of APC's to the specified thread. 00583 00584 Arguments: 00585 00586 Thread - Supplies a pointer to a dispatcher object of type thread. 00587 00588 Return Value: 00589 00590 The previous value of the APC queuing state variable. 00591 00592 --*/ 00593 00594 { 00595 00596 BOOLEAN ApcQueueable; 00597 KIRQL OldIrql; 00598 00599 ASSERT_THREAD(Thread); 00600 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00601 00602 // 00603 // Raise IRQL to dispatcher level and lock dispatcher database. 00604 // 00605 00606 KiLockDispatcherDatabase(&OldIrql); 00607 00608 // 00609 // Capture the current state of the APC queueable state variable and 00610 // set its state to FALSE. 00611 // 00612 00613 ApcQueueable = Thread->ApcQueueable; 00614 Thread->ApcQueueable = FALSE; 00615 00616 // 00617 // Unlock dispatcher database and lower IRQL to its previous 00618 // value. 00619 // 00620 00621 KiUnlockDispatcherDatabase(OldIrql); 00622 00623 // 00624 // Return the previous APC queueable state. 00625 // 00626 00627 return ApcQueueable; 00628 }

BOOLEAN KeEnableApcQueuingThread IN PKTHREAD  Thread  ) 
 

Definition at line 631 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), and TRUE.

Referenced by PspCreateThread().

00637 : 00638 00639 This function enables the queuing of APC's to the specified thread. 00640 00641 Arguments: 00642 00643 Thread - Supplies a pointer to a dispatcher object of type thread. 00644 00645 Return Value: 00646 00647 The previous value of the APC queuing state variable. 00648 00649 --*/ 00650 00651 { 00652 00653 BOOLEAN ApcQueueable; 00654 KIRQL OldIrql; 00655 00656 ASSERT_THREAD(Thread); 00657 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00658 00659 // 00660 // Raise IRQL to dispatcher level and lock dispatcher database. 00661 // 00662 00663 KiLockDispatcherDatabase(&OldIrql); 00664 00665 // 00666 // Capture the current state of the APC queueable state variable and 00667 // set its state to TRUE. 00668 // 00669 00670 ApcQueueable = Thread->ApcQueueable; 00671 Thread->ApcQueueable = TRUE; 00672 00673 // 00674 // Unlock dispatcher database and lower IRQL to its previous 00675 // value. 00676 // 00677 00678 KiUnlockDispatcherDatabase(OldIrql); 00679 00680 // 00681 // Return previous APC queueable state. 00682 // 00683 00684 return ApcQueueable; 00685 }

ULONG KeForceResumeThread IN PKTHREAD  Thread  ) 
 

Definition at line 688 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiWaitTest(), and RESUME_INCREMENT.

Referenced by NtTerminateProcess(), NtTerminateThread(), PspExitNormalApc(), PspExitThread(), and PspTerminateProcess().

00694 : 00695 00696 This function forces resumption of thread execution if the thread is 00697 suspended. If the specified thread is not suspended, then no operation 00698 is performed. 00699 00700 Arguments: 00701 00702 Thread - Supplies a pointer to a dispatcher object of type thread. 00703 00704 Return Value: 00705 00706 The sum of the previous suspend count and the freeze count. 00707 00708 --*/ 00709 00710 { 00711 00712 ULONG OldCount; 00713 KIRQL OldIrql; 00714 00715 ASSERT_THREAD(Thread); 00716 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00717 00718 // 00719 // Raise IRQL to dispatcher level and lock dispatcher database. 00720 // 00721 00722 KiLockDispatcherDatabase(&OldIrql); 00723 00724 // 00725 // Capture the current suspend count. 00726 // 00727 00728 OldCount = Thread->SuspendCount + Thread->FreezeCount; 00729 00730 // 00731 // If the thread is currently suspended, then force resumption of 00732 // thread execution. 00733 // 00734 00735 if (OldCount != 0) { 00736 Thread->FreezeCount = 0; 00737 Thread->SuspendCount = 0; 00738 Thread->SuspendSemaphore.Header.SignalState += 1; 00739 KiWaitTest(&Thread->SuspendSemaphore, RESUME_INCREMENT); 00740 } 00741 00742 // 00743 // Unlock dispatcher database and lower IRQL to its previous 00744 // value. 00745 // 00746 00747 KiUnlockDispatcherDatabase(OldIrql); 00748 00749 // 00750 // Return the previous suspend count. 00751 // 00752 00753 return OldCount; 00754 }

VOID KeFreezeAllThreads VOID   ) 
 

Definition at line 757 of file thredobj.c.

References _KTHREAD::ApcState, ASSERT, DISPATCH_LEVEL, FALSE, _KTHREAD::FreezeCount, _KSEMAPHORE::Header, KeEnterCriticalRegion, KeGetCurrentThread, KiInsertQueueApc(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), NULL, _KAPC_STATE::Process, RESUME_INCREMENT, _DISPATCHER_HEADER::SignalState, _KTHREAD::SuspendApc, _KTHREAD::SuspendCount, _KTHREAD::SuspendSemaphore, _ETHREAD::ThreadListEntry, and _KPROCESS::ThreadListHead.

Referenced by DbgkpSuspendProcess().

00763 : 00764 00765 This function suspends the execution of all thread in the current 00766 process except the current thread. If the freeze count overflows 00767 the maximum suspend count, then a condition is raised. 00768 00769 Arguments: 00770 00771 None. 00772 00773 Return Value: 00774 00775 None. 00776 00777 --*/ 00778 00779 { 00780 00781 PKTHREAD CurrentThread; 00782 PLIST_ENTRY ListHead; 00783 PLIST_ENTRY NextEntry; 00784 PKPROCESS Process; 00785 PKTHREAD Thread; 00786 PETHREAD EThread; 00787 ULONG OldCount; 00788 KIRQL OldIrql; 00789 00790 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00791 00792 // 00793 // Get the address of the current thread object, the current process 00794 // object, raise IRQL to dispatch level, lock dispatcher database, 00795 // and freeze the execution of all threads in the process except the 00796 // current thread. 00797 // 00798 00799 CurrentThread = KeGetCurrentThread(); 00800 Process = CurrentThread->ApcState.Process; 00801 KiLockDispatcherDatabase(&OldIrql); 00802 00803 // 00804 // If the freeze count of the current thread is not zero, then there 00805 // is another thread that is trying to freeze this thread. Unlock the 00806 // dispatcher, lower IRQL to its previous value, allow the suspend 00807 // APC to occur, then raise IRQL to dispatch level, lock the dispatcher 00808 // database, and try again. 00809 // 00810 00811 while (CurrentThread->FreezeCount != 0) { 00812 KiUnlockDispatcherDatabase(OldIrql); 00813 KiLockDispatcherDatabase(&OldIrql); 00814 } 00815 00816 KeEnterCriticalRegion(); 00817 00818 // 00819 // Freeze all threads except the current thread. 00820 // 00821 00822 ListHead = &Process->ThreadListHead; 00823 NextEntry = ListHead->Flink; 00824 do { 00825 00826 // 00827 // Get the address of the next thread and suspend it if it is 00828 // not the current thread. 00829 // 00830 00831 Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry); 00832 if (Thread != CurrentThread) { 00833 00834 EThread = (PETHREAD) Thread; 00835 if ( EThread->ThreadListEntry.Flink == NULL ) { 00836 ; 00837 } else { 00838 00839 // 00840 // Increment the freeze count. If the thread was not previously 00841 // suspended, then queue the thread's suspend APC. 00842 // 00843 00844 OldCount = Thread->FreezeCount; 00845 00846 ASSERT(OldCount != MAXIMUM_SUSPEND_COUNT); 00847 00848 Thread->FreezeCount += 1; 00849 if ((OldCount == 0) && (Thread->SuspendCount == 0)) { 00850 if (KiInsertQueueApc(&Thread->SuspendApc, RESUME_INCREMENT) == FALSE) { 00851 Thread->SuspendSemaphore.Header.SignalState -= 1; 00852 } 00853 } 00854 } 00855 } 00856 NextEntry = NextEntry->Flink; 00857 } while (NextEntry != ListHead); 00858 00859 // 00860 // Unlock dispatcher database and lower IRQL to its previous 00861 // value. 00862 // 00863 00864 KiUnlockDispatcherDatabase(OldIrql); 00865 return; 00866 }

VOID KeInitializeThread IN PKTHREAD  Thread,
IN PVOID  KernelStack,
IN PKSYSTEM_ROUTINE  SystemRoutine,
IN PKSTART_ROUTINE StartRoutine  OPTIONAL,
IN PVOID StartContext  OPTIONAL,
IN PCONTEXT ContextFrame  OPTIONAL,
IN PVOID Teb  OPTIONAL,
IN PKPROCESS  Process
 

Definition at line 43 of file thredobj.c.

References FALSE, _KTIMER::Header, Index, Initialized, KeInitializeApc(), KeInitializeSemaphore(), KeInitializeSpinLock(), KeInitializeTimer(), KeNumberProcessors, KernelMode, KeServiceDescriptorTable, KiInitializeContextThread(), KiLockDispatcherDatabase, KiSuspendNop(), KiSuspendThread(), KiUnlockDispatcherDatabase(), L, NULL, _KWAIT_BLOCK::Object, OriginalApcEnvironment, PKKERNEL_ROUTINE, PKRUNDOWN_ROUTINE, THREAD_WAIT_OBJECTS, ThreadObject, TIMER_WAIT_BLOCK, TRUE, UserMode, _KWAIT_BLOCK::WaitKey, _KWAIT_BLOCK::WaitListEntry, _DISPATCHER_HEADER::WaitListHead, and _KWAIT_BLOCK::WaitType.

Referenced by KiInitializeKernel(), and PspCreateThread().

00056 : 00057 00058 This function initializes a thread object. The priority, affinity, 00059 and initial quantum are taken from the parent process object. The 00060 thread object is inserted at the end of the thread list for the 00061 parent process. 00062 00063 N.B. This routine is carefully written so that if an access violation 00064 occurs while reading the specified context frame, then no kernel 00065 data structures will have been modified. It is the responsibility 00066 of the caller to handle the exception and provide necessary clean 00067 up. 00068 00069 N.B. It is assumed that the thread object is zeroed. 00070 00071 Arguments: 00072 00073 Thread - Supplies a pointer to a dispatcher object of type thread. 00074 00075 KernelStack - Supplies a pointer to the base of a kernel stack on which 00076 the context frame for the thread is to be constructed. 00077 00078 SystemRoutine - Supplies a pointer to the system function that is to be 00079 called when the thread is first scheduled for execution. 00080 00081 StartRoutine - Supplies an optional pointer to a function that is to be 00082 called after the system has finished initializing the thread. This 00083 parameter is specified if the thread is a system thread and will 00084 execute totally in kernel mode. 00085 00086 StartContext - Supplies an optional pointer to an arbitrary data structure 00087 which will be passed to the StartRoutine as a parameter. This 00088 parameter is specified if the thread is a system thread and will 00089 execute totally in kernel mode. 00090 00091 ContextFrame - Supplies an optional pointer a context frame which contains 00092 the initial user mode state of the thread. This parameter is specified 00093 if the thread is a user thread and will execute in user mode. If this 00094 parameter is not specified, then the Teb parameter is ignored. 00095 00096 Teb - Supplies an optional pointer to the user mode thread environment 00097 block. This parameter is specified if the thread is a user thread and 00098 will execute in user mode. This parameter is ignored if the ContextFrame 00099 parameter is not specified. 00100 00101 Process - Supplies a pointer to a control object of type process. 00102 00103 Return Value: 00104 00105 None. 00106 00107 --*/ 00108 00109 { 00110 00111 ULONG Index; 00112 KIRQL OldIrql; 00113 PKTIMER Timer; 00114 PKWAIT_BLOCK WaitBlock; 00115 00116 // 00117 // Initialize the standard dispatcher object header and set the initial 00118 // state of the thread object. 00119 // 00120 00121 Thread->Header.Type = ThreadObject; 00122 Thread->Header.Size = sizeof(KTHREAD) / sizeof(LONG); 00123 InitializeListHead(&Thread->Header.WaitListHead); 00124 00125 // 00126 // Initialize the owned mutant listhead. 00127 // 00128 00129 InitializeListHead(&Thread->MutantListHead); 00130 00131 // 00132 // Initialize the thread field of all builtin wait blocks. 00133 // 00134 00135 for (Index = 0; Index < (THREAD_WAIT_OBJECTS + 1); Index += 1) { 00136 Thread->WaitBlock[Index].Thread = Thread; 00137 } 00138 00139 // 00140 // Initialize the alerted, preempted, debugactive, autoalignment, 00141 // kernel stack resident, enable kernel stack swap, and process 00142 // ready queue boolean values. 00143 // 00144 // N.B. Only nonzero values are initialized. 00145 // 00146 00147 Thread->AutoAlignment = Process->AutoAlignment; 00148 Thread->EnableStackSwap = TRUE; 00149 Thread->KernelStackResident = TRUE; 00150 00151 // 00152 // Set the system service table pointer to the address of the static 00153 // system service descriptor table. If the thread is later converted 00154 // to a Win32 thread this pointer will be change to a pointer to the 00155 // shadow system service descriptor table. 00156 // 00157 00158 Thread->ServiceTable = (PVOID)&KeServiceDescriptorTable[0]; 00159 00160 // 00161 // Initialize the APC state pointers, the current APC state, the saved 00162 // APC state, and enable APC queuing. 00163 // 00164 00165 Thread->ApcStatePointer[0] = &Thread->ApcState; 00166 Thread->ApcStatePointer[1] = &Thread->SavedApcState; 00167 InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]); 00168 InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]); 00169 Thread->ApcState.Process = Process; 00170 Thread->ApcQueueable = TRUE; 00171 00172 // 00173 // Initialize the kernel mode suspend APC and the suspend semaphore object. 00174 // and the builtin wait timeout timer object. 00175 // 00176 00177 KeInitializeApc(&Thread->SuspendApc, 00178 Thread, 00179 OriginalApcEnvironment, 00180 (PKKERNEL_ROUTINE)KiSuspendNop, 00181 (PKRUNDOWN_ROUTINE)NULL, 00182 KiSuspendThread, 00183 KernelMode, 00184 NULL); 00185 00186 KeInitializeSemaphore(&Thread->SuspendSemaphore, 0L, 2L); 00187 00188 // 00189 // Initialize the builtin timer trimer wait wait block. 00190 // 00191 // N.B. This is the only time the wait block is initialized sincs this 00192 // information is constant. 00193 // 00194 00195 Timer = &Thread->Timer; 00196 KeInitializeTimer(Timer); 00197 WaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK]; 00198 WaitBlock->Object = Timer; 00199 WaitBlock->WaitKey = (CSHORT)STATUS_TIMEOUT; 00200 WaitBlock->WaitType = WaitAny; 00201 WaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead; 00202 WaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead; 00203 00204 // 00205 // Initialize the APC queue spinlock. 00206 // 00207 00208 KeInitializeSpinLock(&Thread->ApcQueueLock); 00209 00210 // 00211 // Initialize the Thread Environment Block (TEB) pointer (can be NULL). 00212 // 00213 00214 Thread->Teb = Teb; 00215 00216 // 00217 // Set the initial kernel stack and the initial thread context. 00218 // 00219 00220 Thread->InitialStack = KernelStack; 00221 Thread->StackBase = KernelStack; 00222 Thread->StackLimit = (PVOID)((ULONG_PTR)KernelStack - KERNEL_STACK_SIZE); 00223 KiInitializeContextThread(Thread, 00224 SystemRoutine, 00225 StartRoutine, 00226 StartContext, 00227 ContextFrame); 00228 00229 // 00230 // Set the base thread priority, the thread priority, the thread affinity, 00231 // the thread quantum, and the scheduling state. 00232 // 00233 00234 Thread->BasePriority = Process->BasePriority; 00235 Thread->Priority = Thread->BasePriority; 00236 Thread->Affinity = Process->Affinity; 00237 Thread->UserAffinity = Process->Affinity; 00238 Thread->SystemAffinityActive = FALSE; 00239 Thread->Quantum = Process->ThreadQuantum; 00240 Thread->State = Initialized; 00241 Thread->DisableBoost = Process->DisableBoost; 00242 00243 #ifdef i386 00244 00245 Thread->Iopl = Process->Iopl; 00246 00247 #endif 00248 00249 // 00250 // Lock the dispatcher database, insert the thread in the process 00251 // thread list, increment the kernel stack count, and unlock the 00252 // dispatcher database. 00253 // 00254 // N.B. The distinguished value MAXSHORT is used to signify that no 00255 // threads have been created for a process. 00256 // 00257 00258 KiLockDispatcherDatabase(&OldIrql); 00259 InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry); 00260 if (Process->StackCount == MAXSHORT) { 00261 Process->StackCount = 1; 00262 00263 } else { 00264 Process->StackCount += 1; 00265 } 00266 00267 // 00268 // Initialize the ideal processor number for the thread. 00269 // 00270 // N.B. This must be done under the dispatcher lock to prevent byte 00271 // granularity problems on Alpha. 00272 // 00273 00274 Process->ThreadSeed += 1; 00275 Thread->IdealProcessor = (UCHAR)(Process->ThreadSeed % KeNumberProcessors); 00276 KiUnlockDispatcherDatabase(OldIrql); 00277 return; 00278 }

BOOLEAN KeQueryAutoAlignmentThread IN PKTHREAD  Thread  ) 
 

Definition at line 869 of file thredobj.c.

References ASSERT_THREAD.

00875 : 00876 00877 This function returns the data alignment handling mode for the specified 00878 thread. 00879 00880 Arguments: 00881 00882 None. 00883 00884 Return Value: 00885 00886 A value of TRUE is returned if data alignment exceptions are being 00887 automatically handled by the kernel. Otherwise, a value of FALSE 00888 is returned. 00889 00890 --*/ 00891 00892 { 00893 00894 ASSERT_THREAD(Thread); 00895 00896 // 00897 // Return the data alignment handling mode for the thread. 00898 // 00899 00900 return Thread->AutoAlignment; 00901 }

LONG KeQueryBasePriorityThread IN PKTHREAD  Thread  ) 
 

Definition at line 904 of file thredobj.c.

References ASSERT, ASSERT_THREAD, _KPROCESS::BasePriority, DISPATCH_LEVEL, Increment, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by NtQueryInformationThread().

00910 : 00911 00912 This function returns the base priority increment of the specified 00913 thread. 00914 00915 Arguments: 00916 00917 Thread - Supplies a pointer to a dispatcher object of type thread. 00918 00919 Return Value: 00920 00921 The base priority increment of the specified thread. 00922 00923 --*/ 00924 00925 { 00926 00927 LONG Increment; 00928 KIRQL OldIrql; 00929 PKPROCESS Process; 00930 00931 ASSERT_THREAD(Thread); 00932 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00933 00934 // 00935 // Raise IRQL to dispatcher level and lock dispatcher database. 00936 // 00937 00938 KiLockDispatcherDatabase(&OldIrql); 00939 00940 // 00941 // If priority saturation occured the last time the thread base priority 00942 // was set, then return the saturation increment value. Otherwise, compute 00943 // the increment value as the difference between the thread base priority 00944 // and the process base priority. 00945 // 00946 00947 Process = Thread->ApcStatePointer[0]->Process; 00948 Increment = Thread->BasePriority - Process->BasePriority; 00949 if (Thread->Saturation != 0) { 00950 Increment = ((HIGH_PRIORITY + 1) / 2) * Thread->Saturation; 00951 } 00952 00953 // 00954 // Unlock dispatcher database and lower IRQL to its previous 00955 // value. 00956 // 00957 00958 KiUnlockDispatcherDatabase(OldIrql); 00959 00960 // 00961 // Return the previous thread base priority increment. 00962 // 00963 00964 return Increment; 00965 }

KPRIORITY KeQueryPriorityThread IN PKTHREAD  Thread  ) 
 

Definition at line 968 of file thredobj.c.

00974 : 00975 00976 This function returns the current priority of the specified thread. 00977 00978 Arguments: 00979 00980 Thread - Supplies a pointer to a dispatcher object of type thread. 00981 00982 Return Value: 00983 00984 The current priority of the specified thread. 00985 00986 --*/ 00987 00988 { 00989 return Thread->Priority; 00990 }

BOOLEAN KeReadStateThread IN PKTHREAD  Thread  ) 
 

Definition at line 993 of file thredobj.c.

References ASSERT_THREAD.

Referenced by NtQueryInformationThread().

00999 : 01000 01001 This function reads the current signal state of a thread object. 01002 01003 Arguments: 01004 01005 Thread - Supplies a pointer to a dispatcher object of type thread. 01006 01007 Return Value: 01008 01009 The current signal state of the thread object. 01010 01011 --*/ 01012 01013 { 01014 01015 ASSERT_THREAD(Thread); 01016 01017 // 01018 // Return current signal state of thread object. 01019 // 01020 01021 return (BOOLEAN)Thread->Header.SignalState; 01022 }

VOID KeReadyThread IN PKTHREAD  Thread  ) 
 

Definition at line 1025 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiReadyThread(), and KiUnlockDispatcherDatabase().

Referenced by PspCreateThread().

01031 : 01032 01033 This function readies a thread for execution. If the thread's process 01034 is currently not in the balance set, then the thread is inserted in the 01035 thread's process' ready queue. Else if the thread is higher priority than 01036 another thread that is currently running on a processor then the thread 01037 is selected for execution on that processor. Else the thread is inserted 01038 in the dispatcher ready queue selected by its priority. 01039 01040 Arguments: 01041 01042 Thread - Supplies a pointer to a dispatcher object of type thread. 01043 01044 Return Value: 01045 01046 None. 01047 01048 --*/ 01049 01050 { 01051 01052 KIRQL OldIrql; 01053 01054 ASSERT_THREAD(Thread); 01055 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 01056 01057 // 01058 // Raise IRQL to dispatcher level and lock dispatcher database. 01059 // 01060 01061 KiLockDispatcherDatabase(&OldIrql); 01062 01063 // 01064 // Ready the specified thread for execution. 01065 // 01066 01067 KiReadyThread(Thread); 01068 01069 // 01070 // Unlock dispatcher database and lower IRQL to its previous 01071 // value. 01072 // 01073 01074 KiUnlockDispatcherDatabase(OldIrql); 01075 return; 01076 }

ULONG KeResumeThread IN PKTHREAD  Thread  ) 
 

Definition at line 1079 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiWaitTest(), and RESUME_INCREMENT.

Referenced by NtResumeThread(), and PspCreateThread().

01085 : 01086 01087 This function resumes the execution of a suspended thread. If the 01088 specified thread is not suspended, then no operation is performed. 01089 01090 Arguments: 01091 01092 Thread - Supplies a pointer to a dispatcher object of type thread. 01093 01094 Return Value: 01095 01096 The previous suspend count. 01097 01098 --*/ 01099 01100 { 01101 01102 ULONG OldCount; 01103 KIRQL OldIrql; 01104 01105 ASSERT_THREAD(Thread); 01106 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 01107 01108 // 01109 // Raise IRQL to dispatcher level and lock dispatcher database. 01110 // 01111 01112 KiLockDispatcherDatabase(&OldIrql); 01113 01114 // 01115 // Capture the current suspend count. 01116 // 01117 01118 OldCount = Thread->SuspendCount; 01119 01120 // 01121 // If the thread is currently suspended, then decrement its suspend count. 01122 // 01123 01124 if (OldCount != 0) { 01125 Thread->SuspendCount -= 1; 01126 01127 // 01128 // If the resultant suspend count is zero and the freeze count is 01129 // zero, then resume the thread by releasing its suspend semaphore. 01130 // 01131 01132 if ((Thread->SuspendCount == 0) && (Thread->FreezeCount == 0)) { 01133 Thread->SuspendSemaphore.Header.SignalState += 1; 01134 KiWaitTest(&Thread->SuspendSemaphore, RESUME_INCREMENT); 01135 } 01136 } 01137 01138 // 01139 // Unlock dispatcher database and lower IRQL to its previous 01140 // value. 01141 // 01142 01143 KiUnlockDispatcherDatabase(OldIrql); 01144 01145 // 01146 // Return the previous suspend count. 01147 // 01148 01149 return OldCount; 01150 }

VOID KeRevertToUserAffinityThread VOID   ) 
 

Definition at line 1153 of file thredobj.c.

References _KTHREAD::Affinity, ASSERT, DISPATCH_LEVEL, FALSE, KeGetCurrentPrcb, KeGetCurrentThread, KiLockDispatcherDatabase, KiSelectNextThread(), KiUnlockDispatcherDatabase(), NULL, Standby, _KTHREAD::State, _KTHREAD::SystemAffinityActive, and _KTHREAD::UserAffinity.

Referenced by CmpConfigureProcessors(), CmpInitializeMachineDependentConfiguration(), Ke386CallBios(), KeConnectInterrupt(), KeDisconnectInterrupt(), KeSetSystemTime(), KeSetup80387OrEmulate(), and KiInitMachineDependent().

01159 : 01160 01161 This function setss the affinity of the current thread to its user 01162 affinity. 01163 01164 Arguments: 01165 01166 None. 01167 01168 Return Value: 01169 01170 None. 01171 01172 --*/ 01173 01174 { 01175 01176 PRKTHREAD CurrentThread; 01177 PRKTHREAD NextThread; 01178 KIRQL OldIrql; 01179 PKPRCB Prcb; 01180 01181 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 01182 ASSERT(KeGetCurrentThread()->SystemAffinityActive != FALSE); 01183 01184 // 01185 // Raise IRQL to dispatcher level and lock dispatcher database. 01186 // 01187 01188 CurrentThread = KeGetCurrentThread(); 01189 KiLockDispatcherDatabase(&OldIrql); 01190 01191 // 01192 // Set the current affinity to the user affinity. 01193 // 01194 // If the current processor is not in the new affinity set and another 01195 // thread has not already been selected for execution on the current 01196 // processor, then select a new thread for the current processor. 01197 // 01198 01199 CurrentThread->Affinity = CurrentThread->UserAffinity; 01200 CurrentThread->SystemAffinityActive = FALSE; 01201 Prcb = KeGetCurrentPrcb(); 01202 if (((Prcb->SetMember & CurrentThread->Affinity) == 0) && 01203 (Prcb->NextThread == NULL)) { 01204 NextThread = KiSelectNextThread(CurrentThread); 01205 NextThread->State = Standby; 01206 Prcb->NextThread = NextThread; 01207 } 01208 01209 // 01210 // Unlock dispatcher database and lower IRQL to its previous value. 01211 // 01212 01213 KiUnlockDispatcherDatabase(OldIrql); 01214 return; 01215 }

VOID KeRundownThread  ) 
 

Definition at line 1218 of file thredobj.c.

References _KMUTANT::Abandoned, _KMUTANT::ApcDisable, ASSERT, DISPATCH_LEVEL, _KMUTANT::Header, KeBugCheckEx(), KeGetCurrentThread, KiLockDispatcherDatabase, KiRundownChannel(), KiUnlockDispatcherDatabase(), KiWaitTest(), MUTANT_INCREMENT, _KMUTANT::MutantListEntry, _KTHREAD::MutantListHead, NULL, _KMUTANT::OwnerThread, _DISPATCHER_HEADER::SignalState, TRUE, and _DISPATCHER_HEADER::WaitListHead.

Referenced by PspExitThread().

01223 : 01224 01225 This function is called by the executive to rundown thread structures 01226 which must be guarded by the dispatcher database lock and which must 01227 be processed before actually terminating the thread. An example of such 01228 a structure is the mutant ownership list that is anchored in the kernel 01229 thread object. 01230 01231 Arguments: 01232 01233 None. 01234 01235 Return Value: 01236 01237 None. 01238 01239 --*/ 01240 01241 { 01242 01243 PKMUTANT Mutant; 01244 PLIST_ENTRY NextEntry; 01245 KIRQL OldIrql; 01246 PKTHREAD Thread; 01247 01248 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 01249 01250 // 01251 // Rundown possible associated channel object or receive buffer. 01252 // 01253 01254 #if 0 01255 01256 KiRundownChannel(); 01257 01258 #endif 01259 01260 // 01261 // Raise IRQL to dispatcher level and lock dispatcher database. 01262 // 01263 01264 Thread = KeGetCurrentThread(); 01265 KiLockDispatcherDatabase(&OldIrql); 01266 01267 // 01268 // Scan the list of owned mutant objects and release the mutant objects 01269 // with an abandoned status. If the mutant is a kernel mutex, then bug 01270 // check. 01271 // 01272 01273 NextEntry = Thread->MutantListHead.Flink; 01274 while (NextEntry != &Thread->MutantListHead) { 01275 Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry); 01276 if (Mutant->ApcDisable != 0) { 01277 KeBugCheckEx(THREAD_TERMINATE_HELD_MUTEX, 01278 (ULONG_PTR)Thread, 01279 (ULONG_PTR)Mutant, 0, 0); 01280 } 01281 01282 RemoveEntryList(&Mutant->MutantListEntry); 01283 Mutant->Header.SignalState = 1; 01284 Mutant->Abandoned = TRUE; 01285 Mutant->OwnerThread = (PKTHREAD)NULL; 01286 if (IsListEmpty(&Mutant->Header.WaitListHead) != TRUE) { 01287 KiWaitTest(Mutant, MUTANT_INCREMENT); 01288 } 01289 01290 NextEntry = Thread->MutantListHead.Flink; 01291 } 01292 01293 // 01294 // Release dispatcher database lock and lower IRQL to its previous value. 01295 // 01296 01297 KiUnlockDispatcherDatabase(OldIrql); 01298 return; 01299 }

KAFFINITY KeSetAffinityThread IN PKTHREAD  Thread,
IN KAFFINITY  Affinity
 

Definition at line 1302 of file thredobj.c.

References _KPROCESS::Affinity, ASSERT, ASSERT_THREAD, ClearMember, DISPATCH_LEVEL, FALSE, INVALID_AFFINITY_SET, KeBugCheck(), KiDispatcherReadyListHead, KiLockDispatcherDatabase, KiProcessorBlock, KiReadySummary, KiReadyThread(), KiRequestDispatchInterrupt, KiSelectNextThread(), KiUnlockDispatcherDatabase(), NULL, Ready, Running, Standby, and _KTHREAD::State.

Referenced by NtSetInformationProcess(), NtSetInformationThread(), and PspApplyJobLimitsToProcess().

01309 : 01310 01311 This function sets the affinity of a specified thread to a new 01312 value. If the new affinity is not a proper subset of the parent 01313 process affinity, or is null, then an error condition is raised. 01314 If the specified thread is running on, or about to run on, a 01315 processor for which it is no longer able to run, then the target 01316 processor is rescheduled. If the specified thread is in a ready 01317 state and is not in the parent process ready queue, then it is 01318 rereadied to reevaluate any additional processors it may run on. 01319 01320 Arguments: 01321 01322 Thread - Supplies a pointer to a dispatcher object of type thread. 01323 01324 Affinity - Supplies the new of set of processors on which the thread 01325 can run. 01326 01327 Return Value: 01328 01329 The previous affinity of the specified thread. 01330 01331 --*/ 01332 01333 { 01334 01335 KAFFINITY OldAffinity; 01336 KIRQL OldIrql; 01337 PKPRCB Prcb; 01338 PKPROCESS Process; 01339 ULONG Processor; 01340 KPRIORITY ThreadPriority; 01341 PRKTHREAD Thread1; 01342 01343 ASSERT_THREAD(Thread); 01344 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 01345 01346 // 01347 // Raise IRQL to dispatcher level and lock dispatcher database. 01348 // 01349 01350 KiLockDispatcherDatabase(&OldIrql); 01351 01352 // 01353 // Capture the current affinity of the specified thread and get address 01354 // of parent process object; 01355 // 01356 01357 OldAffinity = Thread->UserAffinity; 01358 Process = Thread->ApcStatePointer[0]->Process; 01359 01360 // 01361 // If new affinity is not a proper subset of the parent process affinity, 01362 // or the new affinity is null, then bugcheck. 01363 // 01364 01365 if (((Affinity & Process->Affinity) != (Affinity)) || (!Affinity)) { 01366 KeBugCheck(INVALID_AFFINITY_SET); 01367 } 01368 01369 // 01370 // Set the thread user affinity to the specified value. 01371 // 01372 // If the thread is not current executing with system affinity active, 01373 // then set the thread current affinity and switch on the thread state. 01374 // 01375 01376 Thread->UserAffinity = Affinity; 01377 if (Thread->SystemAffinityActive == FALSE) { 01378 Thread->Affinity = Affinity; 01379 switch (Thread->State) { 01380 01381 // 01382 // Ready State. 01383 // 01384 // If the thread is not in the process ready queue, then remove 01385 // it from its current dispatcher ready queue and reready it for 01386 // execution. 01387 // 01388 01389 case Ready: 01390 if (Thread->ProcessReadyQueue == FALSE) { 01391 RemoveEntryList(&Thread->WaitListEntry); 01392 ThreadPriority = Thread->Priority; 01393 if (IsListEmpty(&KiDispatcherReadyListHead[ThreadPriority]) != FALSE) { 01394 ClearMember(ThreadPriority, KiReadySummary); 01395 } 01396 01397 KiReadyThread(Thread); 01398 } 01399 01400 break; 01401 01402 // 01403 // Standby State. 01404 // 01405 // If the target processor is not in the new affinity set, then 01406 // set the next thread to null for the target processor, select 01407 // a new thread to run on the target processor, and reready the 01408 // thread for execution. 01409 // 01410 01411 case Standby: 01412 Processor = Thread->NextProcessor; 01413 Prcb = KiProcessorBlock[Processor]; 01414 if ((Prcb->SetMember & Affinity) == 0) { 01415 Prcb->NextThread = NULL; 01416 Thread1 = KiSelectNextThread(Thread); 01417 Thread1->State = Standby; 01418 Prcb->NextThread = Thread1; 01419 KiReadyThread(Thread); 01420 } 01421 01422 break; 01423 01424 // 01425 // Running State. 01426 // 01427 // If the target processor is not in the new affinity set and 01428 // another thread has not already been selected for execution 01429 // on the target processor, then select a new thread for the 01430 // target processor, and cause the target processor to be 01431 // redispatched. 01432 // 01433 01434 case Running: 01435 Processor = Thread->NextProcessor; 01436 Prcb = KiProcessorBlock[Processor]; 01437 if (((Prcb->SetMember & Affinity) == 0) && 01438 (Prcb->NextThread == NULL)) { 01439 Thread1 = KiSelectNextThread(Thread); 01440 Thread1->State = Standby; 01441 Prcb->NextThread = Thread1; 01442 KiRequestDispatchInterrupt(Processor); 01443 } 01444 01445 break; 01446 01447 // 01448 // Initialized, Terminated, Waiting, Transition case - For these 01449 // states it is sufficient to just set the new thread affinity. 01450 // 01451 01452 default: 01453 break; 01454 } 01455 } 01456 01457 // 01458 // Unlock dispatcher database, lower IRQL to its previous value, and 01459 // return the previous user affinity. 01460 // 01461 01462 KiUnlockDispatcherDatabase(OldIrql); 01463 return OldAffinity; 01464 }

LONG KeSetBasePriorityThread IN PKTHREAD  Thread,
IN LONG  Increment
 

Definition at line 1532 of file thredobj.c.

References abs, ASSERT, ASSERT_THREAD, _KPROCESS::BasePriority, DISPATCH_LEVEL, FALSE, Increment, KiLockDispatcherDatabase, KiSetPriorityThread(), KiUnlockDispatcherDatabase(), and _KPROCESS::ThreadQuantum.

Referenced by ExpCreateWorkerThread(), ExpWorkerThreadBalanceManager(), and NtSetInformationThread().

01539 : 01540 01541 This function sets the base priority of the specified thread to a 01542 new value. The new base priority for the thread is the process base 01543 priority plus the increment. 01544 01545 Arguments: 01546 01547 Thread - Supplies a pointer to a dispatcher object of type thread. 01548 01549 Increment - Supplies the base priority increment of the subject thread. 01550 01551 N.B. If the absolute value of the increment is such that saturation 01552 of the base priority is forced, then subsequent changes to the 01553 parent process base priority will not change the base priority 01554 of the thread. 01555 01556 Return Value: 01557 01558 The previous base priority increment of the specified thread. 01559 01560 --*/ 01561 01562 { 01563 01564 KPRIORITY NewBase; 01565 KPRIORITY NewPriority; 01566 KPRIORITY OldBase; 01567 LONG OldIncrement; 01568 KIRQL OldIrql; 01569 PKPROCESS Process; 01570 01571 ASSERT_THREAD(Thread); 01572 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 01573 01574 // 01575 // Raise IRQL to dispatcher level and lock dispatcher database. 01576 // 01577 01578 KiLockDispatcherDatabase(&OldIrql); 01579 01580 // 01581 // Capture the base priority of the specified thread and determine 01582 // whether saturation if being forced. 01583 // 01584 01585 Process = Thread->ApcStatePointer[0]->Process; 01586 OldBase = Thread->BasePriority; 01587 OldIncrement = OldBase - Process->BasePriority; 01588 if (Thread->Saturation != 0) { 01589 OldIncrement = ((HIGH_PRIORITY + 1) / 2) * Thread->Saturation; 01590 } 01591 01592 Thread->Saturation = FALSE; 01593 if (abs(Increment) >= (HIGH_PRIORITY + 1) / 2) { 01594 Thread->Saturation = (Increment > 0) ? 1 : -1; 01595 } 01596 01597 // 01598 // Set the base priority of the specified thread. If the thread's process 01599 // is in the realtime class, then limit the change to the realtime class. 01600 // Otherwise, limit the change to the variable class. 01601 // 01602 01603 NewBase = Process->BasePriority + Increment; 01604 if (Process->BasePriority >= LOW_REALTIME_PRIORITY) { 01605 if (NewBase < LOW_REALTIME_PRIORITY) { 01606 NewBase = LOW_REALTIME_PRIORITY; 01607 01608 } else if (NewBase > HIGH_PRIORITY) { 01609 NewBase = HIGH_PRIORITY; 01610 } 01611 01612 // 01613 // Set the new priority of the thread to the new base priority. 01614 // 01615 01616 NewPriority = NewBase; 01617 01618 } else { 01619 if (NewBase >= LOW_REALTIME_PRIORITY) { 01620 NewBase = LOW_REALTIME_PRIORITY - 1; 01621 01622 } else if (NewBase <= LOW_PRIORITY) { 01623 NewBase = 1; 01624 } 01625 01626 // 01627 // Compute the new thread priority. If the new priority is outside 01628 // the variable class, then set the new priority to the highest 01629 // variable priority. 01630 // 01631 01632 if (Thread->Saturation != 0) { 01633 NewPriority = NewBase; 01634 01635 } else { 01636 NewPriority = Thread->Priority + 01637 (NewBase - OldBase) - Thread->PriorityDecrement; 01638 01639 if (NewPriority >= LOW_REALTIME_PRIORITY) { 01640 NewPriority = LOW_REALTIME_PRIORITY - 1; 01641 } 01642 } 01643 } 01644 01645 // 01646 // Set the new base priority and clear the priority decrement. If the 01647 // new priority is not equal to the old priority, then set the new thread 01648 // priority. 01649 // 01650 01651 Thread->BasePriority = (SCHAR)NewBase; 01652 Thread->DecrementCount = 0; 01653 Thread->PriorityDecrement = 0; 01654 if (NewPriority != Thread->Priority) { 01655 Thread->Quantum = Process->ThreadQuantum; 01656 KiSetPriorityThread(Thread, NewPriority); 01657 } 01658 01659 // 01660 // Unlock dispatcher database and lower IRQL to its previous 01661 // value. 01662 // 01663 01664 KiUnlockDispatcherDatabase(OldIrql); 01665 01666 // 01667 // Return the previous thread base priority. 01668 // 01669 01670 return OldIncrement; 01671 }

LOGICAL KeSetDisableBoostThread IN PKTHREAD  Thread,
IN LOGICAL  Disable
 

Definition at line 1674 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by NtSetInformationProcess(), and NtSetInformationThread().

01681 : 01682 01683 This function disables priority boosts for the specified thread. 01684 01685 Arguments: 01686 01687 Thread - Supplies a pointer to a dispatcher object of type thread. 01688 01689 Disable - Supplies a logical value that determines whether priority 01690 boosts for the thread are disabled or enabled. 01691 01692 Return Value: 01693 01694 The previous value of the disable boost state variable. 01695 01696 --*/ 01697 01698 { 01699 01700 LOGICAL DisableBoost; 01701 KIRQL OldIrql; 01702 01703 ASSERT_THREAD(Thread); 01704 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 01705 01706 // 01707 // Raise IRQL to dispatcher level and lock dispatcher database. 01708 // 01709 01710 KiLockDispatcherDatabase(&OldIrql); 01711 01712 // 01713 // Capture the current state of the disable boost variable and set its 01714 // state to TRUE. 01715 // 01716 01717 DisableBoost = Thread->DisableBoost; 01718 Thread->DisableBoost = (BOOLEAN)Disable; 01719 01720 // 01721 // Unlock dispatcher database and lower IRQL to its previous 01722 // value. 01723 // 01724 01725 KiUnlockDispatcherDatabase(OldIrql); 01726 01727 // 01728 // Return the previous disable boost state. 01729 // 01730 01731 return DisableBoost; 01732 }

CCHAR KeSetIdealProcessorThread IN PKTHREAD  Thread,
IN CCHAR  Processor
 

Definition at line 1735 of file thredobj.c.

References ASSERT, KeNumberProcessors, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), MAXIMUM_PROCESSORS, and _KPROCESS::ThreadSeed.

Referenced by NtSetInformationThread().

01742 : 01743 01744 This function sets the ideal processor for the specified thread execution. 01745 01746 Arguments: 01747 01748 Thread - Supplies a pointer to the thread whose ideal processor number is 01749 set to the specfied value. 01750 01751 Processor - Supplies the number of the ideal processor (the distinguished 01752 value MAXIMUM_PROCESSORS indicates that there is no ideal processor). 01753 01754 Return Value: 01755 01756 The previous ideal processor number. 01757 01758 --*/ 01759 01760 { 01761 01762 CCHAR OldProcessor; 01763 KIRQL OldIrql; 01764 PKPROCESS Process; 01765 01766 // 01767 // Capture the previous ideal processor value, set the new ideal 01768 // processor value, and return the old ideal processor value for the 01769 // current thread; 01770 // 01771 // Note that this is done under the dispatcher lock in order to 01772 // synchronize the updates with the other fields that share the 01773 // same DWORD. Otherwise there is a granularity problem on Alpha. 01774 // 01775 01776 ASSERT(Processor <= MAXIMUM_PROCESSORS); 01777 01778 KiLockDispatcherDatabase(&OldIrql); 01779 OldProcessor = Thread->IdealProcessor; 01780 if (Processor < MAXIMUM_PROCESSORS) { 01781 Thread->IdealProcessor = Processor; 01782 01783 } else { 01784 Process = Thread->ApcState.Process; 01785 Process->ThreadSeed += 1; 01786 Thread->IdealProcessor = (UCHAR)(Process->ThreadSeed % KeNumberProcessors); 01787 } 01788 01789 // 01790 // Unlock dispatcher database and lower IRQL to its previous 01791 // value. 01792 // 01793 01794 KiUnlockDispatcherDatabase(OldIrql); 01795 return OldProcessor; 01796 }

BOOLEAN KeSetKernelStackSwapEnable IN BOOLEAN  Enable  ) 
 

Definition at line 1799 of file thredobj.c.

References _KTHREAD::EnableStackSwap, and KeGetCurrentThread.

Referenced by ExpWorkerThread(), xxxDestroyThreadInfo(), and xxxInterSendMsgEx().

01805 : 01806 01807 This function sets the kernel stack swap enable value for the current 01808 thread and returns the old swap enable value. 01809 01810 Arguments: 01811 01812 Enable - Supplies the new kernel stack swap enable value. 01813 01814 Return Value: 01815 01816 The previous kernel stack swap enable value. 01817 01818 --*/ 01819 01820 { 01821 01822 BOOLEAN OldState; 01823 PKTHREAD Thread; 01824 01825 // 01826 // Capture the previous kernel stack swap enable value, set the new 01827 // swap enable value, and return the old swap enable value for the 01828 // current thread; 01829 // 01830 01831 Thread = KeGetCurrentThread(); 01832 OldState = Thread->EnableStackSwap; 01833 Thread->EnableStackSwap = Enable; 01834 return OldState; 01835 }

KPRIORITY KeSetPriorityThread IN PKTHREAD  Thread,
IN KPRIORITY  Priority
 

Definition at line 1838 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, FALSE, KiLockDispatcherDatabase, KiSetPriorityThread(), KiUnlockDispatcherDatabase(), and _KPROCESS::ThreadQuantum.

Referenced by FsRtlWorkerThread(), KeBalanceSetManager(), KeBoostCurrentThread(), KeSwapProcessOrStack(), KiInitializeKernel(), MiDereferenceSegmentThread(), MiMappedPageWriter(), MiModifiedPageWriter(), MmZeroPageThread(), NtSetInformationThread(), PspExitThread(), and zzzSetWindowsHookEx().

01845 : 01846 01847 This function sets the priority of the specified thread to a new value. 01848 If the new thread priority is lower than the old thread priority, then 01849 resecheduling may take place if the thread is currently running on, or 01850 about to run on, a processor. 01851 01852 Arguments: 01853 01854 Thread - Supplies a pointer to a dispatcher object of type thread. 01855 01856 Priority - Supplies the new priority of the subject thread. 01857 01858 Return Value: 01859 01860 The previous priority of the specified thread. 01861 01862 --*/ 01863 01864 { 01865 01866 KIRQL OldIrql; 01867 KPRIORITY OldPriority; 01868 PKPROCESS Process; 01869 01870 ASSERT_THREAD(Thread); 01871 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 01872 ASSERT(((Priority != 0) || (Thread->BasePriority == 0)) && 01873 (Priority <= HIGH_PRIORITY)); 01874 01875 ASSERT(KeIsExecutingDpc() == FALSE); 01876 01877 // 01878 // Raise IRQL to dispatcher level and lock dispatcher database. 01879 // 01880 01881 KiLockDispatcherDatabase(&OldIrql); 01882 01883 // 01884 // Capture the current thread priority, set the thread priority to the 01885 // the new value, and replenish the thread quantum. It is assumed that 01886 // the priority would not be set unless the thread had already lost it 01887 // initial quantum. 01888 // 01889 01890 OldPriority = Thread->Priority; 01891 Process = Thread->ApcStatePointer[0]->Process; 01892 Thread->Quantum = Process->ThreadQuantum; 01893 Thread->DecrementCount = 0; 01894 Thread->PriorityDecrement = 0; 01895 KiSetPriorityThread(Thread, Priority); 01896 01897 // 01898 // Unlock dispatcher database and lower IRQL to its previous 01899 // value. 01900 // 01901 01902 KiUnlockDispatcherDatabase(OldIrql); 01903 01904 // 01905 // Return the previous thread priority. 01906 // 01907 01908 return OldPriority; 01909 }

VOID KeSetSystemAffinityThread IN KAFFINITY  Affinity  ) 
 

Definition at line 1467 of file thredobj.c.

References _KTHREAD::Affinity, ASSERT, DISPATCH_LEVEL, KeActiveProcessors, KeGetCurrentPrcb, KeGetCurrentThread, KiLockDispatcherDatabase, KiSelectNextThread(), KiUnlockDispatcherDatabase(), NULL, Standby, _KTHREAD::State, _KTHREAD::SystemAffinityActive, and TRUE.

Referenced by CmpConfigureProcessors(), CmpInitializeMachineDependentConfiguration(), Ke386CallBios(), KeConnectInterrupt(), KeDisconnectInterrupt(), KeSetSystemTime(), KeSetup80387OrEmulate(), and KiInitMachineDependent().

01473 : 01474 01475 This function set the system affinity of the current thread. 01476 01477 Arguments: 01478 01479 Affinity - Supplies the new of set of processors on which the thread 01480 can run. 01481 01482 Return Value: 01483 01484 None. 01485 01486 --*/ 01487 01488 { 01489 01490 PRKTHREAD CurrentThread; 01491 PRKTHREAD NextThread; 01492 KIRQL OldIrql; 01493 PKPRCB Prcb; 01494 01495 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 01496 ASSERT((Affinity & KeActiveProcessors) != 0); 01497 01498 // 01499 // Raise IRQL to dispatcher level and lock dispatcher database. 01500 // 01501 01502 CurrentThread = KeGetCurrentThread(); 01503 KiLockDispatcherDatabase(&OldIrql); 01504 01505 // 01506 // Set the current affinity to the specified affinity. 01507 // 01508 // If the current processor is not in the new affinity set and another 01509 // thread has not already been selected for execution on the current 01510 // processor, then select a new thread for the current processor. 01511 // 01512 01513 CurrentThread->Affinity = Affinity; 01514 CurrentThread->SystemAffinityActive = TRUE; 01515 Prcb = KeGetCurrentPrcb(); 01516 if (((Prcb->SetMember & CurrentThread->Affinity) == 0) && 01517 (Prcb->NextThread == NULL)) { 01518 NextThread = KiSelectNextThread(CurrentThread); 01519 NextThread->State = Standby; 01520 Prcb->NextThread = NextThread; 01521 } 01522 01523 // 01524 // Unlock dispatcher database and lower IRQL to its previous value. 01525 // 01526 01527 KiUnlockDispatcherDatabase(OldIrql); 01528 return; 01529 }

ULONG KeSuspendThread IN PKTHREAD  Thread  ) 
 

Definition at line 1912 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, ExRaiseStatus(), FALSE, KiInsertQueueApc(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), and RESUME_INCREMENT.

Referenced by NtSuspendThread(), and PspCreateThread().

01918 : 01919 01920 This function suspends the execution of a thread. If the suspend count 01921 overflows the maximum suspend count, then a condition is raised. 01922 01923 Arguments: 01924 01925 Thread - Supplies a pointer to a dispatcher object of type thread. 01926 01927 Return Value: 01928 01929 The previous suspend count. 01930 01931 --*/ 01932 01933 { 01934 01935 ULONG OldCount; 01936 KIRQL OldIrql; 01937 01938 ASSERT_THREAD(Thread); 01939 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 01940 01941 // 01942 // Raise IRQL to dispatcher level and lock dispatcher database. 01943 // 01944 01945 KiLockDispatcherDatabase(&OldIrql); 01946 01947 // 01948 // Capture the current suspend count. 01949 // 01950 01951 OldCount = Thread->SuspendCount; 01952 01953 // 01954 // If the suspend count is at its maximum value, then unlock dispatcher 01955 // database, lower IRQL to its previous value, and raise an error 01956 // condition. 01957 // 01958 01959 if (OldCount == MAXIMUM_SUSPEND_COUNT) { 01960 01961 // 01962 // Unlock the dispatcher database and raise an exception. 01963 // 01964 01965 KiUnlockDispatcherDatabase(OldIrql); 01966 ExRaiseStatus(STATUS_SUSPEND_COUNT_EXCEEDED); 01967 } 01968 01969 // 01970 // Increment the suspend count. If the thread was not previously suspended, 01971 // then queue the thread's suspend APC. 01972 // 01973 01974 Thread->SuspendCount += 1; 01975 if ((OldCount == 0) && (Thread->FreezeCount == 0)) { 01976 if (KiInsertQueueApc(&Thread->SuspendApc, RESUME_INCREMENT) == FALSE) { 01977 Thread->SuspendSemaphore.Header.SignalState -= 1; 01978 } 01979 } 01980 01981 // 01982 // Unlock dispatcher database and lower IRQL to its previous 01983 // value. 01984 // 01985 01986 KiUnlockDispatcherDatabase(OldIrql); 01987 01988 // 01989 // Return the previous suspend count. 01990 // 01991 01992 return OldCount; 01993 }

VOID KeTerminateThread IN KPRIORITY  Increment  ) 
 

Definition at line 1996 of file thredobj.c.

References ASSERT, BALANCE_INCREMENT, DISPATCH_LEVEL, ExWorkerQueue, FALSE, _KEVENT::Header, HyperCriticalWorkQueue, Increment, KeGetCurrentThread, KiActivateWaiterQueue(), KiInsertQueue(), KiLockDispatcherDatabase, KiProcessOutSwapListHead, KiRundownThread, KiSwapEvent, KiSwapThread(), KiWaitTest(), _WORK_QUEUE_ITEM::List, NULL, ProcessInTransition, PsReaperActive, PsReaperListHead, PsReaperWorkItem, _DISPATCHER_HEADER::SignalState, _KPROCESS::StackCount, _KPROCESS::State, _KPROCESS::SwapListEntry, Terminated, _ETHREAD::ThreadListEntry, _KPROCESS::ThreadListHead, TRUE, and _DISPATCHER_HEADER::WaitListHead.

Referenced by PspExitThread().

02002 : 02003 02004 This function terminates the execution of the current thread, sets the 02005 signal state of the thread to Signaled, and attempts to satisfy as many 02006 Waits as possible. The scheduling state of the thread is set to terminated, 02007 and a new thread is selected to run on the current processor. There is no 02008 return from this function. 02009 02010 Arguments: 02011 02012 None. 02013 02014 Return Value: 02015 02016 None. 02017 02018 --*/ 02019 02020 { 02021 02022 PRKTHREAD NextThread; 02023 KIRQL OldIrql; 02024 PKPROCESS Process; 02025 PRKQUEUE Queue; 02026 PRKTHREAD Thread; 02027 02028 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 02029 02030 // 02031 // Raise IRQL to dispatcher level and lock dispatcher database. 02032 // 02033 02034 Thread = KeGetCurrentThread(); 02035 KiLockDispatcherDatabase(&OldIrql); 02036 02037 // 02038 // Insert the thread in the reaper list. 02039 // 02040 // If a reaper thread is not currently active, then insert a work item in 02041 // the hyper critical work queue. 02042 // 02043 // N.B. This code has knowledge of the reaper data structures and how 02044 // worker threads are implemented. 02045 // 02046 // N.B. The dispatcher database lock is used to synchronize access to the 02047 // reaper list. 02048 // 02049 02050 InsertTailList(&PsReaperListHead, &((PETHREAD)Thread)->TerminationPortList); 02051 if (PsReaperActive == FALSE) { 02052 PsReaperActive = TRUE; 02053 KiInsertQueue(&ExWorkerQueue[HyperCriticalWorkQueue].WorkerQueue, 02054 &PsReaperWorkItem.List, 02055 FALSE); 02056 } 02057 02058 // 02059 // If the current thread is processing a queue entry, then remove 02060 // the thrread from the queue object thread list and attempt to 02061 // activate another thread that is blocked on the queue object. 02062 // 02063 02064 Queue = Thread->Queue; 02065 if (Queue != NULL) { 02066 RemoveEntryList(&Thread->QueueListEntry); 02067 KiActivateWaiterQueue(Queue); 02068 } 02069 02070 // 02071 // Set the state of the current thread object to Signaled, and attempt 02072 // to satisfy as many Waits as possible. 02073 // 02074 02075 Thread->Header.SignalState = TRUE; 02076 if (IsListEmpty(&Thread->Header.WaitListHead) != TRUE) { 02077 KiWaitTest((PVOID)Thread, Increment); 02078 } 02079 02080 // 02081 // Remove thread from its parent process' thread list. 02082 // 02083 02084 RemoveEntryList(&Thread->ThreadListEntry); 02085 02086 // 02087 // Set thread scheduling state to terminated, decrement the process' 02088 // stack count, select a new thread to run on the current processor, 02089 // and swap context to the new thread. 02090 // 02091 02092 Thread->State = Terminated; 02093 Process = Thread->ApcState.Process; 02094 Process->StackCount -= 1; 02095 if (Process->StackCount == 0) { 02096 if (Process->ThreadListHead.Flink != &Process->ThreadListHead) { 02097 Process->State = ProcessInTransition; 02098 InsertTailList(&KiProcessOutSwapListHead, &Process->SwapListEntry); 02099 KiSwapEvent.Header.SignalState = 1; 02100 if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { 02101 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); 02102 } 02103 } 02104 } 02105 02106 // 02107 // Rundown any architectural specific structures 02108 // 02109 02110 KiRundownThread(Thread); 02111 02112 // 02113 // Get off the processor for the last time. 02114 // 02115 02116 KiSwapThread(); 02117 return; 02118 }

BOOLEAN KeTestAlertThread IN KPROCESSOR_MODE  AlertMode  ) 
 

Definition at line 2121 of file thredobj.c.

References _KTHREAD::Alerted, _KAPC_STATE::ApcListHead, _KTHREAD::ApcQueueLock, _KTHREAD::ApcState, ASSERT, DISPATCH_LEVEL, FALSE, KeGetCurrentThread, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), TRUE, _KAPC_STATE::UserApcPending, and UserMode.

Referenced by KiDeliverApc(), and NtTestAlert().

02127 : 02128 02129 This function tests to determine if the alerted variable for the 02130 specified processor mode has a value of TRUE or whether a user mode 02131 APC should be delivered to the current thread. 02132 02133 Arguments: 02134 02135 AlertMode - Supplies the processor mode which is to be tested 02136 for an alerted condition. 02137 02138 Return Value: 02139 02140 The previous state of the alerted variable for the specified processor 02141 mode. 02142 02143 --*/ 02144 02145 { 02146 02147 BOOLEAN Alerted; 02148 KIRQL OldIrql; 02149 PKTHREAD Thread; 02150 02151 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 02152 02153 // 02154 // Raise IRQL to dispatcher level, lock dispatcher database, and lock 02155 // APC queue. 02156 // 02157 02158 Thread = KeGetCurrentThread(); 02159 KiLockDispatcherDatabase(&OldIrql); 02160 KiAcquireSpinLock(&Thread->ApcQueueLock); 02161 02162 // 02163 // If the current thread is alerted for the specified processor mode, 02164 // then clear the alerted state. Else if the specified processor mode 02165 // is user and the current thread's user mode APC queue contains an entry, 02166 // then set user APC pending. 02167 // 02168 02169 Alerted = Thread->Alerted[AlertMode]; 02170 if (Alerted == TRUE) { 02171 Thread->Alerted[AlertMode] = FALSE; 02172 02173 } else if ((AlertMode == UserMode) && 02174 (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) != TRUE)) { 02175 Thread->ApcState.UserApcPending = TRUE; 02176 } 02177 02178 // 02179 // Unlock APC queue, unlock dispatcher database, lower IRQL to its 02180 // previous value, and return the previous alerted state for the 02181 // specified mode. 02182 // 02183 02184 KiReleaseSpinLock(&Thread->ApcQueueLock); 02185 KiUnlockDispatcherDatabase(OldIrql); 02186 return Alerted; 02187 }

VOID KeThawAllThreads VOID   ) 
 

Definition at line 2190 of file thredobj.c.

References ASSERT, DISPATCH_LEVEL, _KTHREAD::FreezeCount, _KSEMAPHORE::Header, KeGetCurrentThread, KeLeaveCriticalRegion, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiWaitTest(), RESUME_INCREMENT, _DISPATCHER_HEADER::SignalState, _KTHREAD::SuspendCount, _KTHREAD::SuspendSemaphore, and _KPROCESS::ThreadListHead.

Referenced by DbgkpResumeProcess().

02196 : 02197 02198 This function resumes the execution of all suspended froozen threads 02199 in the current process. 02200 02201 Arguments: 02202 02203 None. 02204 02205 Return Value: 02206 02207 None. 02208 02209 --*/ 02210 02211 { 02212 02213 PLIST_ENTRY ListHead; 02214 PLIST_ENTRY NextEntry; 02215 PKPROCESS Process; 02216 PKTHREAD Thread; 02217 ULONG OldCount; 02218 KIRQL OldIrql; 02219 02220 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 02221 02222 // 02223 // Get the address of the current current process object, raise IRQL 02224 // to dispatch level, lock dispatcher database, and thaw the execution 02225 // of all threads in the current process that have been frozzen. 02226 // 02227 02228 Process = KeGetCurrentThread()->ApcState.Process; 02229 KiLockDispatcherDatabase(&OldIrql); 02230 ListHead = &Process->ThreadListHead; 02231 NextEntry = ListHead->Flink; 02232 do { 02233 02234 // 02235 // Get the address of the next thread and thaw its execution if 02236 // if was previously froozen. 02237 // 02238 02239 Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry); 02240 OldCount = Thread->FreezeCount; 02241 if (OldCount != 0) { 02242 Thread->FreezeCount -= 1; 02243 02244 // 02245 // If the resultant suspend count is zero and the freeze count is 02246 // zero, then resume the thread by releasing its suspend semaphore. 02247 // 02248 02249 if ((Thread->SuspendCount == 0) && (Thread->FreezeCount == 0)) { 02250 Thread->SuspendSemaphore.Header.SignalState += 1; 02251 KiWaitTest(&Thread->SuspendSemaphore, RESUME_INCREMENT); 02252 } 02253 } 02254 02255 NextEntry = NextEntry->Flink; 02256 } while (NextEntry != ListHead); 02257 02258 // 02259 // Unlock dispatcher database and lower IRQL to its previous 02260 // value. 02261 // 02262 02263 KiUnlockDispatcherDatabase(OldIrql); 02264 KeLeaveCriticalRegion(); 02265 return; 02266 } }


Generated on Sat May 15 19:45:46 2004 for test by doxygen 1.3.7