[NTOS]: Implementation of the "Generic DPC" functionality from Windows NT 5.2, which...
authorSir Richard <sir_richard@svn.reactos.org>
Sat, 25 Feb 2012 20:40:06 +0000 (20:40 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Sat, 25 Feb 2012 20:40:06 +0000 (20:40 +0000)
This is needed for poolmon/querying pool tags.

svn path=/trunk/; revision=55865

reactos/include/ndk/kefuncs.h
reactos/ntoskrnl/include/internal/ke.h
reactos/ntoskrnl/ke/dpc.c
reactos/ntoskrnl/ntoskrnl.spec

index 4888006..defe6ff 100644 (file)
@@ -208,6 +208,28 @@ KiIpiServiceRoutine(
     IN PKEXCEPTION_FRAME ExceptionFrame
 );
 
+//
+// Generic DPC Routines
+//
+VOID
+NTAPI
+KeGenericCallDpc(
+    IN PKDEFERRED_ROUTINE Routine,
+    IN PVOID Context
+);
+
+VOID
+NTAPI
+KeSignalCallDpcDone(
+    IN PVOID SystemArgument1
+);
+
+BOOLEAN
+NTAPI
+KeSignalCallDpcSynchronize(
+    IN PVOID SystemArgument2
+);
+
 //
 // ARC Configuration Functions. Only enabled if you have ARC Support
 //
index 27e46ff..2a3f062 100644 (file)
@@ -36,6 +36,12 @@ typedef struct _DISPATCH_INFO
     PKINTERRUPT_ROUTINE *FlatDispatch;
 } DISPATCH_INFO, *PDISPATCH_INFO;
 
+typedef struct _DEFERRED_REVERSE_BARRIER
+{
+    ULONG Barrier;
+    ULONG TotalProcessors;
+} DEFERRED_REVERSE_BARRIER, *PDEFERRED_REVERSE_BARRIER;
+
 typedef struct _KI_SAMPLE_MAP
 {
     LARGE_INTEGER PerfStart;
index 9895cae..d507b72 100644 (file)
@@ -958,4 +958,60 @@ KeSetTargetProcessorDpc(IN PKDPC Dpc,
     Dpc->Number = Number + MAXIMUM_PROCESSORS;
 }
 
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+KeGenericCallDpc(IN PKDEFERRED_ROUTINE Routine,
+                 IN PVOID Context)
+{
+    ULONG Barrier = KeNumberProcessors;
+    KIRQL OldIrql;
+    DEFERRED_REVERSE_BARRIER ReverseBarrier;
+    ASSERT(KeGetCurrentIrql () < DISPATCH_LEVEL);
+
+    //
+    // The barrier is the number of processors, each processor will decrement it
+    // by one, so when all processors have run the DPC, the barrier reaches zero
+    //
+    ReverseBarrier.Barrier = Barrier;
+    ReverseBarrier.TotalProcessors = Barrier;
+
+    //
+    // But we don't need the barrier on UP, since we can simply call the routine
+    // directly while at DISPATCH_LEVEL and not worry about anything else
+    //
+    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+    Routine(&KeGetCurrentPrcb()->CallDpc, Context, &Barrier, &ReverseBarrier);
+    KeLowerIrql(OldIrql);
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+KeSignalCallDpcDone(IN PVOID SystemArgument1)
+{
+    //
+    // Decrement the barrier, which is actually the processor count
+    //
+    InterlockedDecrement((PLONG)SystemArgument1);
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+KeSignalCallDpcSynchronize(IN PVOID SystemArgument2)
+{
+    //
+    // There is nothing to do on UP systems -- the processor calling this wins
+    //
+    UNREFERENCED_PARAMETER(SystemArgument2);
+    return TRUE;
+}
+
 /* EOF */
index 759d117..a746452 100644 (file)
 @ stdcall KeFindConfigurationNextEntry(ptr long long ptr ptr)
 @ stdcall KeFlushEntireTb(long long)
 @ stdcall KeFlushQueuedDpcs()
-;KeGenericCallDpc
+@ stdcall KeGenericCallDpc(ptr ptr)
 @ stdcall KeGetCurrentThread()
 @ stdcall KeGetPreviousMode()
 @ stdcall KeGetRecommendedSharedDataAlignment()
 @ stdcall KeSetTimeIncrement(long long)
 @ stdcall KeSetTimer(ptr long long ptr)
 @ stdcall KeSetTimerEx(ptr long long long ptr)
-;KeSignalCallDpcDone
-;KeSignalCallDpcSynchronize
+@ stdcall KeSignalCallDpcDone(ptr)
+@ stdcall KeSignalCallDpcSynchronize(ptr)
 @ stdcall KeStackAttachProcess(ptr ptr)
 @ stdcall KeSynchronizeExecution(ptr ptr ptr)
 @ stdcall KeTerminateThread(long)