test: thredsup.c File Reference

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

# thredsup.c File Reference

`#include "ki.h"`

Go to the source code of this file.

## Defines

#define | KiIncrementSwitchCounter(Member)

## Functions

VOID | KiSuspendNop (IN PKAPC Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
PKTHREAD FASTCALL | KiFindReadyThread (IN ULONG Processor, IN KPRIORITY LowPriority)
VOID FASTCALL | KiReadyThread (IN PRKTHREAD Thread)
PRKTHREAD FASTCALL | KiSelectNextThread (IN PRKTHREAD Thread)
VOID FASTCALL | KiSetPriorityThread (IN PRKTHREAD Thread, IN KPRIORITY Priority)
VOID | KiSuspendThread (IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)

## Define Documentation

#define KiIncrementSwitchCounter | ( | Member |  | ) |

| Definition at line 44 of file thredsup.c. Referenced by KiFindReadyThread(), KiReadyThread(), and KiSelectNextThread().

## Function Documentation

PKTHREAD FASTCALL KiFindReadyThread | ( | IN ULONG | Processor,
|  | IN KPRIORITY | LowPriority
| ) |

Definition at line 95 of file thredsup.c.

References _KTHREAD::Affinity, ASSERT, ClearMember, FALSE, FindFirstSetLeftMember, _KTHREAD::IdealProcessor, KiDispatcherReadyListHead, KiIncrementSwitchCounter, KiReadySummary, KiThreadSelectNotifyRoutine, _KTHREAD::NextProcessor, NULL, READY_SKIP_QUANTUM, _KTHREAD::WaitListEntry, and _KTHREAD::WaitTime.

Referenced by KeDelayExecutionThread(), KiAdjustQuantumThread(), KiQuantumEnd(), KiSelectNextThread(), KiSetPriorityThread(), and NtYieldExecution().

    00102                    :
    00103
    00104     This function searches the dispatcher ready queues from the specified
    00105     high priority to the specified low priority in an attempt to find a thread
    00106     that can execute on the specified processor.
    00107
    00108 Arguments:
    00109
    00110     Processor - Supplies the number of the processor to find a thread for.
    00111
    00112     LowPriority - Supplies the lowest priority dispatcher ready queue to
    00113         examine.
    00114
    00115 Return Value:
    00116
    00117     If a thread is located that can execute on the specified processor, then
    00118     the address of the thread object is returned. Otherwise a null pointer is
    00119     returned.
    00120
    00121 --*/
    00122
    00123 {
    00124
    00125     ULONG HighPriority;
    00126     PRLIST_ENTRY ListHead;
    00127     PRLIST_ENTRY NextEntry;
    00128     ULONG PrioritySet;
    00129     KAFFINITY ProcessorSet;
    00130     PRKTHREAD Thread;
    00131     PRKTHREAD Thread1;
    00132     ULONG TickLow;
    00133     ULONG WaitTime;
    00134
    00135     //
    00136     // Compute the set of priority levels that should be scanned in an attempt
    00137     // to find a thread that can run on the specified processor.
    00138     //
    00139
    00140     PrioritySet = (~((1 << LowPriority) - 1)) & KiReadySummary;
    00141
    00142 #if !defined(NT_UP)
    00143
    00144     ProcessorSet = (KAFFINITY)(1 << Processor);
    00145
    00146 #endif
    00147
    00148     FindFirstSetLeftMember(PrioritySet, &HighPriority);
    00149     ListHead = &KiDispatcherReadyListHead[HighPriority];
    00150     PrioritySet <<= (31 - HighPriority);
    00151     while (PrioritySet != 0) {
    00152
    00153         //
    00154         // If the next bit in the priority set is a one, then examine the
    00155         // corresponding dispatcher ready queue.
    00156         //
    00157
    00158         if ((LONG)PrioritySet < 0) {
    00159             NextEntry = ListHead->Flink;
    00160
    00161             ASSERT(NextEntry != ListHead);
    00162
    00163 #if defined(NT_UP)
    00164
    00165             Thread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry);
    00166             RemoveEntryList(&Thread->WaitListEntry);
    00167             if (IsListEmpty(ListHead)) {
    00168                 ClearMember(HighPriority, KiReadySummary);
    00169             }
    00170
    00171             return (PKTHREAD)Thread;
    00172
    00173 #else
    00174
    00175             //
    00176             // Scan the specified dispatcher ready queue for a suitable
    00177             // thread to execute.
    00178             //
    00179
    00180             while (NextEntry != ListHead) {
    00181                 Thread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry);
    00182                 NextEntry = NextEntry->Flink;
    00183                 if (Thread->Affinity & ProcessorSet) {
    00184
    00185                     //
    00186                     // If the found thread ran on the specified processor
    00187                     // last, the processor is the ideal processor for the
    00188                     // thread, the thread has been waiting for longer than
    00189                     // a quantum, or its priority is greater than low realtime
    00190                     // plus 8, then the selected thread is returned. Otherwise,
    00191                     // an attempt is made to find a more appropriate thread.
    00192                     //
    00193
    00194                     TickLow = KiQueryLowTickCount();
    00195                     WaitTime = TickLow - Thread->WaitTime;
    00196                     if ((KiThreadSelectNotifyRoutine ?
    00197                         (KiThreadSelectNotifyRoutine(((PETHREAD)Thread)->Cid.UniqueThread) == FALSE) :
    00198                         (((ULONG)Thread->NextProcessor != Processor) &&
    00199                         ((ULONG)Thread->IdealProcessor != Processor))) &&
    00200                         (WaitTime < (READY_SKIP_QUANTUM + 1)) &&
    00201                         (HighPriority < (LOW_REALTIME_PRIORITY + 9))) {
    00202
    00203                         //
    00204                         // Search forward in the ready queue until the end
    00205                         // of the list is reached or a more appropriate
    00206                         // thread is found.
    00207                         //
    00208
    00209                         while (NextEntry != ListHead) {
    00210                             Thread1 = CONTAINING_RECORD(NextEntry,
    00211                                                         KTHREAD,
    00212                                                         WaitListEntry);
    00213
    00214                             NextEntry = NextEntry->Flink;
    00215                             if ((Thread1->Affinity & ProcessorSet) &&
    00216                                 (KiThreadSelectNotifyRoutine ?
    00217                                 (KiThreadSelectNotifyRoutine(((PETHREAD)Thread)->Cid.UniqueThread) != FALSE) :
    00218                                 (((ULONG)Thread1->NextProcessor == Processor) ||
    00219                                 ((ULONG)Thread1->IdealProcessor == Processor)))) {
    00220                                 Thread = Thread1;
    00221                                 break;
    00222                             }
    00223
    00224                             WaitTime = TickLow - Thread1->WaitTime;
    00225                             if (WaitTime >= (READY_SKIP_QUANTUM + 1)) {
    00226                                 break;
    00227                             }
    00228                         }
    00229                     }
    00230
    00231                     if (Processor == (ULONG)Thread->IdealProcessor) {
    00232                         KiIncrementSwitchCounter(FindIdeal);
    00233
    00234                     } else if (Processor == (ULONG)Thread->NextProcessor) {
    00235                         KiIncrementSwitchCounter(FindLast);
    00236
    00237                     } else {
    00238                         KiIncrementSwitchCounter(FindAny);
    00239                     }
    00240
    00241                     Thread->NextProcessor = (CCHAR)Processor;
    00242
    00243                     RemoveEntryList(&Thread->WaitListEntry);
    00244                     if (IsListEmpty(ListHead)) {
    00245                         ClearMember(HighPriority, KiReadySummary);
    00246                     }
    00247
    00248                     return (PKTHREAD)Thread;
    00249                 }
    00250             }
    00251
    00252 #endif
    00253
    00254         }
    00255
    00256         HighPriority -= 1;
    00257         ListHead -= 1;
    00258         PrioritySet <<= 1;
    00259     };
    00260
    00261     //
    00262     // No thread could be found, return a null pointer.
    00263     //
    00264
    00265     return (PKTHREAD)NULL;
    00266 }

