https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7fd2751c873a59f449b7f3421bdb17488f53253e

commit 7fd2751c873a59f449b7f3421bdb17488f53253e
Author:     Pierre Schweitzer <[email protected]>
AuthorDate: Fri Oct 5 21:14:13 2018 +0200
Commit:     Pierre Schweitzer <[email protected]>
CommitDate: Fri Oct 5 21:26:16 2018 +0200

    [NTOSKRNL] When pinning data, try to find an already pinned BCB
    
    If found, attempt to lock it and return it.
    
    This fixes a lot of CcPinRead tests (and seems to speed up a bit ReactOS)
---
 ntoskrnl/cc/pin.c | 49 +++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/ntoskrnl/cc/pin.c b/ntoskrnl/cc/pin.c
index 0d23211da9..f40405e6c5 100644
--- a/ntoskrnl/cc/pin.c
+++ b/ntoskrnl/cc/pin.c
@@ -299,6 +299,9 @@ CcPinRead (
     OUT        PVOID * Bcb,
     OUT        PVOID * Buffer)
 {
+    KIRQL OldIrql;
+    BOOLEAN Result;
+    PINTERNAL_BCB iBcb;
     PROS_SHARED_CACHE_MAP SharedCacheMap;
 
     CCTRACE(CC_API_DEBUG, "FileOffset=%p FileOffset=%p Length=%lu 
Flags=0x%lx\n",
@@ -320,17 +323,47 @@ CcPinRead (
         ++CcPinReadNoWait;
     }
 
-    /* Map first */
-    if (!CcpMapData(SharedCacheMap, FileOffset, Length, Flags, Bcb, Buffer))
+    KeAcquireSpinLock(&SharedCacheMap->BcbSpinLock, &OldIrql);
+    iBcb = CcpFindBcb(SharedCacheMap, FileOffset, Length, TRUE);
+    KeReleaseSpinLock(&SharedCacheMap->BcbSpinLock, OldIrql);
+
+    if (iBcb == NULL)
     {
-        return FALSE;
-    }
+        /* Map first */
+        if (!CcpMapData(SharedCacheMap, FileOffset, Length, Flags, Bcb, 
Buffer))
+        {
+            return FALSE;
+        }
 
-    /* Pin then */
-    if (!CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb))
+        /* Pin then */
+        if (!CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb))
+        {
+            CcUnpinData(*Bcb);
+            return FALSE;
+        }
+    }
+    /* We found a BCB, lock it and return it */
+    else
     {
-        CcUnpinData(*Bcb);
-        return FALSE;
+        if (BooleanFlagOn(Flags, PIN_EXCLUSIVE))
+        {
+            Result = ExAcquireResourceExclusiveLite(&iBcb->Lock, 
BooleanFlagOn(Flags, PIN_WAIT));
+        }
+        else
+        {
+            Result = ExAcquireSharedStarveExclusive(&iBcb->Lock, 
BooleanFlagOn(Flags, PIN_WAIT));
+        }
+
+        if (!Result)
+        {
+            return FALSE;
+        }
+
+        ++iBcb->PinCount;
+        ++iBcb->RefCount;
+
+        *Bcb = iBcb;
+        *Buffer = (PUCHAR)iBcb->Vacb->BaseAddress + FileOffset->QuadPart % 
VACB_MAPPING_GRANULARITY;
     }
 
     return TRUE;

Reply via email to