Update NTOSKRNL/CC/cclazywriter.cpp
This commit is contained in:
parent
785ff4b644
commit
1f041b4444
@ -1019,7 +1019,74 @@ NTSTATUS CcWaitForCurrentLazyWriterActivity()
|
||||
|
||||
return result;
|
||||
}
|
||||
VOID VECTORCALL CcReEngageWorkerThreads(
|
||||
ULONG NormalThreadsToActivate,
|
||||
ULONG ExtraWriteBehindThreadsToActivate
|
||||
)
|
||||
{
|
||||
ULONG i;
|
||||
PLIST_ENTRY currentThreadEntry;
|
||||
PLIST_ENTRY nextThreadEntry;
|
||||
ULONG j;
|
||||
PLIST_ENTRY currentExtraThreadEntry;
|
||||
PLIST_ENTRY nextExtraThreadEntry;
|
||||
|
||||
/*Activate the required number of normal worker threads*/
|
||||
for (i = 0; i < NormalThreadsToActivate; ++i)
|
||||
{
|
||||
|
||||
currentThreadEntry = CcIdleWorkerThreadList.Flink;
|
||||
|
||||
if (IsListEmpty(&CcIdleWorkerThreadList))
|
||||
break;
|
||||
nextThreadEntry = currentThreadEntry->Flink;
|
||||
|
||||
/*Check if List is corrupt*/
|
||||
if (currentThreadEntry->Blink != &CcIdleWorkerThreadList ||
|
||||
nextThreadEntry->Blink != currentThreadEntry)
|
||||
{
|
||||
__fastfail(3u);
|
||||
}
|
||||
|
||||
/* Move to the next thread in the idle list*/
|
||||
++CcNumberActiveWorkerThreads;
|
||||
CcIdleWorkerThreadList.Flink = nextThreadEntry;
|
||||
nextThreadEntry->Blink = &CcIdleWorkerThreadList;
|
||||
/* Detach the current = thread from the list and schedule it for work*/
|
||||
currentThreadEntry->Flink = NULL;
|
||||
ExQueueWorkItem(currentThreadEntry, CriticalWorkQueue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (j = 0; j < ExtraWriteBehindThreadsToActivate; ++j)
|
||||
{
|
||||
/*first thread in the idle extra write-behind list*/
|
||||
currentExtraThreadEntry = CcIdleExtraWriteBehindThreadList.Flink;
|
||||
|
||||
|
||||
if (IsListEmpty(&CcIdleExtraWriteBehindThreadList))
|
||||
break;
|
||||
|
||||
nextExtraThreadEntry = currentExtraThreadEntry->Flink;
|
||||
|
||||
/*Consistency check to prevent corrupt list operations*/
|
||||
if (currentExtraThreadEntry->Blink != &CcIdleExtraWriteBehindThreadList ||
|
||||
nextExtraThreadEntry->Blink != currentExtraThreadEntry)
|
||||
{
|
||||
__fastfail(3u);
|
||||
}
|
||||
|
||||
/* Move to the next thread in the idle extra list*/
|
||||
++CcActiveExtraWriteBehindThreads;
|
||||
CcIdleExtraWriteBehindThreadList.Flink = nextExtraThreadEntry;
|
||||
nextExtraThreadEntry->Blink = &CcIdleExtraWriteBehindThreadList;
|
||||
|
||||
/* Detach the current extra thread from the list and schedule it for work*/
|
||||
currentExtraThreadEntry->Flink = NULL;
|
||||
ExQueueWorkItem(currentExtraThreadEntry, CriticalWorkQueue);
|
||||
}
|
||||
}
|
||||
VOID
|
||||
NTAPI
|
||||
CcWorkerThread(PVOID Parameter)
|
||||
@ -1037,8 +1104,7 @@ CcWorkerThread(PVOID Parameter)
|
||||
|
||||
DPRINT("CcWorkerThread: WorkItem");
|
||||
|
||||
IoStatus.Status = STATUS_SUCCESS;
|
||||
IoStatus.Information = 0;
|
||||
|
||||
|
||||
/* Loop till we have jobs */
|
||||
while (TRUE)
|
||||
@ -1051,6 +1117,7 @@ CcWorkerThread(PVOID Parameter)
|
||||
{
|
||||
CcQueueThrottle = FALSE;
|
||||
DropThrottle = FALSE;
|
||||
CcReEngageWorkerThreads(CcThreadsActiveBeforeThrottle, CcExtraThreadsActiveBeforeThrottle);
|
||||
}
|
||||
|
||||
if (IoStatus.Information == 0x8A5E)
|
||||
@ -1090,10 +1157,7 @@ CcWorkerThread(PVOID Parameter)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get our work item, if someone is waiting for us to finish
|
||||
and we're not the only thread in queue then, quit running to let the others do
|
||||
and throttle so that noone starts till current activity is over
|
||||
*/
|
||||
|
||||
WorkEntry = CONTAINING_RECORD(Entry->Flink, WORK_QUEUE_ENTRY, WorkQueueLinks);
|
||||
|
||||
if (WorkEntry->Function == SetDone && CcNumberActiveWorkerThreads > 1)
|
||||
@ -1108,10 +1172,8 @@ CcWorkerThread(PVOID Parameter)
|
||||
/* Remove current entry */
|
||||
RemoveHeadList(Entry);
|
||||
|
||||
/* Unlock queues */
|
||||
KeReleaseQueuedSpinLock(LockQueueWorkQueueLock, OldIrql);
|
||||
|
||||
/* And handle it */
|
||||
__try
|
||||
{
|
||||
switch (WorkEntry->Function)
|
||||
@ -1149,11 +1211,9 @@ CcWorkerThread(PVOID Parameter)
|
||||
PsGetCurrentThread()->MemoryMaker = 0;
|
||||
}
|
||||
|
||||
/* Handle for WriteBehind */
|
||||
if (IoStatus.Information == 0x8A5E)
|
||||
continue;
|
||||
|
||||
/* Release the current element and continue */
|
||||
|
||||
LookasideList = Prcb->PPLookasideList[5].P;
|
||||
InterlockedIncrement(&LookasideList->TotalFrees); // Use interlocked increment
|
||||
@ -1183,21 +1243,18 @@ CcWorkerThread(PVOID Parameter)
|
||||
InterlockedIncrement(&LookasideList->FreeMisses);
|
||||
LookasideList->Free(WorkEntry);
|
||||
}
|
||||
/* Our thread is available again */
|
||||
/* UNlock QUes*/
|
||||
InsertTailList(&CcIdleWorkerThreadList, &WorkItem->List);
|
||||
|
||||
/* One less worker */
|
||||
CcNumberActiveWorkerThreads--;
|
||||
|
||||
/* Unlock queues */
|
||||
KeReleaseQueuedSpinLock(LockQueueWorkQueueLock, OldIrql);
|
||||
|
||||
/* If there are pending write openations and we have at least 20 dirty pages */
|
||||
|
||||
if (!IsListEmpty(&CcDeferredWrites) && CcTotalDirtyPages >= 20)
|
||||
{
|
||||
/* And if we performed a write operation previously,
|
||||
then stress the system a bit and reschedule a scan to find stuff to write
|
||||
*/
|
||||
|
||||
if (WritePerformed)
|
||||
CcLazyWriteScan();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user