VOID FASTCALL KiReadyThread | ( | IN PRKTHREAD | Thread | ) |

Definition at line 270 of file thredsup.c.

References BALANCE_INCREMENT, ClearMember, FALSE, FASTCALL, FindFirstSetLeftMember, _KEVENT::Header, IPI_DPC, KeGetCurrentPrcb, KiDispatcherReadyListHead, KiIdleSummary, KiIncrementSwitchCounter, KiIpiSend(), KiProcessInSwapListHead, KiProcessorBlock, KiReadySummary, KiRequestDispatchInterrupt, KiStackInSwapListHead, KiSwapEvent, KiWaitTest(), NULL, PoSleepingSummary, _KTHREAD::Preempted, _KTHREAD::Priority, ProcessInMemory, ProcessInTransition, ProcessOutOfMemory, Ready, _KPROCESS::ReadyListHead, SetMember, _DISPATCHER_HEADER::SignalState, _KPROCESS::StackCount, Standby, _KPROCESS::State, _KPROCESS::SwapListEntry, Transition, TRUE, and _DISPATCHER_HEADER::WaitListHead.

Referenced by KeDelayExecutionThread(), KeReadyThread(), KeSetAffinityThread(), KiAttachProcess(), KiInsertQueue(), KiInSwapKernelStacks(), KiInSwapProcesses(), KiOutSwapProcesses(), KiScanReadyQueues(), KiSetPriorityThread(), KiUnwaitThread(), NtReplyWaitSendChannel(), and NtSendWaitReplyChannel().

    00276                    :
    00277
    00278     This function readies a thread for execution and attempts to immediately
    00279     dispatch the thread for execution by preempting another lower priority
    00280     thread. If a thread can be preempted, then the specified thread enters
    00281     the standby state and the target processor is requested to dispatch. If
    00282     another thread cannot be preempted, then the specified thread is inserted
    00283     either at the head or tail of the dispatcher ready selected by its priority
    00284     acccording to whether it was preempted or not.
    00285
    00286 Arguments:
    00287
    00288     Thread - Supplies a pointer to a dispatcher object of type thread.
    00289
    00290 Return Value:
    00291
    00292     None.
    00293
    00294 --*/
    00295
    00296 {
    00297
    00298     PRKPRCB Prcb;
    00299     BOOLEAN Preempted;
    00300     KPRIORITY Priority;
    00301     PRKPROCESS Process;
    00302     ULONG Processor;
    00303     KPRIORITY ThreadPriority;
    00304     PRKTHREAD Thread1;
    00305     KAFFINITY IdleSet;
    00306
    00307     //
    00308     // Save value of thread's preempted flag, set thread preempted FALSE,
    00309     // capture the thread priority, and set clear the read wait time.
    00310     //
    00311
    00312     Preempted = Thread->Preempted;
    00313     Thread->Preempted = FALSE;
    00314     ThreadPriority = Thread->Priority;
    00315     Thread->WaitTime = KiQueryLowTickCount();
    00316
    00317     //
    00318     // If the thread's process is not in memory, then insert the thread in
    00319     // the process ready queue and inswap the process.
    00320     //
    00321
    00322     Process = Thread->ApcState.Process;
    00323     if (Process->State != ProcessInMemory) {
    00324         Thread->State = Ready;
    00325         Thread->ProcessReadyQueue = TRUE;
    00326         InsertTailList(&Process->ReadyListHead, &Thread->WaitListEntry);
    00327         if (Process->State == ProcessOutOfMemory) {
    00328             Process->State = ProcessInTransition;
    00329             InsertTailList(&KiProcessInSwapListHead, &Process->SwapListEntry);
    00330             KiSwapEvent.Header.SignalState = 1;
    00331             if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) {
    00332                 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT);
    00333             }
    00334         }
    00335
    00336         return;
    00337
    00338     } else if (Thread->KernelStackResident == FALSE) {
    00339
    00340         //
    00341         // The thread's kernel stack is not resident. Increment the process
    00342         // stack count, set the state of the thread to transition, insert
    00343         // the thread in the kernel stack inswap list, and set the kernel
    00344         // stack inswap event.
    00345         //
    00346
    00347         Process->StackCount += 1;
    00348         Thread->State = Transition;
    00349         InsertTailList(&KiStackInSwapListHead, &Thread->WaitListEntry);
    00350         KiSwapEvent.Header.SignalState = 1;
    00351         if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) {
    00352             KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT);
    00353         }
    00354
    00355         return;
    00356
    00357     } else {
    00358
    00359         //
    00360         // If there is an idle processor, then schedule the thread on an
    00361         // idle processor giving preference to the processor the thread
    00362         // last ran on. Otherwise, try to preempt either a thread in the
    00363         // standby or running state.
    00364         //
    00365
    00366 #if defined(NT_UP)
    00367
    00368         Prcb = KiProcessorBlock[0];
    00369         if (KiIdleSummary != 0) {
    00370             KiIdleSummary = 0;
    00371             KiIncrementSwitchCounter(IdleLast);
    00372             Prcb->NextThread = Thread;
    00373             Thread->State = Standby;
    00374
    00375 #else
    00376
    00377         IdleSet = KiIdleSummary & Thread->Affinity;
    00378         if (IdleSet != 0) {
    00379             Prcb = KeGetCurrentPrcb();
    00380             Processor = Thread->IdealProcessor;
    00381             if ((IdleSet & (1 << Processor)) == 0) {
    00382                 Processor = Thread->NextProcessor;
    00383                 if ((IdleSet & (1 << Processor)) == 0) {
    00384                     if ((IdleSet & Prcb->SetMember) == 0) {
    00385                         FindFirstSetLeftMember(IdleSet, &Processor);
    00386                         KiIncrementSwitchCounter(IdleAny);
    00387
    00388                     } else {
    00389                         Processor = Prcb->Number;
    00390                         KiIncrementSwitchCounter(IdleCurrent);
    00391                     }
    00392
    00393                 } else {
    00394                     KiIncrementSwitchCounter(IdleLast);
    00395                 }
    00396
    00397             } else {
    00398                 KiIncrementSwitchCounter(IdleIdeal);
    00399             }
    00400
    00401             Thread->NextProcessor = (CCHAR)Processor;
    00402             ClearMember(Processor, KiIdleSummary);
    00403             KiProcessorBlock[Processor]->NextThread = Thread;
    00404             Thread->State = Standby;
    00405
    00406             if ((PoSleepingSummary & (1 << Processor)) &&
    00407                  Processor != (ULONG) Prcb->Number) {
    00408                 KiIpiSend(1 << Processor, IPI_DPC);
    00409             }
    00410 #endif
    00411
    00412             return;
    00413
    00414         } else {
    00415
    00416 #if !defined(NT_UP)
    00417
    00418             Processor = Thread->IdealProcessor;
    00419             if ((Thread->Affinity & (1 << Processor)) == 0) {
    00420                 Processor = Thread->NextProcessor;
    00421                 if ((Thread->Affinity & (1 << Processor)) == 0) {
    00422                     FindFirstSetLeftMember(Thread->Affinity, &Processor);
    00423                 }
    00424             }
    00425
    00426             Thread->NextProcessor = (CCHAR)Processor;
    00427             Prcb = KiProcessorBlock[Processor];
    00428
    00429 #endif
    00430
    00431             if (Prcb->NextThread != NULL) {
    00432                 Thread1 = Prcb->NextThread;
    00433                 if (ThreadPriority > Thread1->Priority) {
    00434                     Thread1->Preempted = TRUE;
    00435                     Prcb->NextThread = Thread;
    00436                     Thread->State = Standby;
    00437                     KiReadyThread(Thread1);
    00438                     KiIncrementSwitchCounter(PreemptLast);
    00439                     return;
    00440                 }
    00441
    00442             } else {
    00443                 Thread1 = Prcb->CurrentThread;
    00444                 if (ThreadPriority > Thread1->Priority) {
    00445                     Thread1->Preempted = TRUE;
    00446                     Prcb->NextThread = Thread;
    00447                     Thread->State = Standby;
    00448                     KiRequestDispatchInterrupt(Thread->NextProcessor);
    00449                     KiIncrementSwitchCounter(PreemptLast);
    00450                     return;
    00451                 }
    00452             }
    00453         }
    00454     }
    00455
    00456     //
    00457     // No thread can be preempted. Insert the thread in the dispatcher
    00458     // queue selected by its priority. If the thread was preempted and
    00459     // runs at a realtime priority level, then insert the thread at the
    00460     // front of the queue. Else insert the thread at the tail of the queue.
    00461     //
    00462
    00463     Thread->State = Ready;
    00464     if (Preempted != FALSE) {
    00465         InsertHeadList(&KiDispatcherReadyListHead[ThreadPriority],
    00466                        &Thread->WaitListEntry);
    00467
    00468     } else {
    00469         InsertTailList(&KiDispatcherReadyListHead[ThreadPriority],
    00470                        &Thread->WaitListEntry);
    00471     }
    00472
    00473     SetMember(ThreadPriority, KiReadySummary);
    00474     return;
    00475 }

