第一部分:
             if (Thread->ApcState.KernelApcPending &&
                 (Thread->SpecialApcDisable == 0) &&
                 (Thread->WaitIrql < APC_LEVEL)) {
} else {
                 //
                 // Insert wait block in object wait list.
                 //
InsertTailList(&Queue->Header.WaitListHead, &WaitBlock->WaitListEntry);
 VOID
 FORCEINLINE
 InsertTailList(
     IN PLIST_ENTRY ListHead,
     IN PLIST_ENTRY Entry
     )
 {
     PLIST_ENTRY Blink;
    Blink = ListHead->Blink;
     Entry->Flink = ListHead;
     Entry->Blink = Blink;
     Blink->Flink = Entry;
     ListHead->Blink = Entry;
 }
//LIFO队列
 第二部分:
 NTSTATUS
 KeDelayExecutionThread (
     IN KPROCESSOR_MODE WaitMode,
     IN BOOLEAN Alertable,
     IN PLARGE_INTEGER Interval
     )
 {
             //
             // If the current thread is processing a queue entry, then attempt
             // to activate another thread that is blocked on the queue object.
             //
            Queue = Thread->Queue;
             if (Queue != NULL) {
                 KiActivateWaiterQueue(Queue);
             }
 NTSTATUS
 KeWaitForMultipleObjects (
     IN ULONG Count,
     IN PVOID Object[],
     IN WAIT_TYPE WaitType,
     IN KWAIT_REASON WaitReason,
     IN KPROCESSOR_MODE WaitMode,
     IN BOOLEAN Alertable,
     IN PLARGE_INTEGER Timeout OPTIONAL,
     IN PKWAIT_BLOCK WaitBlockArray OPTIONAL
     )
 {
             //
             // If the current thread is processing a queue entry, then attempt
             // to activate another thread that is blocked on the queue object.
             //
            Queue = Thread->Queue;
             if (Queue != NULL) {
                 KiActivateWaiterQueue(Queue);
             }
NTSTATUS
 KeWaitForSingleObject (
     IN PVOID Object,
     IN KWAIT_REASON WaitReason,
     IN KPROCESSOR_MODE WaitMode,
     IN BOOLEAN Alertable,
     IN PLARGE_INTEGER Timeout OPTIONAL
     )
 {
               //
             // If the current thread is processing a queue entry, then attempt
             // to activate another thread that is blocked on the queue object.
             //
            Queue = Thread->Queue;
             if (Queue != NULL) {
                 KiActivateWaiterQueue(Queue);
             }
第三部分:
FORCEINLINE
 VOID
 KiActivateWaiterQueue (
     IN PRKQUEUE Queue
     )
/*++
Routine Description:
    This function is called when the current thread is about to enter a
     wait state and is currently processing a queue entry. The current
     number of threads processign entries for the queue is decrement and
     an attempt is made to activate another thread if the current count
     is less than the maximum count, there is a waiting thread, and the
     queue is not empty.
    N.B. It is possible that this function is called on one processor
          holding the dispatcher database lock while the state of the
          specified queue object is being modified on another processor
          while holding only the queue object lock. This does not cause
          a problem since holding the queue object lock ensures that
          there are no waiting threads.
Arguments:
Queue - Supplies a pointer to a dispatcher object of type event.
Return Value:
None.
--*/
{
    PRLIST_ENTRY Entry;
     PRKTHREAD Thread;
     PRKWAIT_BLOCK WaitBlock;
     PRLIST_ENTRY WaitEntry;
    //
     // Decrement the current count of active threads and check if another
     // thread can be activated. If the current number of active threads is
     // less than the target maximum number of threads, there is a entry in
     // in the queue, and a thread is waiting, then remove the entry from the
     // queue, decrement the number of entries in the queue, and unwait the
     // respectiive thread.
     //
    Queue->CurrentCount -= 1;
     if (Queue->CurrentCount < Queue->MaximumCount) {
         Entry = Queue->EntryListHead.Flink;
         WaitEntry = Queue->Header.WaitListHead.Blink;//LIFO队列
         if ((Entry != &Queue->EntryListHead) &&
             (WaitEntry != &Queue->Header.WaitListHead)) {
            RemoveEntryList(Entry);
             Entry->Flink = NULL;
             Queue->Header.SignalState -= 1;
             WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
             Thread = WaitBlock->Thread;
             KiUnwaitThread(Thread, (LONG_PTR)Entry, 0);
         }
     }
    return;
 }