diff --git a/reactos/include/ndk/kefuncs.h b/reactos/include/ndk/kefuncs.h index 4888006a86e..defe6ffbfe2 100644 --- a/reactos/include/ndk/kefuncs.h +++ b/reactos/include/ndk/kefuncs.h @@ -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 // diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 27e46ff4a92..2a3f062c18a 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -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; diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index 9895cae3f27..d507b726eb7 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -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 */ diff --git a/reactos/ntoskrnl/ntoskrnl.spec b/reactos/ntoskrnl/ntoskrnl.spec index 759d11716dc..a746452f2dd 100644 --- a/reactos/ntoskrnl/ntoskrnl.spec +++ b/reactos/ntoskrnl/ntoskrnl.spec @@ -583,7 +583,7 @@ @ stdcall KeFindConfigurationNextEntry(ptr long long ptr ptr) @ stdcall KeFlushEntireTb(long long) @ stdcall KeFlushQueuedDpcs() -;KeGenericCallDpc +@ stdcall KeGenericCallDpc(ptr ptr) @ stdcall KeGetCurrentThread() @ stdcall KeGetPreviousMode() @ stdcall KeGetRecommendedSharedDataAlignment() @@ -696,8 +696,8 @@ @ 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)