PRKTHREAD FASTCALL KiSelectNextThread | ( | IN PRKTHREAD | Thread | ) |

Definition at line 479 of file thredsup.c.

References KiFindReadyThread(), KiIdleSummary, KiIncrementSwitchCounter, KiProcessorBlock, _KTHREAD::NextProcessor, NULL, and SetMember.

Referenced by KeRevertToUserAffinityThread(), KeSetAffinityThread(), and KeSetSystemAffinityThread().

    00485                    :
    00486
    00487     This function selects the next thread to run on the processor that the
    00488     specified thread is running on. If a thread cannot be found, then the
    00489     idle thread is selected.
    00490
    00491 Arguments:
    00492
    00493     Thread - Supplies a pointer to a dispatcher object of type thread.
    00494
    00495 Return Value:
    00496
    00497     The address of the selected thread object.
    00498
    00499 --*/
    00500
    00501 {
    00502
    00503     PRKPRCB Prcb;
    00504     ULONG Processor;
    00505     PRKTHREAD Thread1;
    00506
    00507     //
    00508     // Get the processor number and the address of the processor control block.
    00509     //
    00510
    00511 #if !defined(NT_UP)
    00512
    00513     Processor = Thread->NextProcessor;
    00514     Prcb = KiProcessorBlock[Processor];
    00515
    00516 #else
    00517
    00518     Prcb = KiProcessorBlock[0];
    00519
    00520 #endif
    00521
    00522     //
    00523     // If a thread has already been selected to run on the specified processor,
    00524     // then return that thread as the selected thread.
    00525     //
    00526
    00527     if ((Thread1 = Prcb->NextThread) != NULL) {
    00528         Prcb->NextThread = (PKTHREAD)NULL;
    00529
    00530     } else {
    00531
    00532         //
    00533         // Attempt to find a ready thread to run.
    00534         //
    00535
    00536 #if !defined(NT_UP)
    00537
    00538         Thread1 = KiFindReadyThread(Processor, 0);
    00539
    00540 #else
    00541
    00542         Thread1 = KiFindReadyThread(0, 0);
    00543
    00544 #endif
    00545
    00546         //
    00547         // If a thread was not found, then select the idle thread and
    00548         // set the processor member in the idle summary.
    00549         //
    00550
    00551         if (Thread1 == NULL) {
    00552             KiIncrementSwitchCounter(SwitchToIdle);
    00553             Thread1 = Prcb->IdleThread;
    00554
    00555 #if !defined(NT_UP)
    00556
    00557             SetMember(Processor, KiIdleSummary);
    00558
    00559 #else
    00560             KiIdleSummary = 1;
    00561
    00562 #endif
    00563
    00564         }
    00565     }
    00566
    00567     //
    00568     // Return address of selected thread object.
    00569     //
    00570
    00571     return Thread1;
    00572 }

