https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7fd2751c873a59f449b7f3...
commit 7fd2751c873a59f449b7f3421bdb17488f53253e Author: Pierre Schweitzer pierre@reactos.org AuthorDate: Fri Oct 5 21:14:13 2018 +0200 Commit: Pierre Schweitzer pierre@reactos.org 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;