Update NTOSKRNL/CC/cclazywriter.cpp
This commit is contained in:
parent
785ff4b644
commit
1f041b4444
@ -1019,7 +1019,74 @@ NTSTATUS CcWaitForCurrentLazyWriterActivity()
|
|||||||
|
|
||||||
return result;
|
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
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CcWorkerThread(PVOID Parameter)
|
CcWorkerThread(PVOID Parameter)
|
||||||
@ -1037,8 +1104,7 @@ CcWorkerThread(PVOID Parameter)
|
|||||||
|
|
||||||
DPRINT("CcWorkerThread: WorkItem");
|
DPRINT("CcWorkerThread: WorkItem");
|
||||||
|
|
||||||
IoStatus.Status = STATUS_SUCCESS;
|
|
||||||
IoStatus.Information = 0;
|
|
||||||
|
|
||||||
/* Loop till we have jobs */
|
/* Loop till we have jobs */
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
@ -1051,6 +1117,7 @@ CcWorkerThread(PVOID Parameter)
|
|||||||
{
|
{
|
||||||
CcQueueThrottle = FALSE;
|
CcQueueThrottle = FALSE;
|
||||||
DropThrottle = FALSE;
|
DropThrottle = FALSE;
|
||||||
|
CcReEngageWorkerThreads(CcThreadsActiveBeforeThrottle, CcExtraThreadsActiveBeforeThrottle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IoStatus.Information == 0x8A5E)
|
if (IoStatus.Information == 0x8A5E)
|
||||||
@ -1090,10 +1157,7 @@ CcWorkerThread(PVOID Parameter)
|
|||||||
break;
|
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);
|
WorkEntry = CONTAINING_RECORD(Entry->Flink, WORK_QUEUE_ENTRY, WorkQueueLinks);
|
||||||
|
|
||||||
if (WorkEntry->Function == SetDone && CcNumberActiveWorkerThreads > 1)
|
if (WorkEntry->Function == SetDone && CcNumberActiveWorkerThreads > 1)
|
||||||
@ -1108,10 +1172,8 @@ CcWorkerThread(PVOID Parameter)
|
|||||||
/* Remove current entry */
|
/* Remove current entry */
|
||||||
RemoveHeadList(Entry);
|
RemoveHeadList(Entry);
|
||||||
|
|
||||||
/* Unlock queues */
|
|
||||||
KeReleaseQueuedSpinLock(LockQueueWorkQueueLock, OldIrql);
|
KeReleaseQueuedSpinLock(LockQueueWorkQueueLock, OldIrql);
|
||||||
|
|
||||||
/* And handle it */
|
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
switch (WorkEntry->Function)
|
switch (WorkEntry->Function)
|
||||||
@ -1149,11 +1211,9 @@ CcWorkerThread(PVOID Parameter)
|
|||||||
PsGetCurrentThread()->MemoryMaker = 0;
|
PsGetCurrentThread()->MemoryMaker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle for WriteBehind */
|
|
||||||
if (IoStatus.Information == 0x8A5E)
|
if (IoStatus.Information == 0x8A5E)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Release the current element and continue */
|
|
||||||
|
|
||||||
LookasideList = Prcb->PPLookasideList[5].P;
|
LookasideList = Prcb->PPLookasideList[5].P;
|
||||||
InterlockedIncrement(&LookasideList->TotalFrees); // Use interlocked increment
|
InterlockedIncrement(&LookasideList->TotalFrees); // Use interlocked increment
|
||||||
@ -1183,21 +1243,18 @@ CcWorkerThread(PVOID Parameter)
|
|||||||
InterlockedIncrement(&LookasideList->FreeMisses);
|
InterlockedIncrement(&LookasideList->FreeMisses);
|
||||||
LookasideList->Free(WorkEntry);
|
LookasideList->Free(WorkEntry);
|
||||||
}
|
}
|
||||||
/* Our thread is available again */
|
/* UNlock QUes*/
|
||||||
InsertTailList(&CcIdleWorkerThreadList, &WorkItem->List);
|
InsertTailList(&CcIdleWorkerThreadList, &WorkItem->List);
|
||||||
|
|
||||||
/* One less worker */
|
|
||||||
CcNumberActiveWorkerThreads--;
|
CcNumberActiveWorkerThreads--;
|
||||||
|
|
||||||
/* Unlock queues */
|
/* Unlock queues */
|
||||||
KeReleaseQueuedSpinLock(LockQueueWorkQueueLock, OldIrql);
|
KeReleaseQueuedSpinLock(LockQueueWorkQueueLock, OldIrql);
|
||||||
|
|
||||||
/* If there are pending write openations and we have at least 20 dirty pages */
|
|
||||||
if (!IsListEmpty(&CcDeferredWrites) && CcTotalDirtyPages >= 20)
|
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)
|
if (WritePerformed)
|
||||||
CcLazyWriteScan();
|
CcLazyWriteScan();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user