VOID FASTCALL KiSetPriorityThread | ( | IN PRKTHREAD | Thread,
|  | IN KPRIORITY | Priority
| ) |

Definition at line 576 of file thredsup.c.

References ASSERT, ClearMember, FALSE, KiDispatcherReadyListHead, KiFindReadyThread(), KiProcessorBlock, KiReadySummary, KiReadyThread(), KiRequestDispatchInterrupt, NULL, Ready, Running, SetMember, Standby, and _KTHREAD::State.

Referenced by ExpBoostOwnerThread(), KeDelayExecutionThread(), KeSetBasePriorityThread(), KeSetPriorityProcess(), KeSetPriorityThread(), KiAdjustQuantumThread(), and KiQuantumEnd().

    00583                    :
    00584
    00585     This function set the priority of the specified thread to the specified
    00586     value. If the thread is in the standby or running state, then the processor
    00587     may be redispatched. If the thread is in the ready state, then some other
    00588     thread may be preempted.
    00589
    00590 Arguments:
    00591
    00592     Thread - Supplies a pointer to a dispatcher object of type thread.
    00593
    00594     Priority - Supplies the new thread priority value.
    00595
    00596 Return Value:
    00597
    00598     None.
    00599
    00600 --*/
    00601
    00602 {
    00603
    00604     PRKPRCB Prcb;
    00605     ULONG Processor;
    00606     KPRIORITY ThreadPriority;
    00607     PRKTHREAD Thread1;
    00608
    00609     ASSERT(Priority <= HIGH_PRIORITY);
    00610
    00611     //
    00612     // Capture the current priority of the specified thread.
    00613     //
    00614
    00615     ThreadPriority = Thread->Priority;
    00616
    00617     //
    00618     // If the new priority is not equal to the old priority, then set the
    00619     // new priority of the thread and redispatch a processor if necessary.
    00620     //
    00621
    00622     if (Priority != ThreadPriority) {
    00623         Thread->Priority = (SCHAR)Priority;
    00624
    00625         //
    00626         // Case on the thread state.
    00627         //
    00628
    00629         switch (Thread->State) {
    00630
    00631             //
    00632             // Ready case - If the thread is not in the process ready queue,
    00633             // then remove it from its current dispatcher ready queue. If the
    00634             // new priority is less than the old priority, then insert the
    00635             // thread at the tail of the dispatcher ready queue selected by
    00636             // the new priority. Else reready the thread for execution.
    00637             //
    00638
    00639         case Ready:
    00640             if (Thread->ProcessReadyQueue == FALSE) {
    00641                 RemoveEntryList(&Thread->WaitListEntry);
    00642                 if (IsListEmpty(&KiDispatcherReadyListHead[ThreadPriority])) {
    00643                     ClearMember(ThreadPriority, KiReadySummary);
    00644                 }
    00645
    00646                 if (Priority < ThreadPriority) {
    00647                     InsertTailList(&KiDispatcherReadyListHead[Priority],
    00648                                    &Thread->WaitListEntry);
    00649                     SetMember(Priority, KiReadySummary);
    00650
    00651                 } else {
    00652                     KiReadyThread(Thread);
    00653                 }
    00654             }
    00655
    00656             break;
    00657
    00658             //
    00659             // Standby case - If the thread's priority is being lowered, then
    00660             // attempt to find another thread to execute. If a new thread is
    00661             // found, then put the new thread in the standby state, and reready
    00662             // the old thread.
    00663             //
    00664
    00665         case Standby:
    00666
    00667 #if !defined(NT_UP)
    00668
    00669             Processor = Thread->NextProcessor;
    00670
    00671 #endif
    00672
    00673             if (Priority < ThreadPriority) {
    00674
    00675 #if !defined(NT_UP)
    00676
    00677                 Thread1 = KiFindReadyThread(Processor, Priority);
    00678
    00679 #else
    00680
    00681                 Thread1 = KiFindReadyThread(0, Priority);
    00682
    00683 #endif
    00684
    00685                 if (Thread1 != NULL) {
    00686
    00687 #if !defined(NT_UP)
    00688
    00689                     Prcb = KiProcessorBlock[Processor];
    00690
    00691 #else
    00692
    00693                     Prcb = KiProcessorBlock[0];
    00694
    00695 #endif
    00696
    00697                     Thread1->State = Standby;
    00698                     Prcb->NextThread = Thread1;
    00699                     KiReadyThread(Thread);
    00700                 }
    00701             }
    00702
    00703             break;
    00704
    00705             //
    00706             // Running case - If there is not a thread in the standby state
    00707             // on the thread's processor and the thread's priority is being
    00708             // lowered, then attempt to find another thread to execute. If
    00709             // a new thread is found, then put the new thread in the standby
    00710             // state, and request a redispatch on the thread's processor.
    00711             //
    00712
    00713         case Running:
    00714
    00715 #if !defined(NT_UP)
    00716
    00717             Processor = Thread->NextProcessor;
    00718             Prcb = KiProcessorBlock[Processor];
    00719
    00720 #else
    00721
    00722             Prcb = KiProcessorBlock[0];
    00723
    00724 #endif
    00725
    00726             if (Prcb->NextThread == NULL) {
    00727                 if (Priority < ThreadPriority) {
    00728
    00729 #if !defined(NT_UP)
    00730
    00731                     Thread1 = KiFindReadyThread(Processor, Priority);
    00732
    00733 #else
    00734
    00735                     Thread1 = KiFindReadyThread(0, Priority);
    00736
    00737 #endif
    00738
    00739                     if (Thread1 != NULL) {
    00740                         Thread1->State = Standby;
    00741                         Prcb->NextThread = Thread1;
    00742
    00743 #if !defined(NT_UP)
    00744
    00745                         KiRequestDispatchInterrupt(Processor);
    00746
    00747 #endif
    00748
    00749                     }
    00750                 }
    00751             }
    00752
    00753             break;
    00754
    00755             //
    00756             // Initialized, Terminated, Waiting, Transition case - For
    00757             // these states it is sufficient to just set the new thread
    00758             // priority.
    00759             //
    00760
    00761         default:
    00762             break;
    00763         }
    00764     }
    00765
    00766     return;
    00767 }

