Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1481 lines
39 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. thredsup.c
  5. Abstract:
  6. This module contains the support routines for the thread object. It
  7. contains functions to boost the priority of a thread, find a ready
  8. thread, select the next thread, ready a thread, set priority of a
  9. thread, and to suspend a thread.
  10. Author:
  11. David N. Cutler (davec) 5-Mar-1989
  12. Environment:
  13. All of the functions in this module execute in kernel mode except
  14. the function that raises a user mode alert condition.
  15. Revision History:
  16. --*/
  17. #include "ki.h"
  18. //
  19. // Define context switch data collection macro.
  20. //
  21. //#define _COLLECT_SWITCH_DATA_ 1
  22. #if defined(_COLLECT_SWITCH_DATA_)
  23. #define KiIncrementSwitchCounter(Member) KeThreadSwitchCounters.Member += 1
  24. #else
  25. #define KiIncrementSwitchCounter(Member)
  26. #endif
  27. VOID
  28. KiSuspendNop (
  29. IN PKAPC Apc,
  30. IN OUT PKNORMAL_ROUTINE *NormalRoutine,
  31. IN OUT PVOID *NormalContext,
  32. IN OUT PVOID *SystemArgument1,
  33. IN OUT PVOID *SystemArgument2
  34. )
  35. /*++
  36. Routine Description:
  37. This function is the kernel routine for the builtin suspend APC for a
  38. thread. It is executed in kernel mode as the result of queuing the
  39. builtin suspend APC and performs no operation. It is called just prior
  40. to calling the normal routine and simply returns.
  41. Arguments:
  42. Apc - Supplies a pointer to a control object of type APC.
  43. NormalRoutine - not used
  44. NormalContext - not used
  45. SystemArgument1 - not used
  46. SystemArgument2 - not used
  47. Return Value:
  48. None.
  49. --*/
  50. {
  51. //
  52. // No operation is performed by this routine.
  53. //
  54. return;
  55. }
  56. VOID
  57. KiSuspendRundown (
  58. IN PKAPC Apc
  59. )
  60. /*++
  61. Routine Description:
  62. This function is the rundown routine for the threads built in suspend APC.
  63. No operation is performed.
  64. Arguments:
  65. Apc - Supplies a pointer to a control object of type APC.
  66. Return Value:
  67. None.
  68. --*/
  69. {
  70. return;
  71. }
  72. PKTHREAD
  73. FASTCALL
  74. KiFindReadyThread (
  75. IN ULONG ProcessorNumber,
  76. IN KPRIORITY LowPriority
  77. )
  78. /*++
  79. Routine Description:
  80. This function searches the dispatcher ready queues from the specified
  81. high priority to the specified low priority in an attempt to find a thread
  82. that can execute on the specified processor.
  83. Arguments:
  84. Processor - Supplies the number of the processor to find a thread for.
  85. LowPriority - Supplies the lowest priority dispatcher ready queue to
  86. examine.
  87. Return Value:
  88. If a thread is located that can execute on the specified processor, then
  89. the address of the thread object is returned. Otherwise a null pointer is
  90. returned.
  91. --*/
  92. {
  93. ULONG HighPriority;
  94. PRLIST_ENTRY ListHead;
  95. PRLIST_ENTRY NextEntry;
  96. ULONG PrioritySet;
  97. KAFFINITY ProcessorSet;
  98. PKTHREAD Thread;
  99. PKTHREAD Thread1;
  100. PKTHREAD Thread2 = NULL;
  101. ULONG WaitLimit;
  102. CCHAR Processor;
  103. //
  104. // Compute the set of priority levels that should be scanned in an attempt
  105. // to find a thread that can run on the specified processor.
  106. //
  107. Processor = (CCHAR)ProcessorNumber;
  108. PrioritySet = (~((1 << LowPriority) - 1)) & KiReadySummary;
  109. #if !defined(NT_UP)
  110. ProcessorSet = AFFINITY_MASK(Processor);
  111. WaitLimit = KiQueryLowTickCount() - (READY_SKIP_QUANTUM + 1);
  112. #endif
  113. KeFindFirstSetLeftMember(PrioritySet, &HighPriority);
  114. ListHead = &KiDispatcherReadyListHead[HighPriority];
  115. PrioritySet <<= (31 - HighPriority);
  116. while (PrioritySet != 0) {
  117. //
  118. // If the next bit in the priority set is a one, then examine the
  119. // corresponding dispatcher ready queue.
  120. //
  121. if ((LONG)PrioritySet < 0) {
  122. NextEntry = ListHead->Flink;
  123. ASSERT(NextEntry != ListHead);
  124. #if defined(NT_UP)
  125. Thread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry);
  126. RemoveEntryList(&Thread->WaitListEntry);
  127. if (IsListEmpty(ListHead)) {
  128. ClearMember(HighPriority, KiReadySummary);
  129. }
  130. return Thread;
  131. #else
  132. //
  133. // Scan the specified dispatcher ready queue for a suitable
  134. // thread to execute.
  135. //
  136. while (NextEntry != ListHead) {
  137. Thread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry);
  138. NextEntry = NextEntry->Flink;
  139. if (Thread->Affinity & ProcessorSet) {
  140. //
  141. // If the found thread ran on the specified processor
  142. // last, the processor is the ideal processor for the
  143. // thread, the thread has been waiting for longer than
  144. // a quantum, or its priority is greater than low realtime
  145. // plus 8, then the selected thread is returned. Otherwise,
  146. // an attempt is made to find a more appropriate thread.
  147. //
  148. if ((Thread->IdealProcessor != Processor) &&
  149. #if defined(KE_MULTINODE)
  150. (!((Thread->NextProcessor == Processor) &&
  151. ((Thread->SoftAffinity & ProcessorSet) != 0))) &&
  152. #else
  153. (Thread->NextProcessor != Processor) &&
  154. #endif
  155. (WaitLimit < Thread->WaitTime) &&
  156. (HighPriority < (LOW_REALTIME_PRIORITY + 9))) {
  157. //
  158. // Search forward in the ready queue until the end
  159. // of the list is reached or a more appropriate
  160. // thread is found.
  161. //
  162. while (NextEntry != ListHead) {
  163. Thread1 = CONTAINING_RECORD(NextEntry,
  164. KTHREAD,
  165. WaitListEntry);
  166. NextEntry = NextEntry->Flink;
  167. if ((Thread1->Affinity & ProcessorSet) == 0) {
  168. continue;
  169. }
  170. if ((Thread1->IdealProcessor == Processor) ||
  171. (Thread1->NextProcessor == Processor)) {
  172. //
  173. // This thread is a better choice than
  174. // the first one but, if this is a multi
  175. // node configuration, and this thread
  176. // isn't on it's prefered node, see if
  177. // there is a better choice.
  178. //
  179. #if defined(KE_MULTINODE)
  180. if (Thread1->SoftAffinity & ProcessorSet) {
  181. Thread = Thread1;
  182. break;
  183. }
  184. //
  185. // Not on preferred node, only update
  186. // "Thread" if this is the first possible.
  187. //
  188. if (Thread2 == NULL) {
  189. Thread2 = Thread1;
  190. Thread = Thread1;
  191. }
  192. #else
  193. Thread = Thread1;
  194. break;
  195. #endif
  196. }
  197. if (WaitLimit >= Thread1->WaitTime) {
  198. //
  199. // This thread has been ready without
  200. // running for too long, select it.
  201. //
  202. Thread = Thread1;
  203. break;
  204. }
  205. }
  206. }
  207. #if defined(_COLLECT_SWITCH_DATA_)
  208. if (Processor == Thread->IdealProcessor) {
  209. KiIncrementSwitchCounter(FindIdeal);
  210. } else if (Processor == Thread->NextProcessor) {
  211. KiIncrementSwitchCounter(FindLast);
  212. } else {
  213. KiIncrementSwitchCounter(FindAny);
  214. }
  215. #endif
  216. Thread->NextProcessor = Processor;
  217. RemoveEntryList(&Thread->WaitListEntry);
  218. if (IsListEmpty(ListHead)) {
  219. ClearMember(HighPriority, KiReadySummary);
  220. }
  221. return Thread;
  222. }
  223. }
  224. #endif
  225. }
  226. HighPriority -= 1;
  227. ListHead -= 1;
  228. PrioritySet <<= 1;
  229. };
  230. //
  231. // No thread could be found, return a null pointer.
  232. //
  233. return NULL;
  234. }
  235. VOID
  236. FASTCALL
  237. KiReadyThread (
  238. IN PKTHREAD Thread
  239. )
  240. /*++
  241. Routine Description:
  242. This function readies a thread for execution and attempts to immediately
  243. dispatch the thread for execution by preempting another lower priority
  244. thread. If a thread can be preempted, then the specified thread enters
  245. the standby state and the target processor is requested to dispatch. If
  246. another thread cannot be preempted, then the specified thread is inserted
  247. either at the head or tail of the dispatcher ready selected by its priority
  248. acccording to whether it was preempted or not.
  249. Arguments:
  250. Thread - Supplies a pointer to a dispatcher object of type thread.
  251. Return Value:
  252. None.
  253. --*/
  254. {
  255. PKPRCB Prcb;
  256. PKPRCB TargetPrcb;
  257. BOOLEAN Preempted;
  258. KPRIORITY Priority;
  259. PKPROCESS Process;
  260. ULONG Processor;
  261. KPRIORITY ThreadPriority;
  262. PKTHREAD Thread1;
  263. KAFFINITY IdleSet;
  264. KAFFINITY Affinity;
  265. KAFFINITY FavoredSMTSet;
  266. //
  267. // Save value of thread's preempted flag, set thread preempted FALSE,
  268. // capture the thread priority, and set clear the read wait time.
  269. //
  270. Preempted = Thread->Preempted;
  271. Thread->Preempted = FALSE;
  272. ThreadPriority = Thread->Priority;
  273. Thread->WaitTime = KiQueryLowTickCount();
  274. //
  275. // If the thread's process is not in memory, then insert the thread in
  276. // the process ready queue and inswap the process.
  277. //
  278. Process = Thread->ApcState.Process;
  279. if (Process->State != ProcessInMemory) {
  280. Thread->State = Ready;
  281. Thread->ProcessReadyQueue = TRUE;
  282. InsertTailList(&Process->ReadyListHead, &Thread->WaitListEntry);
  283. if (Process->State == ProcessOutOfMemory) {
  284. Process->State = ProcessInTransition;
  285. InterlockedPushEntrySingleList(&KiProcessInSwapListHead,
  286. &Process->SwapListEntry);
  287. KiSetSwapEvent();
  288. }
  289. return;
  290. } else if (Thread->KernelStackResident == FALSE) {
  291. //
  292. // The thread's kernel stack is not resident. Increment the process
  293. // stack count, set the state of the thread to transition, insert
  294. // the thread in the kernel stack inswap list, and set the kernel
  295. // stack inswap event.
  296. //
  297. Process->StackCount += 1;
  298. Thread->State = Transition;
  299. InterlockedPushEntrySingleList(&KiStackInSwapListHead,
  300. &Thread->SwapListEntry);
  301. KiSetSwapEvent();
  302. return;
  303. } else {
  304. //
  305. // Assume we will succeed in scheduling this thread.
  306. //
  307. Thread->State = Standby;
  308. //
  309. // If there is an idle processor, then schedule the thread on an
  310. // idle processor giving preference to:
  311. //
  312. // (a) the thread's ideal processor,
  313. //
  314. // (b) if the thread has a soft (preferred affinity set) and
  315. // that set contains an idle processor, reduce the set to
  316. // the intersection of the two sets.
  317. //
  318. // (c) if the processors are Simultaneous Multi Threaded, and the
  319. // set contains physical processors with no busy logical
  320. // processors, reduce the set to that subset.
  321. //
  322. // (d) if this thread last ran on a member of this remaining set,
  323. // select that processor, otherwise,
  324. //
  325. // (e) if there are processors amongst the remainder which are
  326. // not sleeping, reduce to that subset.
  327. //
  328. // (f) select the leftmost processor from this set.
  329. //
  330. #if defined(NT_UP)
  331. Prcb = KiProcessorBlock[0];
  332. if (KiIdleSummary != 0) {
  333. KiIdleSummary = 0;
  334. KiIncrementSwitchCounter(IdleLast);
  335. Prcb->NextThread = Thread;
  336. return;
  337. }
  338. #else
  339. Processor = Thread->IdealProcessor;
  340. #if defined(NT_SMT)
  341. FavoredSMTSet = KiProcessorBlock[Processor]->MultiThreadProcessorSet;
  342. #endif
  343. Affinity = Thread->Affinity;
  344. if (Affinity & Thread->SoftAffinity) {
  345. Affinity &= Thread->SoftAffinity;
  346. }
  347. IdleSet = KiIdleSummary & Affinity;
  348. if (IdleSet != 0) {
  349. Prcb = KeGetCurrentPrcb();
  350. if ((IdleSet & AFFINITY_MASK(Processor)) == 0) {
  351. //
  352. // Ideal processor is not available.
  353. //
  354. // Next highest priority to a physical processor in
  355. // which all logical processors are idle.
  356. //
  357. #if defined(NT_SMT)
  358. if (IdleSet & KiIdleSMTSummary) {
  359. IdleSet &= KiIdleSMTSummary;
  360. }
  361. #endif
  362. //
  363. // Try processor this thread last ran on.
  364. //
  365. Processor = Thread->NextProcessor;
  366. if ((IdleSet & AFFINITY_MASK(Processor)) == 0) {
  367. if ((IdleSet & Prcb->SetMember) == 0) {
  368. //
  369. // Select from idle processors.
  370. //
  371. //
  372. // Try ANY logical processor in the same
  373. // physical processor as the Ideal Processor.
  374. //
  375. #if defined(NT_SMT)
  376. if (IdleSet & FavoredSMTSet) {
  377. IdleSet &= FavoredSMTSet;
  378. } else {
  379. //
  380. // No logical processor in the ideal set, try
  381. // same set as thread last ran in.
  382. //
  383. FavoredSMTSet = KiProcessorBlock[Processor]->MultiThreadProcessorSet;
  384. if (IdleSet & FavoredSMTSet) {
  385. IdleSet &= FavoredSMTSet;
  386. }
  387. }
  388. #endif
  389. if ((IdleSet & ~PoSleepingSummary) != 0) {
  390. //
  391. // Choose an idle processor which is
  392. // not sleeping.
  393. //
  394. IdleSet &= ~PoSleepingSummary;
  395. }
  396. KeFindFirstSetLeftAffinity(IdleSet, &Processor);
  397. KiIncrementSwitchCounter(IdleAny);
  398. } else {
  399. Processor = Prcb->Number;
  400. KiIncrementSwitchCounter(IdleCurrent);
  401. }
  402. } else {
  403. KiIncrementSwitchCounter(IdleLast);
  404. }
  405. } else {
  406. KiIncrementSwitchCounter(IdleIdeal);
  407. }
  408. TargetPrcb = KiProcessorBlock[Processor];
  409. Thread->NextProcessor = (CCHAR)Processor;
  410. ClearMember(Processor, KiIdleSummary);
  411. TargetPrcb->NextThread = Thread;
  412. //
  413. // Update the idle set summary (SMT) to indicate this
  414. // physical processor is not all idle.
  415. //
  416. #if defined(NT_SMT)
  417. KiIdleSMTSummary &= ~TargetPrcb->MultiThreadProcessorSet;
  418. TargetPrcb->MultiThreadSetMaster->MultiThreadSetBusy = TRUE;
  419. #endif
  420. if ((PoSleepingSummary & AFFINITY_MASK(Processor)) &&
  421. (Processor != (ULONG)Prcb->Number)) {
  422. KiIpiSend(AFFINITY_MASK(Processor), IPI_DPC);
  423. }
  424. return;
  425. }
  426. #endif
  427. //
  428. // No idle processors, try to preempt a thread in either the
  429. // standby or running state.
  430. //
  431. #if !defined(NT_UP)
  432. if ((Affinity & AFFINITY_MASK(Processor)) == 0) {
  433. //
  434. // Check if thread can run in the same place it
  435. // ran last time.
  436. //
  437. Processor = Thread->NextProcessor;
  438. if ((Affinity & AFFINITY_MASK(Processor)) == 0) {
  439. //
  440. // Select leftmost processor from the available
  441. // set.
  442. //
  443. KeFindFirstSetLeftAffinity(Affinity, &Processor);
  444. }
  445. }
  446. Thread->NextProcessor = (CCHAR)Processor;
  447. Prcb = KiProcessorBlock[Processor];
  448. #endif
  449. Thread1 = Prcb->NextThread;
  450. if (Thread1 != NULL) {
  451. if (ThreadPriority > Thread1->Priority) {
  452. PKSPIN_LOCK_QUEUE ContextSwap;
  453. //
  454. // Preempt the thread scheduled to run on the selected
  455. // processor.
  456. //
  457. Thread1->Preempted = TRUE;
  458. //
  459. // The thread could migrate from Standby to Running under the
  460. // context swap lock.
  461. //
  462. #if !defined(NT_UP)
  463. ContextSwap = &(KeGetCurrentPrcb()->LockQueue[LockQueueContextSwapLock]);
  464. KeAcquireQueuedSpinLockAtDpcLevel(ContextSwap);
  465. if (Prcb->NextThread != NULL) {
  466. //
  467. // The thread is still in Standby state, substitute the
  468. // new selected thread.
  469. //
  470. Prcb->NextThread = Thread;
  471. KeReleaseQueuedSpinLockFromDpcLevel(ContextSwap);
  472. KiReadyThread(Thread1);
  473. KiIncrementSwitchCounter(PreemptLast);
  474. return;
  475. } else {
  476. //
  477. // The thread has migrated to the running state.
  478. //
  479. KeReleaseQueuedSpinLockFromDpcLevel(ContextSwap);
  480. Prcb->NextThread = Thread;
  481. KiRequestDispatchInterrupt(Thread->NextProcessor);
  482. KiIncrementSwitchCounter(PreemptLast);
  483. return;
  484. }
  485. #else
  486. Prcb->NextThread = Thread;
  487. KiReadyThread(Thread1);
  488. KiIncrementSwitchCounter(PreemptLast);
  489. return;
  490. #endif
  491. }
  492. } else {
  493. Thread1 = Prcb->CurrentThread;
  494. if (ThreadPriority > Thread1->Priority) {
  495. Thread1->Preempted = TRUE;
  496. Prcb->NextThread = Thread;
  497. KiRequestDispatchInterrupt(Thread->NextProcessor);
  498. KiIncrementSwitchCounter(PreemptLast);
  499. return;
  500. }
  501. }
  502. }
  503. //
  504. // No thread can be preempted. Insert the thread in the dispatcher
  505. // queue selected by its priority. If the thread was preempted and
  506. // runs at a realtime priority level, then insert the thread at the
  507. // front of the queue. Else insert the thread at the tail of the queue.
  508. //
  509. Thread->State = Ready;
  510. if (Preempted != FALSE) {
  511. InsertHeadList(&KiDispatcherReadyListHead[ThreadPriority],
  512. &Thread->WaitListEntry);
  513. } else {
  514. InsertTailList(&KiDispatcherReadyListHead[ThreadPriority],
  515. &Thread->WaitListEntry);
  516. }
  517. SetMember(ThreadPriority, KiReadySummary);
  518. return;
  519. }
  520. PKTHREAD
  521. FASTCALL
  522. KiSelectNextThread (
  523. IN ULONG Processor
  524. )
  525. /*++
  526. Routine Description:
  527. This function selects the next thread to run on the specified processor.
  528. Arguments:
  529. Processor - Supplies the processor number.
  530. Return Value:
  531. The address of the selected thread object.
  532. --*/
  533. {
  534. PKPRCB Prcb;
  535. PKTHREAD Thread;
  536. //
  537. // Attempt to find a ready thread to run.
  538. //
  539. // If a thread was not found, then select the idle thread and
  540. // set the processor member in the idle summary.
  541. //
  542. if ((Thread = KiFindReadyThread(Processor, 0)) == NULL) {
  543. Prcb = KiProcessorBlock[Processor];
  544. KiIncrementSwitchCounter(SwitchToIdle);
  545. Thread = Prcb->IdleThread;
  546. KiIdleSummary |= AFFINITY_MASK(Processor);
  547. //
  548. // If all logical processors of the physical processor are idle,
  549. // then update the idle SMT set summary.
  550. //
  551. #if defined(NT_SMT)
  552. if ((KiIdleSummary & Prcb->MultiThreadProcessorSet) ==
  553. Prcb->MultiThreadProcessorSet) {
  554. KiIdleSMTSummary |= Prcb->MultiThreadProcessorSet;
  555. Prcb->MultiThreadSetMaster->MultiThreadSetBusy = FALSE;
  556. }
  557. #endif
  558. }
  559. //
  560. // Return address of selected thread object.
  561. //
  562. return Thread;
  563. }
  564. KAFFINITY
  565. FASTCALL
  566. KiSetAffinityThread (
  567. IN PKTHREAD Thread,
  568. IN KAFFINITY Affinity
  569. )
  570. /*++
  571. Routine Description:
  572. This function sets the affinity of a specified thread to a new value.
  573. If the new affinity is not a proper subset of the parent process affinity
  574. or is null, then a bugcheck occurs. If the specified thread is running on
  575. or about to run on a processor for which it is no longer able to run, then
  576. the target processor is rescheduled. If the specified thread is in a ready
  577. state and is not in the parent process ready queue, then it is rereadied
  578. to reevaluate any additional processors it may run on.
  579. Arguments:
  580. Thread - Supplies a pointer to a dispatcher object of type thread.
  581. Affinity - Supplies the new of set of processors on which the thread
  582. can run.
  583. Return Value:
  584. The previous affinity of the specified thread is returned as the function
  585. value.
  586. --*/
  587. {
  588. KAFFINITY OldAffinity;
  589. PKPRCB Prcb;
  590. PKPROCESS Process;
  591. ULONG Processor;
  592. KPRIORITY ThreadPriority;
  593. PKTHREAD Thread1;
  594. //
  595. // Capture the current affinity of the specified thread and get address
  596. // of parent process object.
  597. //
  598. OldAffinity = Thread->UserAffinity;
  599. Process = Thread->ApcStatePointer[0]->Process;
  600. //
  601. // If new affinity is not a proper subset of the parent process affinity
  602. // or the new affinity is null, then bugcheck.
  603. //
  604. if (((Affinity & Process->Affinity) != (Affinity)) || (!Affinity)) {
  605. KeBugCheck(INVALID_AFFINITY_SET);
  606. }
  607. //
  608. // Set the thread user affinity to the specified value.
  609. //
  610. // If the thread is not current executing with system affinity active,
  611. // then set the thread current affinity and switch on the thread state.
  612. //
  613. Thread->UserAffinity = Affinity;
  614. if (Thread->SystemAffinityActive == FALSE) {
  615. Thread->Affinity = Affinity;
  616. switch (Thread->State) {
  617. //
  618. // Ready State.
  619. //
  620. // If the thread is not in the process ready queue, then remove
  621. // it from its current dispatcher ready queue and reready it for
  622. // execution.
  623. //
  624. case Ready:
  625. if (Thread->ProcessReadyQueue == FALSE) {
  626. RemoveEntryList(&Thread->WaitListEntry);
  627. ThreadPriority = Thread->Priority;
  628. if (IsListEmpty(&KiDispatcherReadyListHead[ThreadPriority]) != FALSE) {
  629. ClearMember(ThreadPriority, KiReadySummary);
  630. }
  631. KiReadyThread(Thread);
  632. }
  633. break;
  634. //
  635. // Standby State.
  636. //
  637. // If the target processor is not in the new affinity set, then
  638. // set the next thread to null for the target processor, select
  639. // a new thread to run on the target processor, and reready the
  640. // thread for execution.
  641. //
  642. // It is possible for a thread to transition from Standby to
  643. // Running even though the dispatcher lock is held by this
  644. // processor. The context swap lock must be taken to ensure
  645. // correct behavior (in this rare case).
  646. //
  647. case Standby:
  648. Processor = Thread->NextProcessor;
  649. Prcb = KiProcessorBlock[Processor];
  650. if ((Prcb->SetMember & Affinity) == 0) {
  651. Thread1 = KiSelectNextThread(Processor);
  652. Thread1->State = Standby;
  653. KeAcquireQueuedSpinLockAtDpcLevel(
  654. &KeGetCurrentPrcb()->LockQueue[LockQueueContextSwapLock]);
  655. if (Prcb->NextThread != NULL) {
  656. //
  657. // The thread is still in Standby state, substitute
  658. // the new selected thread.
  659. //
  660. Prcb->NextThread = Thread1;
  661. KeReleaseQueuedSpinLockFromDpcLevel(
  662. &KeGetCurrentPrcb()->LockQueue[LockQueueContextSwapLock]);
  663. KiReadyThread(Thread);
  664. } else {
  665. //
  666. // The thread has become ready.
  667. //
  668. KeReleaseQueuedSpinLockFromDpcLevel(
  669. &KeGetCurrentPrcb()->LockQueue[LockQueueContextSwapLock]);
  670. Prcb->NextThread = Thread1;
  671. KiRequestDispatchInterrupt(Processor);
  672. }
  673. }
  674. break;
  675. //
  676. // Running State.
  677. //
  678. // If the target processor is not in the new affinity set and
  679. // another thread has not already been selected for execution
  680. // on the target processor, then select a new thread for the
  681. // target processor, and cause the target processor to be
  682. // redispatched.
  683. //
  684. case Running:
  685. Processor = Thread->NextProcessor;
  686. Prcb = KiProcessorBlock[Processor];
  687. //
  688. // It is possible the thread is just switching from
  689. // Standby to Running on an idle processor which is
  690. // not holding the dispatcher lock.
  691. //
  692. if (((Prcb->SetMember & Affinity) == 0) &&
  693. ((Prcb->NextThread == NULL) || (Prcb->NextThread == Thread))) {
  694. Thread1 = KiSelectNextThread(Processor);
  695. Thread1->State = Standby;
  696. Prcb->NextThread = Thread1;
  697. KiRequestDispatchInterrupt(Processor);
  698. }
  699. break;
  700. //
  701. // Initialized, Terminated, Waiting, Transition case - For these
  702. // states it is sufficient to just set the new thread affinity.
  703. //
  704. default:
  705. break;
  706. }
  707. }
  708. //
  709. // Return the previous user affinity.
  710. //
  711. return OldAffinity;
  712. }
  713. VOID
  714. FASTCALL
  715. KiSetPriorityThread (
  716. IN PKTHREAD Thread,
  717. IN KPRIORITY Priority
  718. )
  719. /*++
  720. Routine Description:
  721. This function set the priority of the specified thread to the specified
  722. value. If the thread is in the standby or running state, then the processor
  723. may be redispatched. If the thread is in the ready state, then some other
  724. thread may be preempted.
  725. Arguments:
  726. Thread - Supplies a pointer to a dispatcher object of type thread.
  727. Priority - Supplies the new thread priority value.
  728. Return Value:
  729. None.
  730. --*/
  731. {
  732. PKPRCB Prcb;
  733. ULONG Processor;
  734. KPRIORITY ThreadPriority;
  735. PKTHREAD Thread1;
  736. ASSERT(Priority <= HIGH_PRIORITY);
  737. //
  738. // Capture the current priority of the specified thread.
  739. //
  740. ThreadPriority = Thread->Priority;
  741. //
  742. // If the new priority is not equal to the old priority, then set the
  743. // new priority of the thread and redispatch a processor if necessary.
  744. //
  745. if (Priority != ThreadPriority) {
  746. Thread->Priority = (SCHAR)Priority;
  747. //
  748. // Case on the thread state.
  749. //
  750. switch (Thread->State) {
  751. //
  752. // Ready case - If the thread is not in the process ready queue,
  753. // then remove it from its current dispatcher ready queue. If the
  754. // new priority is less than the old priority, then insert the
  755. // thread at the tail of the dispatcher ready queue selected by
  756. // the new priority. Else reready the thread for execution.
  757. //
  758. case Ready:
  759. if (Thread->ProcessReadyQueue == FALSE) {
  760. RemoveEntryList(&Thread->WaitListEntry);
  761. if (IsListEmpty(&KiDispatcherReadyListHead[ThreadPriority])) {
  762. ClearMember(ThreadPriority, KiReadySummary);
  763. }
  764. if (Priority < ThreadPriority) {
  765. InsertTailList(&KiDispatcherReadyListHead[Priority],
  766. &Thread->WaitListEntry);
  767. SetMember(Priority, KiReadySummary);
  768. } else {
  769. KiReadyThread(Thread);
  770. }
  771. }
  772. break;
  773. //
  774. // Standby case - If the thread's priority is being lowered, then
  775. // attempt to find another thread to execute. If a new thread is
  776. // found, then put the new thread in the standby state, and reready
  777. // the old thread.
  778. //
  779. case Standby:
  780. if (Priority < ThreadPriority) {
  781. #if defined(NT_UP)
  782. Thread1 = KiFindReadyThread(0, Priority + 1);
  783. if (Thread1 != NULL) {
  784. Prcb = KiProcessorBlock[0];
  785. Thread1->State = Standby;
  786. Prcb->NextThread = Thread1;
  787. KiReadyThread(Thread);
  788. }
  789. #else
  790. Processor = Thread->NextProcessor;
  791. Thread1 = KiFindReadyThread(Processor, Priority + 1);
  792. if (Thread1 != NULL) {
  793. Prcb = KiProcessorBlock[Processor];
  794. Thread1->State = Standby;
  795. KeAcquireQueuedSpinLockAtDpcLevel(
  796. &KeGetCurrentPrcb()->LockQueue[LockQueueContextSwapLock]);
  797. if (Prcb->NextThread != NULL) {
  798. //
  799. // The thread is still in Standby state, substitute
  800. // the new selected thread.
  801. //
  802. Prcb->NextThread = Thread1;
  803. KeReleaseQueuedSpinLockFromDpcLevel(
  804. &KeGetCurrentPrcb()->LockQueue[LockQueueContextSwapLock]);
  805. KiReadyThread(Thread);
  806. } else {
  807. //
  808. // The thread has transitioned from Standby
  809. // to running, treat as if running.
  810. //
  811. KeReleaseQueuedSpinLockFromDpcLevel(
  812. &KeGetCurrentPrcb()->LockQueue[LockQueueContextSwapLock]);
  813. Prcb->NextThread = Thread1;
  814. KiRequestDispatchInterrupt(Processor);
  815. }
  816. }
  817. #endif
  818. }
  819. break;
  820. //
  821. // Running case - If there is not a thread in the standby state
  822. // on the thread's processor and the thread's priority is being
  823. // lowered, then attempt to find another thread to execute. If
  824. // a new thread is found, then put the new thread in the standby
  825. // state, and request a redispatch on the thread's processor.
  826. //
  827. case Running:
  828. if (Priority < ThreadPriority) {
  829. #if defined(NT_UP)
  830. Prcb = KiProcessorBlock[0];
  831. if (Prcb->NextThread == NULL) {
  832. Thread1 = KiFindReadyThread(0, Priority + 1);
  833. if (Thread1 != NULL) {
  834. Thread1->State = Standby;
  835. Prcb->NextThread = Thread1;
  836. }
  837. }
  838. #else
  839. Processor = Thread->NextProcessor;
  840. Prcb = KiProcessorBlock[Processor];
  841. //
  842. // It is possible the thread is just switching from
  843. // Standby to Running on an idle processor which has
  844. // not yet cleared the NextThread field.
  845. //
  846. if ((Prcb->NextThread == NULL) ||
  847. (Prcb->NextThread == Thread)) {
  848. Thread1 = KiFindReadyThread(Processor, Priority + 1);
  849. if (Thread1 != NULL) {
  850. Thread1->State = Standby;
  851. Prcb->NextThread = Thread1;
  852. KiRequestDispatchInterrupt(Processor);
  853. }
  854. }
  855. #endif
  856. }
  857. break;
  858. //
  859. // Initialized, Terminated, Waiting, Transition case - For
  860. // these states it is sufficient to just set the new thread
  861. // priority.
  862. //
  863. default:
  864. break;
  865. }
  866. }
  867. return;
  868. }
  869. VOID
  870. KiSuspendThread (
  871. IN PVOID NormalContext,
  872. IN PVOID SystemArgument1,
  873. IN PVOID SystemArgument2
  874. )
  875. /*++
  876. Routine Description:
  877. This function is the kernel routine for the builtin suspend APC of a
  878. thread. It is executed as the result of queuing the builtin suspend
  879. APC and suspends thread execution by waiting nonalerable on the thread's
  880. builtin suspend semaphore. When the thread is resumed, execution of
  881. thread is continued by simply returning.
  882. Arguments:
  883. NormalContext - Not used.
  884. SystemArgument1 - Not used.
  885. SystemArgument2 - Not used.
  886. Return Value:
  887. None.
  888. --*/
  889. {
  890. PKTHREAD Thread;
  891. //
  892. // Get the address of the current thread object and Wait nonalertable on
  893. // the thread's builtin suspend semaphore.
  894. //
  895. Thread = KeGetCurrentThread();
  896. KeWaitForSingleObject(&Thread->SuspendSemaphore,
  897. Suspended,
  898. KernelMode,
  899. FALSE,
  900. NULL);
  901. return;
  902. }
  903. LONG_PTR
  904. FASTCALL
  905. KiSwapThread (
  906. VOID
  907. )
  908. /*++
  909. Routine Description:
  910. This function selects the next thread to run on the current processor
  911. and swaps thread context to the selected thread. When the execution
  912. of the current thread is resumed, the IRQL is lowered to its previous
  913. value and the wait status is returned as the function value.
  914. N.B. This function is only called by the wait functions. On entry to this
  915. routine the dispatcher lock is held. On exit from this routine the
  916. dispatcher lock is not held and the IRQL is lowered to its value at
  917. the start of the wait operation.
  918. Arguments:
  919. None.
  920. Return Value:
  921. The wait completion status is returned as the function value.
  922. --*/
  923. {
  924. PKTHREAD NewThread;
  925. CCHAR Number;
  926. PKTHREAD OldThread;
  927. BOOLEAN Pending;
  928. PKPRCB Prcb;
  929. KIRQL WaitIrql;
  930. LONG_PTR WaitStatus;
  931. //
  932. // If a thread has already been selected to run on the current processor,
  933. // then select that thread.
  934. //
  935. Prcb = KeGetCurrentPrcb();
  936. OldThread = Prcb->CurrentThread;
  937. if ((NewThread = Prcb->NextThread) != NULL) {
  938. Prcb->NextThread = NULL;
  939. } else {
  940. //
  941. // Attempt to find a ready thread to run.
  942. //
  943. // If a thread was not found, then select the idle thread and set the
  944. // processor member in the idle summary.
  945. //
  946. Number = Prcb->Number;
  947. if ((NewThread = KiFindReadyThread(Number, 0)) == NULL) {
  948. KiIncrementSwitchCounter(SwitchToIdle);
  949. NewThread = Prcb->IdleThread;
  950. KiIdleSummary |= AFFINITY_MASK(Number);
  951. //
  952. // If all logical processors of the physical processor are idle,
  953. // then update the idle SMT set summary.
  954. //
  955. #if defined(NT_SMT)
  956. if ((KiIdleSummary & Prcb->MultiThreadProcessorSet) ==
  957. Prcb->MultiThreadProcessorSet) {
  958. KiIdleSMTSummary |= Prcb->MultiThreadProcessorSet;
  959. Prcb->MultiThreadSetMaster->MultiThreadSetBusy = FALSE;
  960. }
  961. #endif
  962. }
  963. }
  964. //
  965. // Swap context to the new thread.
  966. //
  967. // If a kernel APC should be delivered on return from the context swap,
  968. // then deliver the kernel APC.
  969. //
  970. Pending = KiSwapContext(NewThread);
  971. WaitIrql = OldThread->WaitIrql;
  972. WaitStatus = OldThread->WaitStatus;
  973. if (Pending != FALSE) {
  974. KeLowerIrql(APC_LEVEL);
  975. KiDeliverApc(KernelMode, NULL, NULL);
  976. WaitIrql = 0;
  977. }
  978. //
  979. // Lower IRQL to its level before the wait operation and return the wait
  980. // status.
  981. //
  982. KeLowerIrql(WaitIrql);
  983. return WaitStatus;
  984. }
  985. UCHAR
  986. KeFindNextRightSetAffinity (
  987. ULONG Number,
  988. KAFFINITY Set
  989. )
  990. /*++
  991. Routine Description:
  992. This function locates the left most set bit in the set immediately to
  993. the right of the specified bit. If no bits are set to the right of the
  994. specified bit, then the left most set bit in the complete set is located.
  995. N.B. Set must contain at least one bit.
  996. Arguments:
  997. Number - Supplies the bit number from which the search to to begin.
  998. Set - Supplies the bit mask to search.
  999. Return Value:
  1000. The number of the found set bit is returned as the function value.
  1001. --*/
  1002. {
  1003. KAFFINITY NewSet;
  1004. ULONG Temp;
  1005. ASSERT(Set != 0);
  1006. //
  1007. // Get a mask with all bits to the right of bit "Number" set.
  1008. //
  1009. NewSet = (AFFINITY_MASK(Number) - 1) & Set;
  1010. //
  1011. // If no bits are set to the right of the specified bit number, then use
  1012. // the complete set.
  1013. //
  1014. if (NewSet == 0) {
  1015. NewSet = Set;
  1016. }
  1017. //
  1018. // Find leftmost bit in this set.
  1019. //
  1020. KeFindFirstSetLeftAffinity(NewSet, &Temp);
  1021. return (UCHAR)Temp;
  1022. }
  1023. #if 0
  1024. VOID
  1025. KiVerifyReadySummary (
  1026. VOID
  1027. )
  1028. /*++
  1029. Routine Description:
  1030. This function verifies the correctness of ready summary.
  1031. Arguments:
  1032. None.
  1033. Return Value:
  1034. None.
  1035. --*/
  1036. {
  1037. ULONG Index;
  1038. ULONG Summary;
  1039. PKTHREAD Thread;
  1040. extern ULONG InitializationPhase;
  1041. //
  1042. // If initilization has been completed, then check the ready summary
  1043. //
  1044. if (InitializationPhase == 2) {
  1045. //
  1046. // Scan the ready queues and compute the ready summary.
  1047. //
  1048. Summary = 0;
  1049. for (Index = 0; Index < MAXIMUM_PRIORITY; Index += 1) {
  1050. if (IsListEmpty(&KiDispatcherReadyListHead[Index]) == FALSE) {
  1051. Summary |= (1 << Index);
  1052. }
  1053. }
  1054. //
  1055. // If the computed summary does not agree with the current ready
  1056. // summary, then break into the debugger.
  1057. //
  1058. if (Summary != KiReadySummary) {
  1059. DbgBreakPoint();
  1060. }
  1061. //
  1062. // If the priority of the current thread or the next thread is
  1063. // not greater than or equal to all ready threads, then break
  1064. // into the debugger.
  1065. //
  1066. Thread = KeGetCurrentPrcb()->NextThread;
  1067. if (Thread == NULL) {
  1068. Thread = KeGetCurrentPrcb()->CurrentThread;
  1069. }
  1070. if ((1 << Thread->Priority) < (Summary & ((1 << Thread->Priority) - 1))) {
  1071. DbgBreakPoint();
  1072. }
  1073. }
  1074. return;
  1075. }
  1076. #endif