[NTOSKRNL] Hello CcIdleDelay :-)
[reactos.git] / ntoskrnl / cc / view.c
index f58fa5d..7112e02 100644 (file)
@@ -64,12 +64,14 @@ ULONG CcLazyWriteIos = 0;
  * - List for deferred writes
  * - Spinlock when dealing with the deferred list
  * - List for "clean" shared cache maps
+ * - One second delay for lazy writer
  */
 ULONG CcDirtyPageThreshold = 0;
 ULONG CcTotalDirtyPages = 0;
 LIST_ENTRY CcDeferredWrites;
 KSPIN_LOCK CcDeferredWriteSpinLock;
 LIST_ENTRY CcCleanSharedCacheMapList;
+LARGE_INTEGER CcIdleDelay = {.QuadPart = (LONGLONG)-1*1000*1000*10};
 
 /* Internal vars (ROS):
  * - Event to notify lazy writer to shutdown
@@ -175,6 +177,7 @@ CcRosFlushVacb (
         Vacb->Dirty = FALSE;
         RemoveEntryList(&Vacb->DirtyVacbListEntry);
         CcTotalDirtyPages -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
+        Vacb->SharedCacheMap->DirtyPages -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
         CcRosVacbDecRefCount(Vacb);
 
         KeReleaseSpinLock(&Vacb->SharedCacheMap->CacheMapLock, oldIrql);
@@ -250,7 +253,8 @@ CcRosFlushDirtyPages (
         ASSERT(current->Dirty);
 
         /* One reference is added above */