VOID KiSuspendNop | ( | IN PKAPC | Apc,
|  | IN OUT PKNORMAL_ROUTINE * | NormalRoutine,
|  | IN OUT PVOID * | NormalContext,
|  | IN OUT PVOID * | SystemArgument1,
|  | IN OUT PVOID * | SystemArgument2
| ) |

Definition at line 49 of file thredsup.c.

    00059                    :
    00060
    00061     This function is the kernel routine for the builtin suspend APC for a
    00062     thread. It is executed in kernel mode as the result of queuing the
    00063     builtin suspend APC and performs no operation. It is called just prior
    00064     to calling the normal routine and simply returns.
    00065
    00066 Arguments:
    00067
    00068     Apc - Supplies a pointer to a control object of type APC.
    00069
    00070     NormalRoutine - not used
    00071
    00072     NormalContext - not used
    00073
    00074     SystemArgument1 - not used
    00075
    00076     SystemArgument2 - not used
    00077
    00078 Return Value:
    00079
    00080     None.
    00081
    00082 --*/
    00083
    00084 {
    00085
    00086     //
    00087     // No operation is performed by this routine.
    00088     //
    00089
    00090     return;
    00091 }

VOID KiSuspendThread | ( | IN PVOID | NormalContext,
|  | IN PVOID | SystemArgument1,
|  | IN PVOID | SystemArgument2
| ) |

