[NTOSKRNL:CC] Add CcQueueLazyWriteScanThread

Implemented CcQueueLazyWriteScanThread
This commit is contained in:
Dibyamartanda Samanta 2024-08-17 08:47:34 +02:00 committed by CodingWorkshop Signing Team
parent 1dec536c4d
commit 104a0212e0
Signed by: CodingWorkshop Signing Team
GPG Key ID: 6DC88369C82795D2

View File

@ -13,9 +13,142 @@
extern "C"
/*Internal Function*/
BOOLEAN
FASTCALL
CcIsLazyWriteScanQueued(
_In_ ULONG ReasonForFlush
)
{
switch (ReasonForFlush)
{
case 0:
return false;
/* Directives for Extra Write Behind Threads here */
case 1:
case 2:
case 16:
if (LazyWriter.PendingLowMemoryScan ||
LazyWriter.PendingPowerScan ||
LazyWriter.PendingCoalescingFlushScan)
{
return true;
}
return false;
case 4:
if (LazyWriter.PendingPeriodicScan ||
LazyWriter.PendingTeardownScan)
{
return true;
}
return false;
case 8:
return (BOOLEAN)LazyWriter.PendingTeardownScan;
default:
return false;
}
}
VOID
NTAPI
CcQueueLazyWriteScanThread(
_In_ PVOID NULL_PARAM
)
{
UNREFERENCED_PARAMETER(NULL_PARAM);
ULONG Reason = 0;
BOOLEAN NeedAdjustment;
NTSTATUS Status;
KIRQL OldIrql;
PWORK_QUEUE_ENTRY WorkQueueEntry;
PVOID WaitObjects[5];
WaitObjects[0] = &CcLowMemoryEvent;
WaitObjects[1] = &CcPowerEvent;
WaitObjects[2] = &CcPeriodicEvent;
WaitObjects[3] = &CcWaitingForTeardownEvent;
WaitObjects[4] = &CcCoalescingFlushEvent;
for (;;)
{
NeedAdjustment = false;
Status = KeWaitForMultipleObjects(
5,
WaitObjects,
WaitAny,
WrFreePage,
KernelMode,
false,
NULL,
WaitBlockArray);
switch (Status)
{
case STATUS_WAIT_0:
Reason = 1;
NeedAdjustment = true;
break;
case STATUS_WAIT_1:
Reason = 2;
break;
case STATUS_WAIT_2:
Reason = 4;
break;
case STATUS_WAIT_3:
Reason = 8;
break;
case STATUS_WAIT_4:
Reason = 16;
break;
default:
continue;
}
if (CcNumberOfExternalCaches && !IsListEmpty(&CcExternalCacheList))
{
CcNotifyExternalCaches(Reason);
}
CcAdjustWriteBehindThreadPoolIfNeeded(NeedAdjustment);
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
if (CcIsLazyWriteScanQueued(Reason))
{
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
continue;
}
CcSetLazyWriteScanQueued(Reason, true);
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
if (!NT_SUCCESS(CcAllocateWorkQueueEntry(&WorkQueueEntry)))
{
KSPIN_LOCK_QUEUE_NUMBER queueNumber = LockQueueMasterLock;
SpinLockGuard guard(queueNumber);
LazyWriter.ScanActive = false;
CcSetLazyWriteScanQueued(Reason, false);
}
else
{
WorkQueueEntry->Function = 3;
WorkQueueEntry->Parameters.Notification.Reason = Reason;
CcPostWorkQueue(
WorkQueueEntry,
(Reason != 8) ? &CcRegularWorkQueue : &CcFastTeardownWorkQueue);
}
}
}
VOID
NTAPI