-        if (current->ReferenceCount > 2)
+        if ((current->ReferenceCount > 2 && current->PinCount == 0) ||
+            (current->ReferenceCount > 3 && current->PinCount > 1))
         {
             CcRosReleaseVacbLock(current);
             current->SharedCacheMap->Callbacks->ReleaseFromLazyWrite(
@@ -310,10 +314,6 @@ VOID
 NTAPI
 CciLazyWriter(PVOID Unused)
 {
-    LARGE_INTEGER OneSecond;
-
-    OneSecond.QuadPart = (LONGLONG)-1*1000*1000*10;
-
     while (TRUE)
     {
         NTSTATUS Status;
@@ -325,7 +325,7 @@ CciLazyWriter(PVOID Unused)
                                        Executive,
                                        KernelMode,
                                        FALSE,
-                                       &OneSecond);
+                                       &CcIdleDelay);
 
         /* If we succeeed, we've to stop running! */
         if (Status == STATUS_SUCCESS)
@@ -515,25 +515,25 @@ CcRosReleaseVacb (
     BOOLEAN Mapped)
 {
     BOOLEAN WasDirty;
-    KIRQL oldIrql;
 
     ASSERT(SharedCacheMap);
 
     DPRINT("CcRosReleaseVacb(SharedCacheMap 0x%p, Vacb 0x%p, Valid %u)\n",
            SharedCacheMap, Vacb, Valid);
 
-    KeAcquireGuardedMutex(&ViewLock);
-    KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
-
     Vacb->Valid = Valid;
 
-    WasDirty = Vacb->Dirty;
-    Vacb->Dirty = Vacb->Dirty || Dirty;
-
-    if (!WasDirty && Vacb->Dirty)
+    WasDirty = FALSE;
+    if (Dirty)
     {
-        InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
-        CcTotalDirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
+        if (!Vacb->Dirty)
+        {
+            CcRosMarkDirtyVacb(Vacb);
+        }
+        else
+        {
+            WasDirty = TRUE;
+        }
     }
 
     if (Mapped)
@@ -550,8 +550,6 @@ CcRosReleaseVacb (
         CcRosVacbIncRefCount(Vacb);
     }
 
-    KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
-    KeReleaseGuardedMutex(&ViewLock);
     CcRosReleaseVacbLock(Vacb);
 
     return STATUS_SUCCESS;
@@ -620,6 +618,7 @@ CcRosMarkDirtyVacb (
     {
         InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
         CcTotalDirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
+        Vacb->SharedCacheMap->DirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
     }
     else
     {
@@ -657,7 +656,6 @@ CcRosMarkDirtyFile (
 
     CcRosMarkDirtyVacb(Vacb);
 
-
     CcRosReleaseVacbLock(Vacb);
 
     return STATUS_SUCCESS;
@@ -672,7 +670,6 @@ CcRosUnmapVacb (
 {
     PROS_VACB Vacb;
     BOOLEAN WasDirty;
-    KIRQL oldIrql;
 
     ASSERT(SharedCacheMap);
 
@@ -685,20 +682,21 @@ CcRosUnmapVacb (
         return STATUS_UNSUCCESSFUL;
     }
 
-    KeAcquireGuardedMutex(&ViewLock);
-    KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
-
-    WasDirty = Vacb->Dirty;
-    Vacb->Dirty = Vacb->Dirty || NowDirty;
-
-    Vacb->MappedCount--;
-
-    if (!WasDirty && NowDirty)
+    WasDirty = FALSE;
+    if (NowDirty)
     {
-        InsertTailList(&DirtyVacbListHead, &Vacb->DirtyVacbListEntry);
-        CcTotalDirtyPages += VACB_MAPPING_GRANULARITY / PAGE_SIZE;
+        if (!Vacb->Dirty)
+        {
+            CcRosMarkDirtyVacb(Vacb);
+        }
+        else
+        {
+            WasDirty = TRUE;
+        }
     }
 
+    Vacb->MappedCount--;
+
     CcRosVacbDecRefCount(Vacb);
     if (!WasDirty && NowDirty)
     {
@@ -709,8 +707,6 @@ CcRosUnmapVacb (
         CcRosVacbDecRefCount(Vacb);
     }
 
-    KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
-    KeReleaseGuardedMutex(&ViewLock);
     CcRosReleaseVacbLock(Vacb);
 
     return STATUS_SUCCESS;
@@ -883,7 +879,7 @@ CcRosCreateVacb (
 #if MI_TRACE_PFNS
     if ((SharedCacheMap->FileObject) && (SharedCacheMap->FileObject->FileName.Buffer))
     {
-        PWCHAR pos = NULL;
+        PWCHAR pos;
         ULONG len = 0;
         pos = wcsrchr(SharedCacheMap->FileObject->FileName.Buffer, '\\');
         if (pos)
@@ -1155,15 +1151,22 @@ CcRosDeleteFileCache (
         while (!IsListEmpty(&SharedCacheMap->CacheMapVacbListHead))
         {
             current_entry = RemoveTailList(&SharedCacheMap->CacheMapVacbListHead);
+            KeReleaseSpinLock(&SharedCacheMap->CacheMapLock, oldIrql);
+
             current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
+            CcRosAcquireVacbLock(current, NULL);
             RemoveEntryList(&current->VacbLruListEntry);
             if (current->Dirty)
             {
                 RemoveEntryList(&current->DirtyVacbListEntry);
                 CcTotalDirtyPages -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
+                current->SharedCacheMap->DirtyPages -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
                 DPRINT1("Freeing dirty VACB\n");
             }
             InsertHeadList(&FreeList, &current->CacheMapVacbListEntry);
+            CcRosReleaseVacbLock(current);
+
+            KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
         }
 #if DBG
         SharedCacheMap->Trace = FALSE;
@@ -1348,6 +1351,7 @@ CcRosInitializeFileCache (
         SharedCacheMap->FileSize = FileSizes->FileSize;
         SharedCacheMap->PinAccess = PinAccess;
         SharedCacheMap->DirtyPageThreshold = 0;
+        SharedCacheMap->DirtyPages = 0;
         KeInitializeSpinLock(&SharedCacheMap->CacheMapLock);
         InitializeListHead(&SharedCacheMap->CacheMapVacbListHead);
         FileObject->SectionObjectPointer->SharedCacheMap = SharedCacheMap;
@@ -1500,7 +1504,8 @@ ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[])
     PLIST_ENTRY ListEntry;
     UNICODE_STRING NoName = RTL_CONSTANT_STRING(L"No name for File");
 
-    KdbpPrint("Control\t\tValid\tDirty\tName\n");
+    KdbpPrint("  Usage Summary (in kb)\n");
+    KdbpPrint("Shared\t\tValid\tDirty\tName\n");
     /* No need to lock the spin lock here, we're in DBG */
     for (ListEntry = CcCleanSharedCacheMapList.Flink;
          ListEntry != &CcCleanSharedCacheMapList;
@@ -1513,6 +1518,9 @@ ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[])
 
         SharedCacheMap = CONTAINING_RECORD(ListEntry, ROS_SHARED_CACHE_MAP, SharedCacheMapLinks);
 
+        /* Dirty size */
+        Dirty = (SharedCacheMap->DirtyPages * PAGE_SIZE) / 1024;
+
         /* First, count for all the associated VACB */
         for (Vacbs = SharedCacheMap->CacheMapVacbListHead.Flink;
              Vacbs != &SharedCacheMap->CacheMapVacbListHead;
@@ -1521,10 +1529,6 @@ ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[])
             PROS_VACB Vacb;
 
             Vacb = CONTAINING_RECORD(Vacbs, ROS_VACB, CacheMapVacbListEntry);
-            if (Vacb->Dirty)
-            {
-                Dirty += VACB_MAPPING_GRANULARITY / 1024;
-            }
             if (Vacb->Valid)
             {
                 Valid += VACB_MAPPING_GRANULARITY / 1024;