Leaked source code of windows server 2003
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.

2151 lines
62 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. --*/
  16. #include "ki.h"
  17. VOID
  18. KiSuspendNop (
  19. IN PKAPC Apc,
  20. IN OUT PKNORMAL_ROUTINE *NormalRoutine,
  21. IN OUT PVOID *NormalContext,
  22. IN OUT PVOID *SystemArgument1,
  23. IN OUT PVOID *SystemArgument2
  24. )
  25. /*++
  26. Routine Description:
  27. This function is the kernel routine for the builtin suspend APC for a
  28. thread. It is executed in kernel mode as the result of queuing the
  29. builtin suspend APC.
  30. Arguments:
  31. Apc - Supplies a pointer to a control object of type APC.
  32. NormalRoutine - not used
  33. NormalContext - not used
  34. SystemArgument1 - not used
  35. SystemArgument2 - not used
  36. Return Value:
  37. None.
  38. --*/
  39. {
  40. UNREFERENCED_PARAMETER(Apc);
  41. UNREFERENCED_PARAMETER(NormalRoutine);
  42. UNREFERENCED_PARAMETER(NormalContext);
  43. UNREFERENCED_PARAMETER(SystemArgument1);
  44. UNREFERENCED_PARAMETER(SystemArgument2);
  45. //
  46. // No operation is performed by this routine.
  47. //
  48. return;
  49. }
  50. VOID
  51. KiSuspendRundown (
  52. IN PKAPC Apc
  53. )
  54. /*++
  55. Routine Description:
  56. This function is the rundown routine for the threads built in suspend APC.
  57. Arguments:
  58. Apc - Supplies a pointer to a control object of type APC.
  59. Return Value:
  60. None.
  61. --*/
  62. {
  63. UNREFERENCED_PARAMETER(Apc);
  64. //
  65. // No operation is performed by this routine.
  66. //
  67. return;
  68. }
  69. VOID
  70. FASTCALL
  71. KiDeferredReadyThread (
  72. IN PKTHREAD Thread
  73. )
  74. /*++
  75. Routine Description:
  76. This function readies a thread for execution and attempts to dispatch the
  77. thread for execution by either assigning the thread to an idle processor
  78. or preempting another lower priority thread.
  79. If the thread can be assigned to an idle procesor, then the thread enters
  80. the standby state and the target processor will switch to the thread on
  81. its next iteration of the idle loop.
  82. If a lower priority thread can be preempted, then the thread enters the
  83. standby state and the target processor is requested to dispatch.
  84. If the thread cannot be assigned to an idle processor and another thread
  85. cannot be preempted, then the specified thread is inserted at the head or
  86. tail of the dispatcher ready selected by its priority depending on whether
  87. it was preempted or not.
  88. N.B. This function is called at SYNCH level with no PRCB locks held.
  89. N.B. This function may be called with the dispatcher database lock held.
  90. N.B. Neither the priority nor the affinity of a thread in the deferred
  91. ready state can be changed outside the PRCB lock of the respective
  92. processor.
  93. Arguments:
  94. Thread - Supplies a pointer to a dispatcher object of type thread.
  95. Return Value:
  96. None.
  97. --*/
  98. {
  99. PKPRCB CurrentPrcb;
  100. BOOLEAN Preempted;
  101. KPRIORITY Priority;
  102. PKPROCESS Process;
  103. ULONG Processor;
  104. PKPRCB TargetPrcb;
  105. KPRIORITY ThreadPriority;
  106. PKTHREAD Thread1;
  107. #if !defined(NT_UP)
  108. KAFFINITY Affinity;
  109. ULONG IdealProcessor;
  110. KAFFINITY IdleSet;
  111. PKNODE Node;
  112. #endif
  113. #if defined(NT_SMT)
  114. KAFFINITY FavoredSMTSet;
  115. #endif
  116. ASSERT(Thread->State == DeferredReady);
  117. ASSERT((Thread->Priority >= 0) && (Thread->Priority <= HIGH_PRIORITY));
  118. //
  119. // Check if a priority adjustment is requested.
  120. //
  121. if (Thread->AdjustReason == AdjustNone) {
  122. //
  123. // No priority adjustment.
  124. //
  125. NOTHING;
  126. } else if (Thread->AdjustReason == AdjustBoost) {
  127. //
  128. // Priority adjustment as the result of a set event boost priority.
  129. //
  130. // The current thread priority is stored in the adjust increment
  131. // field of the thread object.
  132. //
  133. // Acquire the thread lock.
  134. //
  135. // If the priority of the waiting thread is less than or equal
  136. // to the priority of the current thread and the waiting thread
  137. // priority is less than the time critical priority bound and
  138. // boosts are not disabled for the waiting thread, then boost
  139. // the priority of the waiting thread to the minimum of the
  140. // priority of the current thread priority plus one and the time
  141. // critical bound minus one. This boost will be taken away at
  142. // quantum end.
  143. //
  144. KiAcquireThreadLock(Thread);
  145. if ((Thread->Priority <= Thread->AdjustIncrement) &&
  146. (Thread->Priority < (TIME_CRITICAL_PRIORITY_BOUND - 1)) &&
  147. (Thread->DisableBoost == FALSE)) {
  148. //
  149. // Compute the new thread priority.
  150. //
  151. Priority = min(Thread->AdjustIncrement + 1,
  152. TIME_CRITICAL_PRIORITY_BOUND - 1);
  153. ASSERT((Thread->PriorityDecrement >= 0) &&
  154. (Thread->PriorityDecrement <= Thread->Priority));
  155. Thread->PriorityDecrement += ((SCHAR)Priority - Thread->Priority);
  156. ASSERT((Thread->PriorityDecrement >= 0) &&
  157. (Thread->PriorityDecrement <= Priority));
  158. Thread->Priority = (SCHAR)Priority;
  159. }
  160. //
  161. // Make sure the thread has a quantum that is appropriate for
  162. // lock ownership and charge quantum.
  163. //
  164. if (Thread->Quantum < LOCK_OWNERSHIP_QUANTUM) {
  165. Thread->Quantum = LOCK_OWNERSHIP_QUANTUM;
  166. }
  167. Thread->Quantum -= WAIT_QUANTUM_DECREMENT;
  168. //
  169. // Release the thread lock and set the adjust reason to none.
  170. //
  171. ASSERT((Thread->Priority >= 0) && (Thread->Priority <= HIGH_PRIORITY));
  172. KiReleaseThreadLock(Thread);
  173. Thread->AdjustReason = AdjustNone;
  174. } else if (Thread->AdjustReason == AdjustUnwait) {
  175. //
  176. // Priority adjustment as the result of an unwait operation.
  177. //
  178. // The priority increment is stored in the adjust increment field of
  179. // the thread object.
  180. //
  181. // Acquire the thread lock.
  182. //
  183. // If the thread runs at a realtime priority level, then reset the
  184. // thread quantum. Otherwise, compute the next thread priority and
  185. // charge the thread for the wait operation.
  186. //
  187. Process = Thread->ApcState.Process;
  188. KiAcquireThreadLock(Thread);
  189. if (Thread->Priority < LOW_REALTIME_PRIORITY) {
  190. //
  191. // If the thread base priority is time critical or higher, then
  192. // replenish the quantum.
  193. //
  194. if (Thread->BasePriority >= TIME_CRITICAL_PRIORITY_BOUND) {
  195. Thread->Quantum = Process->ThreadQuantum;
  196. } else {
  197. //
  198. // If the thread has not received an unusual boost and the
  199. // priority increment is nonzero, then replenish the thread
  200. // quantum.
  201. //
  202. if ((Thread->PriorityDecrement == 0) && (Thread->AdjustIncrement > 0)) {
  203. Thread->Quantum = Process->ThreadQuantum;
  204. }
  205. //
  206. // If the thread was unwaited to execute a kernel APC,
  207. // then do not charge the thread any quantum. The wait
  208. // code will charge quantum after the kernel APC has
  209. // executed and the wait is actually satisifed. Otherwise,
  210. // reduce the thread quantum and compute the new thread
  211. // priority if quantum runout occurs.
  212. //
  213. if (Thread->WaitStatus != STATUS_KERNEL_APC) {
  214. Thread->Quantum -= WAIT_QUANTUM_DECREMENT;
  215. if (Thread->Quantum <= 0) {
  216. Thread->Quantum = Process->ThreadQuantum;
  217. Thread->Priority = KiComputeNewPriority(Thread, 1);
  218. }
  219. }
  220. }
  221. //
  222. // If the thread is not running with an unusual boost and boosts
  223. // are not disabled, then attempt to apply the specified priority
  224. // increment.
  225. //
  226. if ((Thread->PriorityDecrement == 0) &&
  227. (Thread->DisableBoost == FALSE)) {
  228. //
  229. // If the specified thread is from a process with a foreground
  230. // memory priority, then add the foreground boost separation.
  231. //
  232. ASSERT(Thread->AdjustIncrement >= 0);
  233. Priority = Thread->BasePriority + Thread->AdjustIncrement;
  234. if (((PEPROCESS)Process)->Vm.Flags.MemoryPriority == MEMORY_PRIORITY_FOREGROUND) {
  235. Priority += ((SCHAR)PsPrioritySeperation);
  236. }
  237. //
  238. // If the new thread priority is greater than the current
  239. // thread priority, then boost the thread priority, but not
  240. // above low real time minus one.
  241. //
  242. if (Priority > Thread->Priority) {
  243. if (Priority >= LOW_REALTIME_PRIORITY) {
  244. Priority = LOW_REALTIME_PRIORITY - 1;
  245. }
  246. //
  247. // If the new thread priority is greater than the thread
  248. // base priority plus the specified increment (i.e., the
  249. // foreground separation was added), then set the priority
  250. // decrement to remove the separation boost after one
  251. // quantum.
  252. //
  253. if (Priority > (Thread->BasePriority + Thread->AdjustIncrement)) {
  254. Thread->PriorityDecrement =
  255. ((SCHAR)Priority - Thread->BasePriority - Thread->AdjustIncrement);
  256. }
  257. ASSERT((Thread->PriorityDecrement >= 0) &&
  258. (Thread->PriorityDecrement <= Priority));
  259. Thread->Priority = (SCHAR)Priority;
  260. }
  261. }
  262. } else {
  263. Thread->Quantum = Process->ThreadQuantum;
  264. }
  265. //
  266. // Release the thread lock and set the adjust reason to none.
  267. //
  268. ASSERT((Thread->Priority >= 0) && (Thread->Priority <= HIGH_PRIORITY));
  269. KiReleaseThreadLock(Thread);
  270. Thread->AdjustReason = AdjustNone;
  271. } else {
  272. //
  273. // Invalid priority adjustment reason.
  274. //
  275. ASSERT(FALSE);
  276. Thread->AdjustReason = AdjustNone;
  277. }
  278. //
  279. // Save the value of thread's preempted flag and set thread preempted
  280. // FALSE,
  281. //
  282. Preempted = Thread->Preempted;
  283. Thread->Preempted = FALSE;
  284. //
  285. // If there is an idle processor, then schedule the thread on an
  286. // idle processor giving preference to:
  287. //
  288. // (a) the thread's ideal processor,
  289. //
  290. // (b) if the thread has a soft (preferred affinity set) and
  291. // that set contains an idle processor, reduce the set to
  292. // the intersection of the two sets.
  293. //
  294. // (c) if the processors are Simultaneous Multi Threaded, and the
  295. // set contains physical processors with no busy logical
  296. // processors, reduce the set to that subset.
  297. //
  298. // (d) if this thread last ran on a member of this remaining set,
  299. // select that processor, otherwise,
  300. //
  301. // (e) if there are processors amongst the remainder which are
  302. // not sleeping, reduce to that subset.
  303. //
  304. // (f) select the leftmost processor from this set.
  305. //
  306. #if defined(NT_UP)
  307. Thread->NextProcessor = 0;
  308. TargetPrcb = KiProcessorBlock[0];
  309. if (KiIdleSummary != 0) {
  310. KiIdleSummary = 0;
  311. Thread->State = Standby;
  312. TargetPrcb->NextThread = Thread;
  313. return;
  314. }
  315. Processor = 0;
  316. CurrentPrcb = TargetPrcb;
  317. ThreadPriority = Thread->Priority;
  318. #else
  319. //
  320. // Attempt to assign the thread on an idle processor.
  321. //
  322. CurrentPrcb = KeGetCurrentPrcb();
  323. IdleAssignment:
  324. Affinity = Thread->Affinity;
  325. do {
  326. Processor = Thread->IdealProcessor;
  327. IdleSet = KiIdleSummary & Affinity;
  328. if (IdleSet != 0) {
  329. if ((IdleSet & AFFINITY_MASK(Processor)) == 0) {
  330. //
  331. // Ideal processor is not available.
  332. //
  333. // If the intersection of the idle set and the node
  334. // affinity is nonzero, then reduce the set of idle
  335. // processors by the node affinity.
  336. //
  337. Node = KiProcessorBlock[Processor]->ParentNode;
  338. if ((IdleSet & Node->ProcessorMask) != 0) {
  339. IdleSet &= Node->ProcessorMask;
  340. }
  341. //
  342. // If the intersection of the idle set and the SMT idle
  343. // set is nonzero, then reduce the set of idle processors
  344. // by the SMT idle set.
  345. //
  346. #if defined(NT_SMT)
  347. if ((IdleSet & KiIdleSMTSummary) != 0) {
  348. IdleSet &= KiIdleSMTSummary;
  349. }
  350. #endif
  351. //
  352. // If the last processor the thread ran on is included in
  353. // the idle set, then attempt to select that processor.
  354. //
  355. IdealProcessor = Processor;
  356. Processor = Thread->NextProcessor;
  357. if ((IdleSet & AFFINITY_MASK(Processor)) == 0) {
  358. //
  359. // If the current processor is included in the idle,
  360. // then attempt to select that processor.
  361. //
  362. Processor = KeGetCurrentPrcb()->Number;
  363. if ((IdleSet & AFFINITY_MASK(Processor)) == 0) {
  364. //
  365. // If the intersection of the idle set and the
  366. // logical processor set on the ideal processor
  367. // node is nonzero, then reduce the set of idle
  368. // processors by the logical processor set.
  369. //
  370. // Otherwise, if the intersection of the idle
  371. // set and the logical processor set of the last
  372. // processor node is nonzero, then reduce the set
  373. // of idle processors by the logical processor set.
  374. //
  375. #if defined(NT_SMT)
  376. FavoredSMTSet = KiProcessorBlock[IdealProcessor]->MultiThreadProcessorSet;
  377. if ((IdleSet & FavoredSMTSet) != 0) {
  378. IdleSet &= FavoredSMTSet;
  379. } else {
  380. FavoredSMTSet = KiProcessorBlock[Processor]->MultiThreadProcessorSet;
  381. if ((IdleSet & FavoredSMTSet) != 0) {
  382. IdleSet &= FavoredSMTSet;
  383. }
  384. }
  385. #endif
  386. //
  387. // If the intersection of the idle set and the
  388. // set of processors that are not sleeping is
  389. // nonzero, then reduce the idle set to the set
  390. // of processors that are snot sleeping.
  391. //
  392. if ((IdleSet & ~PoSleepingSummary) != 0) {
  393. IdleSet &= ~PoSleepingSummary;
  394. }
  395. //
  396. // Select an idle processor from the remaining
  397. // set.
  398. //
  399. KeFindFirstSetLeftAffinity(IdleSet, &Processor);
  400. }
  401. }
  402. }
  403. //
  404. // Acquire the current and target PRCB locks and ensure the
  405. // selected processor is still idle and the thread can still
  406. // run on the processor.
  407. //
  408. TargetPrcb = KiProcessorBlock[Processor];
  409. KiAcquireTwoPrcbLocks(CurrentPrcb, TargetPrcb);
  410. if (((KiIdleSummary & TargetPrcb->SetMember) != 0) &&
  411. ((Thread->Affinity & TargetPrcb->SetMember) != 0)) {
  412. //
  413. // Set the thread state to standby, set the processor
  414. // number the thread is being assigned to, and clear the
  415. // associated bit in idle summary.
  416. //
  417. Thread->State = Standby;
  418. Thread->NextProcessor = (UCHAR)Processor;
  419. KiClearIdleSummary(AFFINITY_MASK(Processor));
  420. ASSERT((TargetPrcb->NextThread == NULL) ||
  421. (TargetPrcb->NextThread == TargetPrcb->IdleThread));
  422. TargetPrcb->NextThread = Thread;
  423. //
  424. // Update the idle SMT summary set to indicate that the
  425. // SMT set is not idle.
  426. //
  427. KiClearSMTSummary(TargetPrcb->MultiThreadProcessorSet);
  428. if (((PoSleepingSummary & AFFINITY_MASK(Processor)) != 0) &&
  429. (Processor != (ULONG)KeGetCurrentPrcb()->Number)) {
  430. KiIpiSend(AFFINITY_MASK(Processor), IPI_DPC);
  431. }
  432. KiReleaseTwoPrcbLocks(CurrentPrcb, TargetPrcb);
  433. return;
  434. } else {
  435. KiReleaseTwoPrcbLocks(CurrentPrcb, TargetPrcb);
  436. continue;
  437. }
  438. } else {
  439. break;
  440. }
  441. } while (TRUE);
  442. //
  443. // Select the ideal processor as the processor to preempt, if possible.
  444. //
  445. TargetPrcb = KiProcessorBlock[Processor];
  446. //
  447. // There are no suitable idle processors to run the thread. Acquire
  448. // the current and target PRCB locks and ensure the target processor
  449. // is not idle and the thread can still run on the processor.
  450. //
  451. KiAcquireTwoPrcbLocks(CurrentPrcb, TargetPrcb);
  452. ThreadPriority = Thread->Priority;
  453. if (((KiIdleSummary & TargetPrcb->SetMember) == 0) &&
  454. (Thread->IdealProcessor == Processor)) {
  455. ASSERT((Thread->Affinity & TargetPrcb->SetMember) != 0);
  456. #endif
  457. Thread->NextProcessor = (UCHAR)Processor;
  458. if ((Thread1 = TargetPrcb->NextThread) != NULL) {
  459. ASSERT(Thread1->State == Standby);
  460. if (ThreadPriority > Thread1->Priority) {
  461. Thread1->Preempted = TRUE;
  462. Thread->State = Standby;
  463. TargetPrcb->NextThread = Thread;
  464. Thread1->State = DeferredReady;
  465. Thread1->DeferredProcessor = CurrentPrcb->Number;
  466. KiReleaseTwoPrcbLocks(CurrentPrcb, TargetPrcb);
  467. KiDeferredReadyThread(Thread1);
  468. return;
  469. }
  470. } else {
  471. Thread1 = TargetPrcb->CurrentThread;
  472. if (ThreadPriority > Thread1->Priority) {
  473. Thread1->Preempted = TRUE;
  474. Thread->State = Standby;
  475. TargetPrcb->NextThread = Thread;
  476. KiReleaseTwoPrcbLocks(CurrentPrcb, TargetPrcb);
  477. KiRequestDispatchInterrupt(Thread->NextProcessor);
  478. return;
  479. }
  480. }
  481. #if !defined(NT_UP)
  482. } else {
  483. KiReleaseTwoPrcbLocks(CurrentPrcb, TargetPrcb);
  484. goto IdleAssignment;
  485. }
  486. #endif
  487. //
  488. // No thread can be preempted. Insert the thread in the dispatcher
  489. // queue selected by its priority. If the thread was preempted and
  490. // runs at a realtime priority level, then insert the thread at the
  491. // front of the queue. Else insert the thread at the tail of the queue.
  492. //
  493. ASSERT((ThreadPriority >= 0) && (ThreadPriority <= HIGH_PRIORITY));
  494. Thread->State = Ready;
  495. Thread->WaitTime = KiQueryLowTickCount();
  496. if (Preempted != FALSE) {
  497. InsertHeadList(&TargetPrcb->DispatcherReadyListHead[ThreadPriority],
  498. &Thread->WaitListEntry);
  499. } else {
  500. InsertTailList(&TargetPrcb->DispatcherReadyListHead[ThreadPriority],
  501. &Thread->WaitListEntry);
  502. }
  503. TargetPrcb->ReadySummary |= PRIORITY_MASK(ThreadPriority);
  504. ASSERT(ThreadPriority == Thread->Priority);
  505. KiReleaseTwoPrcbLocks(CurrentPrcb, TargetPrcb);
  506. return;
  507. }
  508. #if !defined(NT_UP)
  509. PKTHREAD
  510. FASTCALL
  511. KiFindReadyThread (
  512. IN ULONG Number,
  513. IN PKPRCB Prcb
  514. )
  515. /*++
  516. Routine Description:
  517. This function searches the dispatcher ready queues in an attempt to find
  518. a thread that can execute on the specified processor.
  519. N.B. This routine is called with the sources PRCB locked and the specified
  520. PRCB lock held and returns with both locks held.
  521. N.B. This routine is only called when it is known that the ready summary
  522. for the specified processor is nonzero.
  523. Arguments:
  524. Number - Supplies the number of the processor to find a thread for.
  525. Prcb - Supplies a pointer to the processor control block whose ready
  526. queues are to be examined.
  527. Return Value:
  528. If a thread is located that can execute on the specified processor, then
  529. the address of the thread object is returned. Otherwise a null pointer is
  530. returned.
  531. --*/
  532. {
  533. ULONG HighPriority;
  534. PRLIST_ENTRY ListHead;
  535. PRLIST_ENTRY NextEntry;
  536. ULONG PrioritySet;
  537. PKTHREAD Thread;
  538. //
  539. // Initialize the set of priority levels that should be scanned in an
  540. // attempt to find a thread that can run on the specified processor.
  541. //
  542. PrioritySet = Prcb->ReadySummary;
  543. ASSERT(PrioritySet != 0);
  544. KeFindFirstSetLeftMember(PrioritySet, &HighPriority);
  545. do {
  546. ASSERT((PrioritySet & PRIORITY_MASK(HighPriority)) != 0);
  547. ASSERT(IsListEmpty(&Prcb->DispatcherReadyListHead[HighPriority]) == FALSE);
  548. ListHead = &Prcb->DispatcherReadyListHead[HighPriority];
  549. NextEntry = ListHead->Flink;
  550. ASSERT(NextEntry != ListHead);
  551. //
  552. // Scan the specified dispatcher ready queue for a suitable
  553. // thread to execute.
  554. //
  555. // N.B. It is not necessary to attempt to find a better candidate
  556. // on either multinode or non-multinode systems. For multinode
  557. // systems, this routine is called sequentially specifying each
  558. // processor on the current node before attempting to schedule
  559. // from other processors. For non-multinode systems all threads
  560. // run on a single node and there is no node distinction. In
  561. // both cases threads are inserted in per-processor ready queues
  562. // according to their ideal processor.
  563. //
  564. do {
  565. Thread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry);
  566. if ((Thread->Affinity & AFFINITY_MASK(Number)) != 0) {
  567. ASSERT((Prcb->ReadySummary & PRIORITY_MASK(HighPriority)) != 0);
  568. ASSERT((KPRIORITY)HighPriority == Thread->Priority);
  569. ASSERT(Thread->NextProcessor == Prcb->Number);
  570. if (RemoveEntryList(&Thread->WaitListEntry) != FALSE) {
  571. Prcb->ReadySummary ^= PRIORITY_MASK(HighPriority);
  572. }
  573. Thread->NextProcessor = (UCHAR)Number;
  574. return Thread;
  575. }
  576. NextEntry = NextEntry->Flink;
  577. } while (NextEntry != ListHead);
  578. PrioritySet ^= PRIORITY_MASK(HighPriority);
  579. KeFindFirstSetLeftMember(PrioritySet, &HighPriority);
  580. } while (PrioritySet != 0);
  581. //
  582. // No thread could be found, return a null pointer.
  583. //
  584. return NULL;
  585. }
  586. VOID
  587. FASTCALL
  588. KiProcessDeferredReadyList (
  589. IN PKPRCB CurrentPrcb
  590. )
  591. /*++
  592. Routine Description:
  593. This function is called to process the deferred ready list.
  594. N.B. This function is called at SYNCH level with no locks held.
  595. N.B. This routine is only called when it is known that the deferred
  596. ready list is not empty.
  597. N.B. The deferred ready list is a per processor list and items are
  598. only inserted and removed from the respective processor. Thus
  599. no synchronization of the list is required.
  600. Arguments:
  601. CurrentPrcb - Supplies a pointer to the current processor's PRCB.
  602. Return Value:
  603. None.
  604. --*/
  605. {
  606. PSINGLE_LIST_ENTRY NextEntry;
  607. PKTHREAD Thread;
  608. ASSERT(CurrentPrcb->DeferredReadyListHead.Next != NULL);
  609. //
  610. // Save the address of the first entry in the deferred ready list and
  611. // set the list to empty.
  612. //
  613. NextEntry = CurrentPrcb->DeferredReadyListHead.Next;
  614. CurrentPrcb->DeferredReadyListHead.Next = NULL;
  615. //
  616. // Process each entry in deferred ready list and ready the specified
  617. // thread for execution.
  618. //
  619. do {
  620. Thread = CONTAINING_RECORD(NextEntry, KTHREAD, SwapListEntry);
  621. NextEntry = NextEntry->Next;
  622. KiDeferredReadyThread(Thread);
  623. } while (NextEntry != NULL);
  624. ASSERT(CurrentPrcb->DeferredReadyListHead.Next == NULL);
  625. return;
  626. }
  627. #endif
  628. VOID
  629. FASTCALL
  630. KiQueueReadyThread (
  631. IN PKTHREAD Thread,
  632. IN PKPRCB Prcb
  633. )
  634. /*++
  635. Routine Description:
  636. This function inserts the specified thread in the appropriate dispatcher
  637. ready queue for the specified processor if the thread can run on the
  638. specified processor. Otherwise, the specified thread is readied for
  639. execution.
  640. N.B. This function is called with the specified PRCB lock held and returns
  641. with the PRCB lock not held.
  642. N.B. This function is called with the dispatcher lock held and returns
  643. with the dispatcher lock held.
  644. Arguments:
  645. Thread - Supplies a pointer to a dsispatcher object of type thread.
  646. Prcb - Supplies a pointer to a processor control block.
  647. Return Value:
  648. None.
  649. --*/
  650. {
  651. KxQueueReadyThread(Thread, Prcb);
  652. return;
  653. }
  654. VOID
  655. FASTCALL
  656. KiReadyThread (
  657. IN PKTHREAD Thread
  658. )
  659. /*++
  660. Routine Description:
  661. This function inserts the specified thread in the process ready list if
  662. the thread's process is currently not in memory, inserts the specified
  663. thread in the kernel stack in swap list if the thread's kernel stack is
  664. not resident, or inserts the thread in the deferred ready list.
  665. N.B. This function is called with the dispatcher database lock held and
  666. returns with the lock held.
  667. N.B. The deferred ready list is a per processor list and items are
  668. only inserted and removed from the respective processor. Thus
  669. no synchronization of the list is required.
  670. Arguments:
  671. Thread - Supplies a pointer to a dispatcher object of type thread.
  672. Return Value:
  673. None.
  674. --*/
  675. {
  676. PKPROCESS Process;
  677. //
  678. // If the thread's process is not in memory, then insert the thread in
  679. // the process ready queue and inswap the process.
  680. //
  681. Process = Thread->ApcState.Process;
  682. if (Process->State != ProcessInMemory) {
  683. Thread->State = Ready;
  684. Thread->ProcessReadyQueue = TRUE;
  685. InsertTailList(&Process->ReadyListHead, &Thread->WaitListEntry);
  686. if (Process->State == ProcessOutOfMemory) {
  687. Process->State = ProcessInTransition;
  688. InterlockedPushEntrySingleList(&KiProcessInSwapListHead,
  689. &Process->SwapListEntry);
  690. KiSetInternalEvent(&KiSwapEvent, KiSwappingThread);
  691. }
  692. return;
  693. } else if (Thread->KernelStackResident == FALSE) {
  694. //
  695. // The thread's kernel stack is not resident. Increment the process
  696. // stack count, set the state of the thread to transition, insert
  697. // the thread in the kernel stack inswap list, and set the kernel
  698. // stack inswap event.
  699. //
  700. Process->StackCount += 1;
  701. Thread->State = Transition;
  702. InterlockedPushEntrySingleList(&KiStackInSwapListHead,
  703. &Thread->SwapListEntry);
  704. KiSetInternalEvent(&KiSwapEvent, KiSwappingThread);
  705. return;
  706. } else {
  707. //
  708. // Insert the specified thread in the deferred ready list.
  709. //
  710. KiInsertDeferredReadyList(Thread);
  711. return;
  712. }
  713. }
  714. PKTHREAD
  715. FASTCALL
  716. KiSelectNextThread (
  717. IN PKPRCB Prcb
  718. )
  719. /*++
  720. Routine Description:
  721. This function selects the next thread to run on the specified processor.
  722. N.B. This function is called with the specified PRCB lock held and also
  723. returns with the lock held.
  724. Arguments:
  725. Prcb - Supplies a pointer to a processor block.
  726. Return Value:
  727. The address of the selected thread object.
  728. --*/
  729. {
  730. PKTHREAD Thread;
  731. //
  732. // Find a ready thread to run from the specified PRCB dispatcher ready
  733. // queues.
  734. //
  735. if ((Thread = KiSelectReadyThread(0, Prcb)) == NULL) {
  736. //
  737. // A ready thread cannot be found in the specified PRCB dispatcher
  738. // ready queues. Select the idle thread and set idle schedule for
  739. // the specified processor.
  740. //
  741. // N.B. Selecting the idle thread with idle schedule set avoids doing
  742. // a complete search of all the dispatcher queues for a suitable
  743. // thread to run. A complete search will be performed by the idle
  744. // thread outside the dispatcher lock.
  745. //
  746. Thread = Prcb->IdleThread;
  747. KiSetIdleSummary(Prcb->SetMember);
  748. Prcb->IdleSchedule = TRUE;
  749. //
  750. // If all logical processors of the physical processor are idle, then
  751. // update the idle SMT set summary.
  752. //
  753. if (KeIsSMTSetIdle(Prcb) == TRUE) {
  754. KiSetSMTSummary(Prcb->MultiThreadProcessorSet);
  755. }
  756. }
  757. ASSERT(Thread != NULL);
  758. //
  759. // Return address of selected thread object.
  760. //
  761. return Thread;
  762. }
  763. KAFFINITY
  764. FASTCALL
  765. KiSetAffinityThread (
  766. IN PKTHREAD Thread,
  767. IN KAFFINITY Affinity
  768. )
  769. /*++
  770. Routine Description:
  771. This function sets the affinity of a specified thread to a new value.
  772. If the new affinity is not a proper subset of the parent process affinity
  773. or is null, then a bugcheck occurs. If the specified thread is running on
  774. or about to run on a processor for which it is no longer able to run, then
  775. the target processor is rescheduled. If the specified thread is in a ready
  776. state and is not in the parent process ready queue, then it is rereadied
  777. to reevaluate any additional processors it may run on.
  778. Arguments:
  779. Thread - Supplies a pointer to a dispatcher object of type thread.
  780. Affinity - Supplies the new of set of processors on which the thread
  781. can run.
  782. Return Value:
  783. The previous affinity of the specified thread is returned as the function
  784. value.
  785. --*/
  786. {
  787. KAFFINITY OldAffinity;
  788. PKPRCB Prcb;
  789. PKPROCESS Process;
  790. ULONG Processor;
  791. #if !defined(NT_UP)
  792. ULONG IdealProcessor;
  793. ULONG Index;
  794. PKNODE Node;
  795. ULONG NodeNumber;
  796. #endif
  797. PKTHREAD Thread1;
  798. //
  799. // Capture the current affinity of the specified thread and get address
  800. // of parent process object.
  801. //
  802. OldAffinity = Thread->UserAffinity;
  803. Process = Thread->Process;
  804. //
  805. // If new affinity is not a proper subset of the parent process affinity
  806. // or the new affinity is null, then bugcheck.
  807. //
  808. if (((Affinity & Process->Affinity) != (Affinity)) || (!Affinity)) {
  809. KeBugCheck(INVALID_AFFINITY_SET);
  810. }
  811. //
  812. // Set the thread user affinity to the specified value.
  813. //
  814. Thread->UserAffinity = Affinity;
  815. //
  816. // If the thread user ideal processor is not a member of the new affinity
  817. // set, then recompute the user ideal processor.
  818. //
  819. #if !defined(NT_UP)
  820. if ((Affinity & AFFINITY_MASK(Thread->UserIdealProcessor)) == 0) {
  821. if (KeNumberNodes > 1) {
  822. NodeNumber = (KeProcessNodeSeed + 1) % KeNumberNodes;
  823. KeProcessNodeSeed = (UCHAR)NodeNumber;
  824. Index = 0;
  825. do {
  826. if ((KeNodeBlock[NodeNumber]->ProcessorMask & Affinity) != 0) {
  827. break;
  828. }
  829. Index += 1;
  830. NodeNumber = (NodeNumber + 1) % KeNumberNodes;
  831. } while (Index < KeNumberNodes);
  832. } else {
  833. NodeNumber = 0;
  834. }
  835. Node = KeNodeBlock[NodeNumber];
  836. ASSERT((Node->ProcessorMask & Affinity) != 0);
  837. IdealProcessor = KeFindNextRightSetAffinity(Node->Seed,
  838. Node->ProcessorMask & Affinity);
  839. Thread->UserIdealProcessor = (UCHAR)IdealProcessor;
  840. Node->Seed = (UCHAR)IdealProcessor;
  841. }
  842. #endif
  843. //
  844. // If the thread is not current executing with system affinity active,
  845. // then set the thread current affinity and switch on the thread state.
  846. //
  847. if (Thread->SystemAffinityActive == FALSE) {
  848. //
  849. // Switch on the thread state.
  850. //
  851. do {
  852. switch (Thread->State) {
  853. //
  854. // Ready State.
  855. //
  856. // If the thread is not in the process ready queue, then
  857. // remove the thread from its current dispatcher ready
  858. // queue and ready the thread for execution.
  859. //
  860. case Ready:
  861. if (Thread->ProcessReadyQueue == FALSE) {
  862. Processor = Thread->NextProcessor;
  863. Prcb = KiProcessorBlock[Processor];
  864. KiAcquirePrcbLock(Prcb);
  865. if ((Thread->State == Ready) &&
  866. (Thread->NextProcessor == Prcb->Number)) {
  867. Thread->Affinity = Affinity;
  868. #if !defined(NT_UP)
  869. Thread->IdealProcessor = Thread->UserIdealProcessor;
  870. #endif
  871. ASSERT((Prcb->ReadySummary & PRIORITY_MASK(Thread->Priority)) != 0);
  872. if (RemoveEntryList(&Thread->WaitListEntry) != FALSE) {
  873. Prcb->ReadySummary ^= PRIORITY_MASK(Thread->Priority);
  874. }
  875. KiInsertDeferredReadyList(Thread);
  876. KiReleasePrcbLock(Prcb);
  877. } else {
  878. KiReleasePrcbLock(Prcb);
  879. continue;
  880. }
  881. } else {
  882. Thread->Affinity = Affinity;
  883. #if !defined(NT_UP)
  884. Thread->IdealProcessor = Thread->UserIdealProcessor;
  885. #endif
  886. }
  887. break;
  888. //
  889. // Standby State.
  890. //
  891. // If the target processor is not in the new affinity set,
  892. // then select a new thread to run on the target processor,
  893. // and ready the thread for execution.
  894. //
  895. case Standby:
  896. Processor = Thread->NextProcessor;
  897. Prcb = KiProcessorBlock[Processor];
  898. KiAcquirePrcbLock(Prcb);
  899. if (Thread == Prcb->NextThread) {
  900. Thread->Affinity = Affinity;
  901. #if !defined(NT_UP)
  902. Thread->IdealProcessor = Thread->UserIdealProcessor;
  903. #endif
  904. if ((Prcb->SetMember & Affinity) == 0) {
  905. Thread1 = KiSelectNextThread(Prcb);
  906. Thread1->State = Standby;
  907. Prcb->NextThread = Thread1;
  908. KiInsertDeferredReadyList(Thread);
  909. KiReleasePrcbLock(Prcb);
  910. } else {
  911. KiReleasePrcbLock(Prcb);
  912. }
  913. } else {
  914. KiReleasePrcbLock(Prcb);
  915. continue;
  916. }
  917. break;
  918. //
  919. // Running State.
  920. //
  921. // If the target processor is not in the new affinity set and
  922. // another thread has not already been selected for execution
  923. // on the target processor, then select a new thread for the
  924. // target processor, and cause the target processor to be
  925. // redispatched.
  926. //
  927. case Running:
  928. Processor = Thread->NextProcessor;
  929. Prcb = KiProcessorBlock[Processor];
  930. KiAcquirePrcbLock(Prcb);
  931. if (Thread == Prcb->CurrentThread) {
  932. Thread->Affinity = Affinity;
  933. #if !defined(NT_UP)
  934. Thread->IdealProcessor = Thread->UserIdealProcessor;
  935. #endif
  936. if (((Prcb->SetMember & Affinity) == 0) &&
  937. (Prcb->NextThread == NULL)) {
  938. Thread1 = KiSelectNextThread(Prcb);
  939. Thread1->State = Standby;
  940. Prcb->NextThread = Thread1;
  941. KiRequestDispatchInterrupt(Processor);
  942. }
  943. KiReleasePrcbLock(Prcb);
  944. } else {
  945. KiReleasePrcbLock(Prcb);
  946. continue;
  947. }
  948. break;
  949. //
  950. // Deferred Ready State:
  951. //
  952. // Set the affinity of the thread in a deferred ready state.
  953. //
  954. case DeferredReady:
  955. Processor = Thread->DeferredProcessor;
  956. Prcb = KiProcessorBlock[Processor];
  957. KiAcquirePrcbLock(Prcb);
  958. if ((Thread->State == DeferredReady) &&
  959. (Thread->DeferredProcessor == Processor)) {
  960. Thread->Affinity = Affinity;
  961. #if !defined(NT_UP)
  962. Thread->IdealProcessor = Thread->UserIdealProcessor;
  963. #endif
  964. KiReleasePrcbLock(Prcb);
  965. } else {
  966. KiReleasePrcbLock(Prcb);
  967. continue;
  968. }
  969. break;
  970. //
  971. // Initialized, Terminated, Waiting, Transition case - For
  972. // these states it is sufficient to just set the new thread
  973. // affinity.
  974. //
  975. default:
  976. Thread->Affinity = Affinity;
  977. #if !defined(NT_UP)
  978. Thread->IdealProcessor = Thread->UserIdealProcessor;
  979. #endif
  980. break;
  981. }
  982. break;
  983. } while (TRUE);
  984. }
  985. //
  986. // Return the previous user affinity.
  987. //
  988. return OldAffinity;
  989. }
  990. VOID
  991. KiSetInternalEvent (
  992. IN PKEVENT Event,
  993. IN PKTHREAD Thread
  994. )
  995. /*++
  996. Routine Description:
  997. This function sets an internal event or unwaits the specfied thread.
  998. N.B. The dispatcher lock must be held to call this routine.
  999. Arguments:
  1000. None.
  1001. Return Value:
  1002. None.
  1003. --*/
  1004. {
  1005. PLIST_ENTRY WaitEntry;
  1006. //
  1007. // If the swap event wait queue is not empty, then unwait the swap
  1008. // thread (there is only one swap thread). Otherwise, set the swap
  1009. // event.
  1010. //
  1011. WaitEntry = Event->Header.WaitListHead.Flink;
  1012. if (WaitEntry != &Event->Header.WaitListHead) {
  1013. KiUnwaitThread(Thread, 0, BALANCE_INCREMENT);
  1014. } else {
  1015. Event->Header.SignalState = 1;
  1016. }
  1017. return;
  1018. }
  1019. VOID
  1020. FASTCALL
  1021. KiSetPriorityThread (
  1022. IN PKTHREAD Thread,
  1023. IN KPRIORITY Priority
  1024. )
  1025. /*++
  1026. Routine Description:
  1027. This function set the priority of the specified thread to the specified
  1028. value. If the thread is in the standby or running state, then the processor
  1029. may be redispatched. If the thread is in the ready state, then some other
  1030. thread may be preempted.
  1031. Arguments:
  1032. Thread - Supplies a pointer to a dispatcher object of type thread.
  1033. Priority - Supplies the new thread priority value.
  1034. Return Value:
  1035. None.
  1036. --*/
  1037. {
  1038. PKPRCB Prcb;
  1039. ULONG Processor;
  1040. KPRIORITY ThreadPriority;
  1041. PKTHREAD Thread1;
  1042. ASSERT((Priority >= 0) && (Priority <= HIGH_PRIORITY));
  1043. //
  1044. // If the new priority is not equal to the old priority, then set the
  1045. // new priority of the thread and redispatch a processor if necessary.
  1046. //
  1047. if (Priority != Thread->Priority) {
  1048. //
  1049. //
  1050. // Switch on the thread state.
  1051. do {
  1052. switch (Thread->State) {
  1053. //
  1054. // Ready State.
  1055. //
  1056. // If the thread is not in the process ready queue, then
  1057. // remove the thread from its current dispatcher ready
  1058. // queue and ready the thread for execution.
  1059. //
  1060. case Ready:
  1061. if (Thread->ProcessReadyQueue == FALSE) {
  1062. Processor = Thread->NextProcessor;
  1063. Prcb = KiProcessorBlock[Processor];
  1064. KiAcquirePrcbLock(Prcb);
  1065. if ((Thread->State == Ready) &&
  1066. (Thread->NextProcessor == Prcb->Number)) {
  1067. ASSERT((Prcb->ReadySummary & PRIORITY_MASK(Thread->Priority)) != 0);
  1068. if (RemoveEntryList(&Thread->WaitListEntry) != FALSE) {
  1069. Prcb->ReadySummary ^= PRIORITY_MASK(Thread->Priority);
  1070. }
  1071. Thread->Priority = (SCHAR)Priority;
  1072. KiInsertDeferredReadyList(Thread);
  1073. KiReleasePrcbLock(Prcb);
  1074. } else {
  1075. KiReleasePrcbLock(Prcb);
  1076. continue;
  1077. }
  1078. } else {
  1079. Thread->Priority = (SCHAR)Priority;
  1080. }
  1081. break;
  1082. //
  1083. // Standby State.
  1084. //
  1085. // If the thread's priority is being lowered, then attempt
  1086. // to find another thread to execute on the target processor.
  1087. //
  1088. case Standby:
  1089. Processor = Thread->NextProcessor;
  1090. Prcb = KiProcessorBlock[Processor];
  1091. KiAcquirePrcbLock(Prcb);
  1092. if (Thread == Prcb->NextThread) {
  1093. ThreadPriority = Thread->Priority;
  1094. Thread->Priority = (SCHAR)Priority;
  1095. if (Priority < ThreadPriority) {
  1096. if ((Thread1 = KiSelectReadyThread(Priority + 1, Prcb)) != NULL) {
  1097. Thread1->State = Standby;
  1098. Prcb->NextThread = Thread1;
  1099. KiInsertDeferredReadyList(Thread);
  1100. KiReleasePrcbLock(Prcb);
  1101. } else {
  1102. KiReleasePrcbLock(Prcb);
  1103. }
  1104. } else {
  1105. KiReleasePrcbLock(Prcb);
  1106. }
  1107. } else {
  1108. KiReleasePrcbLock(Prcb);
  1109. continue;
  1110. }
  1111. break;
  1112. //
  1113. // Running State.
  1114. //
  1115. // If the thread's priority is being lowered, then attempt
  1116. // to find another thread to execute on the target processor.
  1117. //
  1118. case Running:
  1119. Processor = Thread->NextProcessor;
  1120. Prcb = KiProcessorBlock[Processor];
  1121. KiAcquirePrcbLock(Prcb);
  1122. if (Thread == Prcb->CurrentThread) {
  1123. ThreadPriority = Thread->Priority;
  1124. Thread->Priority = (SCHAR)Priority;
  1125. if ((Priority < ThreadPriority) &&
  1126. (Prcb->NextThread == NULL)) {
  1127. if ((Thread1 = KiSelectReadyThread(Priority + 1, Prcb)) != NULL) {
  1128. Thread1->State = Standby;
  1129. Prcb->NextThread = Thread1;
  1130. KiRequestDispatchInterrupt(Processor);
  1131. }
  1132. }
  1133. KiReleasePrcbLock(Prcb);
  1134. } else {
  1135. KiReleasePrcbLock(Prcb);
  1136. continue;
  1137. }
  1138. break;
  1139. //
  1140. // Deferred Ready State:
  1141. //
  1142. // Set the priority of the thread in a deferred ready state.
  1143. //
  1144. case DeferredReady:
  1145. Processor = Thread->DeferredProcessor;
  1146. Prcb = KiProcessorBlock[Processor];
  1147. KiAcquirePrcbLock(Prcb);
  1148. if ((Thread->State == DeferredReady) &&
  1149. (Thread->DeferredProcessor == Processor)) {
  1150. Thread->Priority = (SCHAR)Priority;
  1151. KiReleasePrcbLock(Prcb);
  1152. } else {
  1153. KiReleasePrcbLock(Prcb);
  1154. continue;
  1155. }
  1156. break;
  1157. //
  1158. // Initialized, Terminated, Waiting, Transition case - For
  1159. // these states it is sufficient to just set the new thread
  1160. // priority.
  1161. //
  1162. default:
  1163. Thread->Priority = (SCHAR)Priority;
  1164. break;
  1165. }
  1166. break;
  1167. } while(TRUE);
  1168. }
  1169. return;
  1170. }
  1171. VOID
  1172. KiSuspendThread (
  1173. IN PVOID NormalContext,
  1174. IN PVOID SystemArgument1,
  1175. IN PVOID SystemArgument2
  1176. )
  1177. /*++
  1178. Routine Description:
  1179. This function is the kernel routine for the builtin suspend APC of a
  1180. thread. It is executed as the result of queuing the builtin suspend
  1181. APC and suspends thread execution by waiting nonalerable on the thread's
  1182. builtin suspend semaphore. When the thread is resumed, execution of
  1183. thread is continued by simply returning.
  1184. Arguments:
  1185. NormalContext - Not used.
  1186. SystemArgument1 - Not used.
  1187. SystemArgument2 - Not used.
  1188. Return Value:
  1189. None.
  1190. --*/
  1191. {
  1192. PKTHREAD Thread;
  1193. UNREFERENCED_PARAMETER(NormalContext);
  1194. UNREFERENCED_PARAMETER(SystemArgument1);
  1195. UNREFERENCED_PARAMETER(SystemArgument2);
  1196. //
  1197. // Get the address of the current thread object and Wait nonalertable on
  1198. // the thread's builtin suspend semaphore.
  1199. //
  1200. Thread = KeGetCurrentThread();
  1201. KeWaitForSingleObject(&Thread->SuspendSemaphore,
  1202. Suspended,
  1203. KernelMode,
  1204. FALSE,
  1205. NULL);
  1206. return;
  1207. }
  1208. LONG_PTR
  1209. FASTCALL
  1210. KiSwapThread (
  1211. IN PKTHREAD OldThread,
  1212. IN PKPRCB CurrentPrcb
  1213. )
  1214. /*++
  1215. Routine Description:
  1216. This function selects the next thread to run on the current processor
  1217. and swaps thread context to the selected thread. When the execution
  1218. of the current thread is resumed, the IRQL is lowered to its previous
  1219. value and the wait status is returned as the function value.
  1220. N.B. This function is called with no locks held.
  1221. Arguments:
  1222. Thread - Supplies a pointer to the current thread object.
  1223. CurrentPrcb - Supplies a pointer to the current PRCB.
  1224. Return Value:
  1225. The wait completion status is returned as the function value.
  1226. --*/
  1227. {
  1228. PKTHREAD NewThread;
  1229. BOOLEAN Pending;
  1230. KIRQL WaitIrql;
  1231. LONG_PTR WaitStatus;
  1232. #if !defined(NT_UP)
  1233. LONG Index;
  1234. LONG Limit;
  1235. LONG Number;
  1236. ULONG Processor;
  1237. PKPRCB TargetPrcb;
  1238. #endif
  1239. //
  1240. // If the deferred ready list is not empty, then process the list.
  1241. //
  1242. #if !defined(NT_UP)
  1243. if (CurrentPrcb->DeferredReadyListHead.Next != NULL) {
  1244. KiProcessDeferredReadyList(CurrentPrcb);
  1245. }
  1246. #endif
  1247. //
  1248. // Acquire the current PRCB lock and check if a thread has been already
  1249. // selected to run of this processor.
  1250. //
  1251. // If a thread has already been selected to run on the current processor,
  1252. // then select that thread. Otherwise, attempt to select a thread from
  1253. // the current processor dispatcher ready queues.
  1254. //
  1255. KiAcquirePrcbLock(CurrentPrcb);
  1256. if ((NewThread = CurrentPrcb->NextThread) != NULL) {
  1257. //
  1258. // Clear the next thread address, set the current thread address, and
  1259. // set the thread state to running.
  1260. //
  1261. CurrentPrcb->NextThread = NULL;
  1262. CurrentPrcb->CurrentThread = NewThread;
  1263. NewThread->State = Running;
  1264. } else {
  1265. //
  1266. // Attempt to select a thread from the current processor dispatcher
  1267. // ready queues.
  1268. //
  1269. if ((NewThread = KiSelectReadyThread(0, CurrentPrcb)) != NULL) {
  1270. CurrentPrcb->CurrentThread = NewThread;
  1271. NewThread->State = Running;
  1272. } else {
  1273. //
  1274. // A thread could not be selected from the current processor
  1275. // dispatcher ready queues. Set the current processor idle while
  1276. // attempting to select a ready thread from any other processor
  1277. // dispatcher ready queue.
  1278. //
  1279. // Setting the current processor idle allows the old thread to
  1280. // masquerade as the idle thread while scanning other processor
  1281. // dispatcher ready queues and avoids forcing the idle thread
  1282. // to perform a complete scan should no suitable thread be found.
  1283. //
  1284. KiSetIdleSummary(CurrentPrcb->SetMember);
  1285. //
  1286. // On a UP system, select the idle thread as the new thread.
  1287. //
  1288. // On an MP system, attempt to select a thread from another
  1289. // processor's dispatcher ready queues as the new thread.
  1290. //
  1291. #if defined(NT_UP)
  1292. NewThread = CurrentPrcb->IdleThread;
  1293. CurrentPrcb->CurrentThread = NewThread;
  1294. NewThread->State = Running;
  1295. }
  1296. }
  1297. #else
  1298. //
  1299. // If all logical processors of the physical processor are idle,
  1300. // then update the idle SMT summary set.
  1301. //
  1302. if (KeIsSMTSetIdle(CurrentPrcb) == TRUE) {
  1303. KiSetSMTSummary(CurrentPrcb->MultiThreadProcessorSet);
  1304. }
  1305. //
  1306. // Release the current PRCB lock and attempt to select a thread
  1307. // from any processor dispatcher ready queues.
  1308. //
  1309. // If this is a multinode system, then start with the processors
  1310. // on the same node. Otherwise, start with the current processor.
  1311. //
  1312. // N.B. It is possible to perform the below loop with minimal
  1313. // releases of the current PRCB lock. However, this limits
  1314. // parallelism.
  1315. //
  1316. KiReleasePrcbLock(CurrentPrcb);
  1317. Processor = CurrentPrcb->Number;
  1318. Index = Processor;
  1319. if (KeNumberNodes > 1) {
  1320. KeFindFirstSetLeftAffinity(CurrentPrcb->ParentNode->ProcessorMask,
  1321. (PULONG)&Index);
  1322. }
  1323. Limit = KeNumberProcessors - 1;
  1324. Number = Limit;
  1325. ASSERT(Index <= Limit);
  1326. do {
  1327. TargetPrcb = KiProcessorBlock[Index];
  1328. if (CurrentPrcb != TargetPrcb) {
  1329. if (TargetPrcb->ReadySummary != 0) {
  1330. //
  1331. // Acquire both current and target PRCB locks in
  1332. // address order to prevent deadlock.
  1333. //
  1334. if (CurrentPrcb < TargetPrcb) {
  1335. KiAcquirePrcbLock(CurrentPrcb);
  1336. KiAcquirePrcbLock(TargetPrcb);
  1337. } else {
  1338. KiAcquirePrcbLock(TargetPrcb);
  1339. KiAcquirePrcbLock(CurrentPrcb);
  1340. }
  1341. //
  1342. // If a new thread has not been selected to run on
  1343. // the current processor, then attempt to select a
  1344. // thread to run on the current processor.
  1345. //
  1346. if ((NewThread = CurrentPrcb->NextThread) == NULL) {
  1347. if ((TargetPrcb->ReadySummary != 0) &&
  1348. (NewThread = KiFindReadyThread(Processor,
  1349. TargetPrcb)) != NULL) {
  1350. //
  1351. // A new thread has been found to run on the
  1352. // current processor.
  1353. //
  1354. NewThread->State = Running;
  1355. KiReleasePrcbLock(TargetPrcb);
  1356. CurrentPrcb->CurrentThread = NewThread;
  1357. //
  1358. // Clear idle on the current processor and
  1359. // update the idle summary SMT set to indicate
  1360. // the physical processor is not entirely idle.
  1361. //
  1362. KiClearIdleSummary(AFFINITY_MASK(Processor));
  1363. KiClearSMTSummary(CurrentPrcb->MultiThreadProcessorSet);
  1364. goto ThreadFound;
  1365. } else {
  1366. KiReleasePrcbLock(CurrentPrcb);
  1367. KiReleasePrcbLock(TargetPrcb);
  1368. }
  1369. } else {
  1370. //
  1371. // A thread has already been selected to run on
  1372. // the current processor. It is possible that
  1373. // the thread is the idle thread due to a state
  1374. // change that made a scheduled runable thread
  1375. // unrunable.
  1376. //
  1377. // N.B. If the idle thread is selected, then the
  1378. // current processor is idle. Otherwise,
  1379. // the current processor is not idle.
  1380. //
  1381. if (NewThread == CurrentPrcb->IdleThread) {
  1382. CurrentPrcb->NextThread = NULL;
  1383. CurrentPrcb->IdleSchedule = FALSE;
  1384. KiReleasePrcbLock(CurrentPrcb);
  1385. KiReleasePrcbLock(TargetPrcb);
  1386. continue;
  1387. } else {
  1388. NewThread->State = Running;
  1389. KiReleasePrcbLock(TargetPrcb);
  1390. CurrentPrcb->NextThread = NULL;
  1391. CurrentPrcb->CurrentThread = NewThread;
  1392. goto ThreadFound;
  1393. }
  1394. }
  1395. }
  1396. }
  1397. Index -= 1;
  1398. if (Index < 0) {
  1399. Index = Limit;
  1400. }
  1401. Number -= 1;
  1402. } while (Number >= 0);
  1403. //
  1404. // Acquire the current PRCB lock and if a thread has not been
  1405. // selected to run on the current processor, then select the
  1406. // idle thread.
  1407. //
  1408. KiAcquirePrcbLock(CurrentPrcb);
  1409. if ((NewThread = CurrentPrcb->NextThread) != NULL) {
  1410. CurrentPrcb->NextThread = NULL;
  1411. } else {
  1412. NewThread = CurrentPrcb->IdleThread;
  1413. }
  1414. CurrentPrcb->CurrentThread = NewThread;
  1415. NewThread->State = Running;
  1416. }
  1417. }
  1418. //
  1419. // If the new thread is not the idle thread, and the old thread is not
  1420. // the new thread, and the new thread has not finished saving context,
  1421. // then avoid a deadlock by scheduling the new thread via the idle thread.
  1422. //
  1423. ThreadFound:;
  1424. if ((NewThread != CurrentPrcb->IdleThread) &&
  1425. (NewThread != OldThread) &&
  1426. (NewThread->SwapBusy != FALSE)) {
  1427. NewThread->State = Standby;
  1428. CurrentPrcb->NextThread = NewThread;
  1429. NewThread = CurrentPrcb->IdleThread;
  1430. NewThread->State = Running;
  1431. CurrentPrcb->CurrentThread = NewThread;
  1432. }
  1433. #endif
  1434. //
  1435. // Release the current PRCB lock.
  1436. //
  1437. ASSERT(OldThread != CurrentPrcb->IdleThread);
  1438. KiReleasePrcbLock(CurrentPrcb);
  1439. //
  1440. // If the old thread is the same as the new thread, then the current
  1441. // thread has been readied for execution before the context was saved.
  1442. // Release the old thread lock, and set the APC pending value. Otherwise,
  1443. // swap context to the new thread.
  1444. //
  1445. WaitIrql = OldThread->WaitIrql;
  1446. #if !defined(NT_UP)
  1447. if (OldThread == NewThread) {
  1448. KiSetContextSwapIdle(OldThread);
  1449. Pending = (BOOLEAN)((NewThread->ApcState.KernelApcPending != FALSE) &&
  1450. (NewThread->SpecialApcDisable == 0) &&
  1451. (WaitIrql == 0));
  1452. } else {
  1453. Pending = KiSwapContext(OldThread, NewThread);
  1454. }
  1455. #else
  1456. Pending = KiSwapContext(OldThread, NewThread);
  1457. #endif
  1458. //
  1459. // If a kernel APC should be delivered, then deliver it now.
  1460. //
  1461. WaitStatus = OldThread->WaitStatus;
  1462. if (Pending != FALSE) {
  1463. KeLowerIrql(APC_LEVEL);
  1464. KiDeliverApc(KernelMode, NULL, NULL);
  1465. ASSERT(WaitIrql == 0);
  1466. }
  1467. //
  1468. // Lower IRQL to its level before the wait operation and return the wait
  1469. // status.
  1470. //
  1471. KeLowerIrql(WaitIrql);
  1472. return WaitStatus;
  1473. }
  1474. ULONG
  1475. KeFindNextRightSetAffinity (
  1476. ULONG Number,
  1477. KAFFINITY Set
  1478. )
  1479. /*++
  1480. Routine Description:
  1481. This function locates the left most set bit in the set immediately to
  1482. the right of the specified bit. If no bits are set to the right of the
  1483. specified bit, then the left most set bit in the complete set is located.
  1484. N.B. Set must contain at least one bit.
  1485. Arguments:
  1486. Number - Supplies the bit number from which the search to to begin.
  1487. Set - Supplies the bit mask to search.
  1488. Return Value:
  1489. The number of the found set bit is returned as the function value.
  1490. --*/
  1491. {
  1492. KAFFINITY NewSet;
  1493. ULONG Temp;
  1494. ASSERT(Set != 0);
  1495. //
  1496. // Get a mask with all bits to the right of bit "Number" set.
  1497. //
  1498. NewSet = (AFFINITY_MASK(Number) - 1) & Set;
  1499. //
  1500. // If no bits are set to the right of the specified bit number, then use
  1501. // the complete set.
  1502. //
  1503. if (NewSet == 0) {
  1504. NewSet = Set;
  1505. }
  1506. //
  1507. // Find leftmost bit in this set.
  1508. //
  1509. KeFindFirstSetLeftAffinity(NewSet, &Temp);
  1510. return Temp;
  1511. }
  1512. #if 0
  1513. VOID
  1514. KiVerifyReadySummary (
  1515. PKPRCB Prcb
  1516. )
  1517. /*++
  1518. Routine Description:
  1519. This function verifies the correctness of ready summary.
  1520. Arguments:
  1521. None.
  1522. Return Value:
  1523. None.
  1524. --*/
  1525. {
  1526. PLIST_ENTRY Entry;
  1527. ULONG Index;
  1528. ULONG Summary;
  1529. PKTHREAD Thread;
  1530. extern ULONG InitializationPhase;
  1531. //
  1532. // If initilization has been completed, then check the ready summary
  1533. //
  1534. if (InitializationPhase == 2) {
  1535. //
  1536. // Scan the ready queues and compute the ready summary.
  1537. //
  1538. Summary = 0;
  1539. for (Index = 0; Index < MAXIMUM_PRIORITY; Index += 1) {
  1540. if (IsListEmpty(&Prcb->DispatcherReadyListHead[Index]) == FALSE) {
  1541. Summary |= PRIORITY_MASK(Index);
  1542. Entry = Prcb->DispatcherReadyListHead[Index].Flink;
  1543. do {
  1544. Thread = CONTAINING_RECORD(Entry, KTHREAD, WaitListEntry);
  1545. //
  1546. // If the thread next processor does not match the
  1547. // processor number, then break into the debugger.
  1548. //
  1549. if (Thread->NextProcessor != Prcb->Number) {
  1550. DbgBreakPoint();
  1551. }
  1552. Entry = Entry->Flink;
  1553. } while (Entry != &Prcb->DispatcherReadyListHead[Index]);
  1554. }
  1555. }
  1556. //
  1557. // If the computed summary does not agree with the current ready
  1558. // summary, then break into the debugger.
  1559. //
  1560. if (Summary != Prcb->ReadySummary) {
  1561. DbgBreakPoint();
  1562. }
  1563. }
  1564. return;
  1565. }
  1566. #endif