Definition at line 770 of file thredsup.c.

References _KAPC_STATE::ApcListHead, _KTHREAD::ApcState, FALSE, KeGetCurrentThread, KernelMode, _KAPC::KernelRoutine, KeWaitForSingleObject(), NULL, PsExitSpecialApc(), Suspended, _KTHREAD::SuspendSemaphore, _KAPC_STATE::UserApcPending, and UserMode.

Referenced by KeInitializeThread().

    00778                    :
    00779
    00780     This function is the kernel routine for the builtin suspend APC of a
    00781     thread. It is executed in kernel mode as the result of queuing the builtin
    00782     suspend APC and suspends thread execution by Waiting nonalerable on the
    00783     thread's builtin suspend semaphore. When the thread is resumed, execution
    00784     of thread is continued by simply returning.
    00785
    00786 Arguments:
    00787
    00788     Apc - Supplies a pointer to a control object of type APC.
    00789
    00790 Return Value:
    00791
    00792     None.
    00793
    00794 --*/
    00795
    00796 {
    00797
    00798     PRKTHREAD Thread;
    00799     PKAPC Apc;
    00800
    00801     //
    00802     // Get the address of the current thread object and Wait nonalertable on
    00803     // the thread's builtin suspend semaphore.
    00804     //
    00805
    00806     Thread = KeGetCurrentThread();
    00807
    00808     //
    00809     // See if the thread is exiting. If the thread has the user-mode exit
    00810     // APC in it's queue, KeForceResumeThread has been called, but it might
    00811     // have been called just before KeSuspendThread. Account for the race here
    00812     // by testing for the exit APC. During exit, we queue the user-mode exit APC
    00813     // and set UserApcPending from the kernel-mode exit APC, then we call
    00814     // KeForceResumeThread.
    00815     //
    00816
    00817     if ( Thread->ApcState.UserApcPending ) {
    00818         Apc = CONTAINING_RECORD((Thread->ApcState.ApcListHead[UserMode].Flink), KAPC, ApcListEntry);
    00819         if ( Apc->KernelRoutine == PsExitSpecialApc ) {
    00820             return;
    00821         }
    00822     }
    00823     KeWaitForSingleObject(&Thread->SuspendSemaphore,
    00824                           Suspended,
    00825                           KernelMode,
    00826                           FALSE,
    00827                           (PLARGE_INTEGER)NULL);
    00828
    00829 }
    #if 0