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.

118 lines
2.4 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. yield.c
  5. Abstract:
  6. This module implements the function to yield execution for one quantum
  7. to any other runnable thread.
  8. Author:
  9. David N. Cutler (davec) 15-Mar-1996
  10. Environment:
  11. Kernel mode only.
  12. Revision History:
  13. --*/
  14. #include "ki.h"
  15. NTSTATUS
  16. NtYieldExecution (
  17. VOID
  18. )
  19. /*++
  20. Routine Description:
  21. This function yields execution to any ready thread for up to one
  22. quantum.
  23. Arguments:
  24. None.
  25. Return Value:
  26. None.
  27. --*/
  28. {
  29. KIRQL OldIrql;
  30. PRKPRCB Prcb;
  31. KPRIORITY Priority;
  32. NTSTATUS Status;
  33. PRKTHREAD Thread;
  34. //
  35. // If any other threads are ready, then attempt to yield execution.
  36. //
  37. Status = STATUS_NO_YIELD_PERFORMED;
  38. if (KiReadySummary != 0) {
  39. //
  40. // If a thread has not already been selected for execution, then
  41. // attempt to select another thread for execution.
  42. //
  43. Thread = KeGetCurrentThread();
  44. KiLockDispatcherDatabase(&Thread->WaitIrql);
  45. Prcb = KeGetCurrentPrcb();
  46. if (Prcb->NextThread == NULL) {
  47. Prcb->NextThread = KiFindReadyThread(Thread->NextProcessor, 1);
  48. }
  49. //
  50. // If a new thread has been selected for execution, then switch
  51. // immediately to the selected thread.
  52. //
  53. if (Prcb->NextThread != NULL) {
  54. //
  55. // Give the current thread a new quantum, simulate a quantum
  56. // end, insert the current thread in the appropriate ready list,
  57. // and switch context to selected thread.
  58. //
  59. Thread->Quantum = Thread->ApcState.Process->ThreadQuantum;
  60. Thread->State = Ready;
  61. Priority = Thread->Priority;
  62. if (Priority < LOW_REALTIME_PRIORITY) {
  63. Priority = Priority - Thread->PriorityDecrement - 1;
  64. if (Priority < Thread->BasePriority) {
  65. Priority = Thread->BasePriority;
  66. }
  67. Thread->PriorityDecrement = 0;
  68. }
  69. Thread->Priority = (SCHAR)Priority;
  70. InsertTailList(&KiDispatcherReadyListHead[Priority],
  71. &Thread->WaitListEntry);
  72. SetMember(Priority, KiReadySummary);
  73. KiSwapThread();
  74. Status = STATUS_SUCCESS;
  75. } else {
  76. KiUnlockDispatcherDatabase(Thread->WaitIrql);
  77. }
  78. }
  79. return Status;
  80. }