ASSERT3U(Old, ==, Index);
}
-
KDEFERRED_ROUTINE SyncWorker;
#pragma intrinsic(_enable)
#pragma intrinsic(_disable)
+#pragma warning(push)
+#pragma warning(disable:28167) // Function changes IRQL and does not restore it before exit
+#pragma warning(disable:28156) // Actual IRQL is inconsistent with required IRQL
+
+static FORCEINLINE NTSTATUS
+__SyncProcessorDisableInterrupts(
+ VOID
+ )
+{
+ PSYNC_CONTEXT Context = SyncContext;
+ ULONG Attempts;
+ LONG Old;
+ LONG New;
+ NTSTATUS status;
+
+ (VOID) KfRaiseIrql(HIGH_LEVEL);
+ status = STATUS_SUCCESS;
+
+ InterlockedIncrement(&Context->CompletionCount);
+
+ Attempts = 0;
+ while (++Attempts <= 1000) {
+ KeMemoryBarrier();
+
+ if (Context->CompletionCount == Context->ProcessorCount)
+ break;
+
+ _mm_pause();
+ }
+
+ do {
+ Old = Context->CompletionCount;
+ New = Old - 1;
+
+ if (Old == Context->ProcessorCount)
+ break;
+ } while (InterlockedCompareExchange(&Context->CompletionCount, New, Old) != Old);
+
+ if (Old < Context->ProcessorCount) {
+#pragma prefast(suppress:28138) // Use constant rather than variable
+ KeLowerIrql(DISPATCH_LEVEL);
+ status = STATUS_UNSUCCESSFUL;
+ }
+
+ if (NT_SUCCESS(status))
+ _disable();
+
+ return status;
+}
+
+static FORCEINLINE VOID
+__SyncProcessorEnableInterrupts(
+ VOID
+ )
+{
+ PSYNC_CONTEXT Context = SyncContext;
+
+ _enable();
+
+#pragma prefast(suppress:28138) // Use constant rather than variable
+ KeLowerIrql(DISPATCH_LEVEL);
+
+ InterlockedIncrement(&Context->CompletionCount);
+}
+
+static FORCEINLINE VOID
+__SyncWait(
+ VOID
+ )
+{
+ PSYNC_CONTEXT Context = SyncContext;
+
+ for (;;) {
+ KeMemoryBarrier();
+
+ if (Context->CompletionCount == Context->ProcessorCount)
+ break;
+
+ _mm_pause();
+ }
+}
+
VOID
#pragma prefast(suppress:28166) // Function does not restore IRQL
SyncWorker(
}
if (Processor->DisableInterrupts) {
- ULONG Attempts;
- NTSTATUS status;
-
- (VOID) KfRaiseIrql(HIGH_LEVEL);
- status = STATUS_SUCCESS;
-
- InterlockedIncrement(&Context->CompletionCount);
-
- Attempts = 0;
- while (Context->CompletionCount < Context->ProcessorCount) {
- _mm_pause();
- KeMemoryBarrier();
-
- if (++Attempts > 1000) {
- LONG Old;
- LONG New;
-
- do {
- Old = Context->CompletionCount;
- New = Old - 1;
-
- if (Old == Context->ProcessorCount)
- break;
- } while (InterlockedCompareExchange(&Context->CompletionCount, New, Old) != Old);
-
- if (Old < Context->ProcessorCount) {
-#pragma prefast(suppress:28138) // Use constant rather than variable
- KeLowerIrql(DISPATCH_LEVEL);
- status = STATUS_UNSUCCESSFUL;
- break;
- }
- }
- }
+ NTSTATUS status = __SyncProcessorDisableInterrupts();
if (!NT_SUCCESS(status))
continue;
- _disable();
-
InterruptsDisabled = TRUE;
} else {
InterruptsDisabled = FALSE;
if (Context->Early != NULL)
Context->Early(Context->Argument, Index);
- _enable();
-
-#pragma prefast(suppress:28138) // Use constant rather than variable
- KeLowerIrql(DISPATCH_LEVEL);
-
- InterlockedIncrement(&Context->CompletionCount);
+ __SyncProcessorEnableInterrupts();
}
}
KeInsertQueueDpc(&Processor->Dpc, NULL, NULL);
}
- InterlockedIncrement(&Context->CompletionCount);
+ KeMemoryBarrier();
- while (Context->CompletionCount < Context->ProcessorCount) {
- _mm_pause();
- KeMemoryBarrier();
- }
+ InterlockedIncrement(&Context->CompletionCount);
+ __SyncWait();
Trace("<==== (%u:%u)\n", Group, Number);
}
{
PSYNC_CONTEXT Context = SyncContext;
LONG Index;
- ULONG Attempts;
NTSTATUS status;
Trace("====>\n");
KeMemoryBarrier();
-again:
- (VOID) KfRaiseIrql(HIGH_LEVEL);
- status = STATUS_SUCCESS;
-
- InterlockedIncrement(&Context->CompletionCount);
-
- Attempts = 0;
- while (Context->CompletionCount < Context->ProcessorCount) {
- _mm_pause();
- KeMemoryBarrier();
-
- if (++Attempts > 1000) {
- LONG Old;
- LONG New;
-
- do {
- Old = Context->CompletionCount;
- New = Old - 1;
-
- if (Old == Context->ProcessorCount)
- break;
- } while (InterlockedCompareExchange(&Context->CompletionCount, New, Old) != Old);
-
- if (Old < Context->ProcessorCount) {
- LogPrintf(LOG_LEVEL_WARNING,
- "SYNC: %d < %d\n",
- Old,
- Context->ProcessorCount);
+ for (;;) {
+ status = __SyncProcessorDisableInterrupts();
+ if (NT_SUCCESS(status))
+ break;
-#pragma prefast(suppress:28138) // Use constant rather than variable
- KeLowerIrql(DISPATCH_LEVEL);
- status = STATUS_UNSUCCESSFUL;
- break;
- }
- }
+ LogPrintf(LOG_LEVEL_WARNING, "SYNC: RE-TRY\n");
}
-
- if (!NT_SUCCESS(status))
- goto again;
-
- _disable();
}
__drv_requiresIRQL(HIGH_LEVEL)
)
{
PSYNC_CONTEXT Context = SyncContext;
- KIRQL Irql;
LONG Index;
ASSERT(SyncOwner >= 0);
if (Context->Early != NULL)
Context->Early(Context->Argument, SyncOwner);
- _enable();
-
- Irql = KeGetCurrentIrql();
- ASSERT3U(Irql, ==, HIGH_LEVEL);
-
Context->CompletionCount = 0;
KeMemoryBarrier();
+ __SyncProcessorEnableInterrupts();
+
for (Index = 0; Index < Context->ProcessorCount; Index++) {
PSYNC_PROCESSOR Processor = &Context->Processor[Index];
KeMemoryBarrier();
- InterlockedIncrement(&Context->CompletionCount);
-
- while (Context->CompletionCount < Context->ProcessorCount) {
- _mm_pause();
- KeMemoryBarrier();
- }
-
-#pragma prefast(suppress:28138) // Use constant rather than variable
- KeLowerIrql(DISPATCH_LEVEL);
+ __SyncWait();
Trace("<====\n");
}
Context->CompletionCount = 0;
KeMemoryBarrier();
+ InterlockedIncrement(&Context->CompletionCount);
+
for (Index = 0; Index < Context->ProcessorCount; Index++) {
PSYNC_PROCESSOR Processor = &Context->Processor[Index];
KeMemoryBarrier();
- InterlockedIncrement(&Context->CompletionCount);
-
- while (Context->CompletionCount < Context->ProcessorCount) {
- _mm_pause();
- KeMemoryBarrier();
- }
+ __SyncWait();
RtlZeroMemory(Context, PAGE_SIZE);
Trace("<====\n");
}
+
+#pragma warning(pop)