Kernel Gates. Ultra-lightweight and exclusive Wait Objects used in NT 5.2+ as high-speed events. Code is untested, so it's not added to the build until I'm back in May.
Modified: trunk/reactos/include/ddk/ketypes.h
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
Added: trunk/reactos/ntoskrnl/ke/gate.c

Modified: trunk/reactos/include/ddk/ketypes.h
--- trunk/reactos/include/ddk/ketypes.h	2005-04-12 23:33:29 UTC (rev 14602)
+++ trunk/reactos/include/ddk/ketypes.h	2005-04-13 01:12:08 UTC (rev 14603)
@@ -88,6 +88,11 @@
    LIST_ENTRY        ThreadListHead;
 } KQUEUE, *PKQUEUE;
 
+typedef struct _KGATE
+{
+    DISPATCHER_HEADER Header;
+} KGATE, *PKGATE;
+
 struct _KDPC;
 
 typedef struct _KTIMER

Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
--- trunk/reactos/ntoskrnl/include/internal/ps.h	2005-04-12 23:33:29 UTC (rev 14602)
+++ trunk/reactos/ntoskrnl/include/internal/ps.h	2005-04-13 01:12:08 UTC (rev 14603)
@@ -85,7 +85,10 @@
    CHAR              WaitMode;            /* 55 */
    UCHAR             WaitNext;            /* 56 */
    UCHAR             WaitReason;          /* 57 */
-   PKWAIT_BLOCK      WaitBlockList;       /* 58 */
+   union {                                /* 58 */
+      PKWAIT_BLOCK   WaitBlockList;       /* 58 */
+      PKGATE         GateObject;          /* 58 */
+   };                                     /* 58 */
    LIST_ENTRY        WaitListEntry;       /* 5C */
    ULONG             WaitTime;            /* 64 */
    CHAR              BasePriority;        /* 68 */

Added: trunk/reactos/ntoskrnl/ke/gate.c
--- trunk/reactos/ntoskrnl/ke/gate.c	2005-04-12 23:33:29 UTC (rev 14602)
+++ trunk/reactos/ntoskrnl/ke/gate.c	2005-04-13 01:12:08 UTC (rev 14603)
@@ -0,0 +1,149 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Kernel
+ * FILE:            ntoskrnl/ke/gate.c
+ * PURPOSE:         Implements the Gate Dispatcher Object
+ * 
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID 
+FASTCALL
+KeInitializeGate(PKGATE Gate)
+{
+    DPRINT1("KeInitializeGate(Gate %x)\n", Gate);
+    
+    /* Initialize the Dispatcher Header */
+    KeInitializeDispatcherHeader(&Gate->Header,
+                                 GateObject,
+                                 sizeof(Gate) / sizeof(ULONG),
+                                 0);
+}
+
+VOID
+FASTCALL
+KeWaitForGate(PKGATE Gate,
+              KWAIT_REASON WaitReason,
+              KPROCESSOR_MODE WaitMode)       
+{
+    KIRQL OldIrql;
+    PKTHREAD CurrentThread = KeGetCurrentThread();
+    PKWAIT_BLOCK GateWaitBlock;
+    NTSTATUS Status;
+    
+    DPRINT1("KeWaitForGate(Gate %x)\n", Gate);
+    
+    do 
+    {
+        /* Lock the APC Queue */
+        KeAcquireSpinLock(&CurrentThread->ApcQueueLock, &OldIrql);
+    
+        /* Check if it's already signaled */
+        if (!Gate->Header.SignalState)
+        {
+            /* Unsignal it */
+            Gate->Header.SignalState = 0;
+    
+            /* Unlock the Queue and return */
+            KeReleaseSpinLock(&CurrentThread->ApcQueueLock, OldIrql);
+            return;
+        }
+    
+        /* Setup a Wait Block */
+        GateWaitBlock = &CurrentThread->WaitBlock[0];
+        GateWaitBlock->Object = (PVOID)Gate;
+        GateWaitBlock->Thread = CurrentThread;
+    
+        /* Set the Thread Wait Data */
+        CurrentThread->WaitReason = WaitReason;
+        CurrentThread->WaitMode = WaitMode;
+        CurrentThread->WaitIrql = OldIrql;
+        CurrentThread->GateObject = Gate;
+    
+        /* Insert into the Wait List */
+        InsertTailList(&Gate->Header.WaitListHead, &GateWaitBlock->WaitListEntry);
+    
+        /* Handle Kernel Queues */
+        if (CurrentThread->Queue) 
+        {
+            DPRINT1("Waking Queue\n");
+            KiWakeQueue(CurrentThread->Queue);
+        }
+    
+        /* Unlock the Queue*/
+        KeReleaseSpinLock(&CurrentThread->ApcQueueLock, OldIrql);
+    
+        /* Block the Thread */
+        DPRINT1("Blocking the Thread: %x\n", CurrentThread);
+        KiBlockThread(&Status, 
+                      CurrentThread->Alertable, 
+                      WaitMode, 
+                      WaitReason);
+    
+        /* Check if we were executing an APC */
+        if (Status != STATUS_KERNEL_APC) return;
+        
+        DPRINT1("Looping Again\n");
+    } while (TRUE);
+}
+
+VOID
+FASTCALL
+KeSignalGateBoostPriority(PKGATE Gate)
+{
+    PKTHREAD WaitThread;
+    PKWAIT_BLOCK WaitBlock;
+    KIRQL OldIrql;
+    NTSTATUS WaitStatus = STATUS_SUCCESS;
+
+    DPRINT1("KeSignalGateBoostPriority(EveGate %x)\n", Gate);
+    
+    /* Acquire Dispatcher Database Lock */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Make sure we're not already signaled or that the list is empty */
+    if (Gate->Header.SignalState) goto quit;
+    
+    /* If our wait list is empty, then signal the event and return */
+    if (IsListEmpty(&Gate->Header.WaitListHead))
+    {    
+        Gate->Header.SignalState = 1;
+        goto quit;
+    }
+    
+    /* Get WaitBlock */
+    WaitBlock = CONTAINING_RECORD(Gate->Header.WaitListHead.Flink, 
+                                  KWAIT_BLOCK, 
+                                  WaitListEntry);                      
+    /* Remove it */
+    RemoveEntryList(&WaitBlock->WaitListEntry);
+    
+    /* Get the Associated thread */
+    WaitThread = WaitBlock->Thread;
+
+    /* Increment the Queue's active threads */
+    if (WaitThread->Queue) 
+    {
+        DPRINT1("Incrementing Queue's active threads\n");
+        WaitThread->Queue->CurrentCount++;
+    }
+    
+    /* Reschedule the Thread */
+    DPRINT1("Unblocking the Thread\n");
+    KiUnblockThread(WaitThread, &WaitStatus, EVENT_INCREMENT);
+    return;
+
+quit:    
+    /* Release the Dispatcher Database Lock */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+}
+
+/* EOF */